1 // Copyright (C) 2007-2021 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 <SUIT_ResourceMgr.h>
44 #include <SalomeApp_IntSpinBox.h>
45 #include <SalomeApp_Tools.h>
49 #include <BRepBndLib.hxx>
50 #include <Bnd_Box.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopoDS_Shape.hxx>
56 #include <QAbstractItemModel>
57 #include <QApplication>
58 #include <QButtonGroup>
60 #include <QFontMetrics>
61 #include <QGridLayout>
63 #include <QHBoxLayout>
66 #include <QListWidget>
67 #include <QModelIndex>
68 #include <QPushButton>
69 #include <QRadioButton>
71 #include <QStyleOptionViewItem>
73 #include <QTreeWidget>
74 #include <QTreeWidgetItem>
75 #include <QVBoxLayout>
80 namespace StdMeshersGUI
82 enum { COORD_BUT = 0, SPACING_BUT };
84 //================================================================================
86 * \brief get spacing definition from a tree item
88 //================================================================================
90 void getFromItem(QTreeWidgetItem * item, double& t0, double& t1, QString& fun )
94 t0 = item->text( 0 ).split(' ')[0].toDouble();
95 t1 = item->data( 0, Qt::UserRole ).toDouble();
96 fun = item->text( 1 );
100 //================================================================================
102 * \brief set spacing definition to a tree item
104 //================================================================================
106 QTreeWidgetItem* setToItem(double t0, double t1, const QString& fun, QTreeWidgetItem * item)
108 if ( !item ) item = new QTreeWidgetItem;
109 item->setText( 0, QString( "%1 - %2" ).arg( t0 ).arg( t1 ));
110 item->setData( 0, Qt::UserRole, t1 );
111 item->setText( 1, fun );
112 item->setFlags( item->flags() | Qt::ItemIsEditable );
116 //================================================================================
118 * \brief Retrieves coordinate value from a list item
120 //================================================================================
122 double coordFromItem( QListWidgetItem * item )
124 return item ? item->data( Qt::UserRole ).toDouble() : 0;
127 //================================================================================
129 * \brief Sets coordinate value to a list item
131 //================================================================================
133 QListWidgetItem* coordToItem( double coord, QListWidgetItem * item )
135 if ( !item ) item = new QListWidgetItem;
136 item->setText( QString::number( coord ));
137 item->setData( Qt::UserRole, coord );
138 item->setFlags( item->flags() | Qt::ItemIsEditable );
142 //================================================================================
145 * \param theParent - Parent widget for this tab
147 * Makes tab's look and feel
149 //================================================================================
151 GridAxisTab::GridAxisTab( QWidget* theParent,const int axisIndex ):
152 QFrame( theParent ), myAxisIndex( axisIndex )
154 // 1) Grid definition mode
155 myModeGroup = new QButtonGroup( this );
156 QGroupBox* modeBox = new QGroupBox( tr( "GRID_DEF_MODE" ), this );
157 QHBoxLayout* modeLay = new QHBoxLayout( modeBox );
158 modeLay->setMargin( MARGIN );
159 modeLay->setSpacing( SPACING );
161 QRadioButton* coordModeBtn = new QRadioButton( tr( "SMESH_COORDINATES" ), modeBox );
162 QRadioButton* spacModeBtn = new QRadioButton( tr( "SPACING" ), modeBox );
164 modeLay->addWidget( coordModeBtn );
165 modeLay->addWidget( spacModeBtn );
166 myModeGroup->addButton( coordModeBtn, COORD_BUT );
167 myModeGroup->addButton( spacModeBtn, SPACING_BUT );
170 myInsertBtn = new QPushButton( tr("INSERT"), this);
171 myDeleteBtn = new QPushButton( tr("SMESH_BUT_DELETE"), this);
173 myStepLabel = new QLabel( tr("COORD_STEP"));
174 myStepSpin = new SMESHGUI_SpinBox( this );
175 myStepSpin->setAcceptNames( false ); // No Notebook variables allowed
176 myStepSpin->RangeStepAndValidator();
177 myStepSpin->SetStep( 1. );
178 myStepSpin->SetValue( myStep = 1. );
180 // 3) Coordinates/Spacing group
181 QFrame* csFrame = new QFrame( this );
182 QVBoxLayout* scLay = new QVBoxLayout( csFrame );
183 scLay->setMargin( 0 );
184 scLay->setSpacing( SPACING );
187 mySpacingTreeWdg = new QTreeWidget( csFrame );
188 mySpacingTreeWdg->setColumnCount(2);
189 mySpacingTreeWdg->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << QString( "f(t)" ));
190 mySpacingTreeWdg->setColumnWidth( 1, 40 );
191 mySpacingTreeWdg->setColumnWidth( 2, 30 );
192 mySpacingTreeWdg->setItemDelegate( new LineDelegate( mySpacingTreeWdg ));
193 scLay->addWidget( mySpacingTreeWdg );
196 myCoordList = new QListWidget( csFrame );
197 myCoordList->setItemDelegate( new LineDelegate( myCoordList ));
198 scLay->addWidget( myCoordList );
202 QGridLayout* axisTabLayout = new QGridLayout( this );
203 axisTabLayout->setMargin( MARGIN );
204 axisTabLayout->setSpacing( SPACING );
206 axisTabLayout->addWidget( modeBox , 0, 0, 1, 3 );
207 axisTabLayout->addWidget( myInsertBtn, 1, 0, 1, 2 );
208 axisTabLayout->addWidget( myDeleteBtn, 2, 0, 1, 2 );
209 axisTabLayout->addWidget( myStepLabel, 3, 0 );
210 axisTabLayout->addWidget( myStepSpin , 3, 1 );
211 axisTabLayout->addWidget( csFrame , 1, 2, 4, 1 );
213 axisTabLayout->setRowStretch( 4, 1 );
216 connect( myInsertBtn, SIGNAL( clicked() ), SLOT( onInsert() ));
217 connect( myDeleteBtn, SIGNAL( clicked() ), SLOT( onDelete() ));
218 connect( myModeGroup, SIGNAL( buttonClicked ( int )), SLOT( onMode(int)));
219 connect( myModeGroup, SIGNAL( buttonClicked ( int )), SIGNAL( gridModeChanged(int)));
220 connect( mySpacingTreeWdg, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
221 connect( myCoordList, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
222 connect( myStepSpin, SIGNAL( valueChanged(double)), SLOT( onStepChange() ));
225 //================================================================================
227 * \brief SLOT onInsert
229 //================================================================================
231 void GridAxisTab::onInsert()
233 if ( isGridBySpacing() )
235 QTreeWidgetItem * item = mySpacingTreeWdg->currentItem();
236 if ( !item ) item = mySpacingTreeWdg->topLevelItem( 0 );
237 int i = mySpacingTreeWdg->indexOfTopLevelItem( item );
239 double t0, t1; QString fun;
240 getFromItem( item, t0, t1, fun );
241 double t = 0.5 * ( t0 + t1 );
242 setToItem( t0, t, fun, item );
244 item = setToItem( t, t1, fun );
245 if ( i == mySpacingTreeWdg->topLevelItemCount()-1 )
246 mySpacingTreeWdg->addTopLevelItem( item );
248 mySpacingTreeWdg->insertTopLevelItem( i+1, item );
249 mySpacingTreeWdg->setCurrentItem( item );
253 if ( myCoordList->count() == 0 )
255 myCoordList->addItem( coordToItem( 0 ));
259 double coord = coordFromItem( myCoordList->currentItem() ) + myStep;
260 int i = myCoordList->currentRow();
261 while ( i > 0 && coordFromItem( myCoordList->item( i-1 )) > coord )
263 while ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) < coord )
265 const double tol = 1e-6;
267 ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) - coord < tol ) ||
268 ( i > 0 && coord - coordFromItem( myCoordList->item( i-1 )) < tol );
270 myCoordList->insertItem( i, coordToItem( coord ));
271 else if ( myStep < 0 )
273 myCoordList->setCurrentRow( i );
279 //================================================================================
281 * \brief SLOT onDelete
283 //================================================================================
285 void GridAxisTab::onDelete()
287 if ( isGridBySpacing() )
289 QList<QTreeWidgetItem *> selItems = mySpacingTreeWdg->selectedItems();
290 QTreeWidgetItem * item;
291 foreach ( item, selItems )
293 int i = mySpacingTreeWdg->indexOfTopLevelItem( item );
294 if ( i == 0 ) continue;
295 QTreeWidgetItem* prevItem = mySpacingTreeWdg->topLevelItem( i-1 );
297 double t0, t1, t2; QString fun;
298 getFromItem( item, t1, t2, fun );
299 getFromItem( prevItem, t0, t1, fun );
302 setToItem( t0, t2, fun, prevItem );
307 if ( myCoordList->count() > 2 )
308 if ( QListWidgetItem * item = myCoordList->currentItem() )
314 //================================================================================
318 //================================================================================
320 void GridAxisTab::onMode(int isSpacing)
322 mySpacingTreeWdg->setVisible( isSpacing );
323 myCoordList->setVisible( !isSpacing );
324 myStepSpin->setVisible( !isSpacing );
325 myStepLabel->setVisible( !isSpacing );
328 if ( mySpacingTreeWdg->topLevelItemCount() == 0 )
330 QString spacing( "1" );
331 if ( myCoordList->count() > 1 )
333 double c1 = coordFromItem( myCoordList->item( 1 ));
334 double c0 = coordFromItem( myCoordList->item( 0 ));
335 spacing = QString::number( c1 - c0 );
337 mySpacingTreeWdg->addTopLevelItem( setToItem( 0., 1., spacing ) );
339 //myCoordList->clear();
343 //mySpacingTreeWdg->clear();
344 if ( myCoordList->count() == 0 )
345 myCoordList->addItem( coordToItem( 0 ));
350 //================================================================================
352 * \brief SLOT onStepChange
354 //================================================================================
356 void GridAxisTab::onStepChange()
358 if ( fabs( myStepSpin->GetValue() ) < 1e-100 )
360 double delta = myStepSpin->singleStep() * ( myStep > myStepSpin->GetValue() ? -1 : +1 );
361 myStepSpin->SetValue( myStepSpin->GetValue() + delta );
363 myStep = myStepSpin->GetValue();
366 //================================================================================
368 * \brief Enables/disables buttons
370 //================================================================================
372 void GridAxisTab::updateButtons()
374 bool insertEnable = false, deleteEnable = false;
375 if ( isGridBySpacing() )
378 const int nbSelected = mySpacingTreeWdg->selectedItems().count();
379 if ( nbSelected > 0 )
381 // we delete a current range by uniting it with the previous
382 int i = mySpacingTreeWdg->indexOfTopLevelItem( mySpacingTreeWdg->currentItem() );
383 deleteEnable = ( i > 0 );
388 const int nbSelected = myCoordList->selectedItems().count();
389 insertEnable = ( nbSelected || myCoordList->count() < 2 );
390 deleteEnable = ( nbSelected && myCoordList->count() > 2 );
392 myInsertBtn->setEnabled( insertEnable );
393 myDeleteBtn->setEnabled( deleteEnable );
396 //================================================================================
398 * \brief Inserts coordinates into myCoordList
400 //================================================================================
402 void GridAxisTab::setCoordinates( SMESH::double_array_var coords )
404 myCoordList->clear();
405 for ( size_t i = 0; i < coords->length(); ++i )
406 myCoordList->addItem( coordToItem( coords[i] ));
408 myModeGroup->button( COORD_BUT )->setChecked( true );
412 //================================================================================
414 * \brief Sets spacing got from hypothesis
416 //================================================================================
418 void GridAxisTab::setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points )
420 mySpacingTreeWdg->clear();
421 if ( funs->length() == points->length() - 1 )
423 for ( size_t i = 1; i < points->length(); ++i )
424 mySpacingTreeWdg->addTopLevelItem
425 ( setToItem( points[i-1], points[i], (const char*) funs[i-1] ));
427 myModeGroup->button( SPACING_BUT )->setChecked( true );
428 onMode( SPACING_BUT );
431 //================================================================================
433 * \brief Checks grid definition mode
435 //================================================================================
437 bool GridAxisTab::isGridBySpacing() const
439 return ( myModeGroup->checkedId() == SPACING_BUT );
442 //================================================================================
444 * \brief Returns coordinates to set to a hypothesis
446 //================================================================================
448 SMESH::double_array* GridAxisTab::getCoordinates()
450 SMESH::double_array_var coords = new SMESH::double_array;
451 coords->length( myCoordList->count() );
452 for ( size_t i = 0; i < coords->length(); ++i )
453 coords[i] = coordFromItem( myCoordList->item( i ) );
455 return coords._retn();
458 //================================================================================
460 * \brief Returns spacing to set to a hypothesis
462 //================================================================================
464 void GridAxisTab::getSpacing(SMESH::string_array_out funs,
465 SMESH::double_array_out points) const
467 funs = new SMESH::string_array();
468 points = new SMESH::double_array();
469 funs->length( mySpacingTreeWdg->topLevelItemCount() );
470 points->length( mySpacingTreeWdg->topLevelItemCount() + 1 );
471 double t0, t1; QString fun;
472 for ( size_t i = 0; i < funs->length(); ++i )
474 QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( i );
475 getFromItem( item, t0, t1, fun );
477 funs[i] = fun.toLatin1().constData();
479 points[ points->length()-1 ] = 1.0;
483 //================================================================================
485 * \brief Verifies parameters
487 //================================================================================
489 bool GridAxisTab::checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const
491 if ( isGridBySpacing() )
493 if ( mySpacingTreeWdg->topLevelItemCount() == 0 )
494 return false; // how could it be?
495 StdMeshers::StdMeshers_CartesianParameters3D_var h =
496 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hyp );
497 SMESH::string_array_var funs;
498 SMESH::double_array_var points;
499 getSpacing( funs.out(), points.out() );
501 const char* axisName[3] = { "X", "Y", "Z" };
502 SMESH::double_array_var coords =
503 h->ComputeCoordinates(0.,1., funs, points, axisName[ myAxisIndex ]);
505 catch ( const SALOME::SALOME_Exception& ex ) {
506 msg = (const char*) ex.details.text;
512 return myCoordList->count() > 1;
517 //================================================================================
519 * \brief LineDelegate constructor
521 //================================================================================
523 LineDelegate::LineDelegate( QWidget* parent ):
524 QItemDelegate( parent ),
525 mySpacingTreeWdg( qobject_cast<QTreeWidget*>( parent )),
526 myCoordList( qobject_cast<QListWidget*>( parent ))
530 //================================================================================
532 * \brief Creates an editor depending on a current item
534 //================================================================================
536 QWidget* LineDelegate::createEditor( QWidget* parent,
537 const QStyleOptionViewItem& /*opt*/,
538 const QModelIndex& index) const
541 if ( mySpacingTreeWdg )
543 if ( index.column() == 0 &&
544 index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
546 SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
547 sb->setAcceptNames( false ); // No Notebook variables allowed
548 sb->setFrame( false );
551 if ( index.column() == 1 ) {
552 w = new QLineEdit( parent );
557 SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
558 sb->setAcceptNames( false ); // No Notebook variables allowed
559 sb->setFrame( false );
560 const double tol = 1e-5;
561 double from = index.row() ? coordFromItem( myCoordList->item( index.row()-1 ))+tol : -1e+6;
562 double to = index.row() == myCoordList->count()-1 ? 1e+6 : coordFromItem( myCoordList->item( index.row()+1 ))-tol;
563 sb->RangeStepAndValidator( from, to, 0.01 );
569 //================================================================================
571 * \brief Limit value range in the spin of a neighbor range
573 //================================================================================
575 void LineDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const
577 if ( mySpacingTreeWdg && index.column() == 0 )
579 double t0, t1, t2=1.0; QString fun;
580 QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() );
581 getFromItem( item, t0, t1, fun );
582 if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
584 item = mySpacingTreeWdg->topLevelItem( index.row()+1 );
585 getFromItem( item, t1, t2, fun );
587 const double tol = 1e-3;
588 SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
589 sb->RangeStepAndValidator( t0 + tol, t2 - tol, 0.01 );
594 QItemDelegate::setEditorData( editor, index );
598 //================================================================================
602 //================================================================================
604 void LineDelegate::setModelData( QWidget* editor,
605 QAbstractItemModel* model,
606 const QModelIndex& index ) const
608 if ( mySpacingTreeWdg )
610 if ( index.column() == 0 )
612 if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
614 SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
615 double t0, t1, t = sb->GetValue(); QString fun;
617 QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() );
618 getFromItem( item, t0, t1, fun );
619 setToItem( t0, t, fun, item );
621 item = mySpacingTreeWdg->topLevelItem( index.row() + 1 );
622 getFromItem( item, t0, t1, fun );
623 setToItem( t, t1, fun, item );
626 else if ( !qobject_cast<QLineEdit*>(editor)->text().trimmed().isEmpty() )
628 QItemDelegate::setModelData( editor, model, index );
633 SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
634 coordToItem( sb->GetValue(), myCoordList->item( index.row() ));
638 } // namespace StdMeshersGUI
642 const double theAngTol = M_PI / 180.;
644 //================================================================================
646 * \brief Set variables to groups of spin boxes
648 //================================================================================
650 void setText( const QString& vars, SMESHGUI_SpinBox** spins )
652 QStringList varList = vars.split( ':' );
653 for ( int i = 0; i < 3 && i < varList.count(); ++i )
654 if ( !varList[i].isEmpty() )
655 spins[i]->setText( varList[i] );
658 //================================================================================
660 * \brief Computes more 2 axes by one
661 * \param [in] iOk - index of a given axis
662 * \param [in,out] dirs - directions of 3 axes
664 //================================================================================
666 void get3Dirs( int iOk, gp_XYZ dirs[3] )
668 dirs[ ( iOk+1 ) % 3 ] = dirs[ iOk ];
670 if ( Abs( dirs[ iOk ].Y() ) < 1e-100 &&
671 Abs( dirs[ iOk ].Z() ) < 1e-100 )
673 dirs[ ( iOk+1 ) % 3 ].SetY( dirs[ iOk ].Y() + 1. );
675 dirs[ ( iOk+1 ) % 3 ].SetX( dirs[ iOk ].X() + 1. );
677 dirs[( iOk+2 ) % 3] = dirs[ iOk ] ^ dirs[ ( iOk+1 ) % 3 ];
678 dirs[( iOk+1 ) % 3] = dirs[ ( iOk+2 ) % 3 ] ^ dirs[ iOk ];
681 //================================================================================
683 * \brief Returns a minimal width of a SpinBox depending on a precision type
685 //================================================================================
687 int getMinWidth( const char* precisionType )
689 int nb = SMESHGUI::resourceMgr()->integerValue( "SMESH", precisionType, -3 );
691 s.fill('0', qAbs(nb)+7 );
693 QFontMetrics metrics( le.font() );
694 return metrics.width( s );
698 //================================================================================
700 * \brief StdMeshersGUI_CartesianParamCreator constructor
702 //================================================================================
704 StdMeshersGUI_CartesianParamCreator::StdMeshersGUI_CartesianParamCreator(const QString& aHypType)
705 : StdMeshersGUI_StdHypothesisCreator( aHypType ),
712 myAxesPreview = new SMESHGUI_MeshEditPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
713 myAxesPreview->SetArrowShapeAndNb( /*nbArrows=*/3,
719 myDirTic[0] = myDirTic[1] = myDirTic[2] = 0;
722 //================================================================================
724 * \brief StdMeshersGUI_CartesianParamCreator destructor
726 //================================================================================
728 StdMeshersGUI_CartesianParamCreator::~StdMeshersGUI_CartesianParamCreator()
730 if ( myAxisTabs[0] ) delete myAxisTabs[0];
731 if ( myAxisTabs[1] ) delete myAxisTabs[1];
732 if ( myAxisTabs[2] ) delete myAxisTabs[2];
737 delete myAxesPreview;
740 //================================================================================
742 * \brief Validate parameters
744 //================================================================================
746 bool StdMeshersGUI_CartesianParamCreator::checkParams( QString& msg ) const
748 if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) )
751 if ( myName && myName->text().trimmed().isEmpty() )
753 msg = tr("SMESH_WRN_EMPTY_NAME");
756 if ( ! myThreshold->isValid( msg, true ))
759 SMESH::SMESH_Hypothesis_var hyp = hypothesis();
760 if ( !myAxisTabs[0]->checkParams( msg, hyp )) return false;
761 if ( !myAxisTabs[1]->checkParams( msg, hyp )) return false;
762 if ( !myAxisTabs[2]->checkParams( msg, hyp )) return false;
764 StdMeshersGUI_CartesianParamCreator* me = (StdMeshersGUI_CartesianParamCreator*) this;
765 if ( !me->updateAxesPreview() )
767 msg = tr("INVALID_AXES_DIR");
774 //================================================================================
776 * \brief Create widgets
778 //================================================================================
780 QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame()
782 QFrame* fr = new QFrame();
783 //fr->setMinimumWidth(460);
785 QVBoxLayout* lay = new QVBoxLayout( fr );
787 lay->setSpacing( SPACING );
789 QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
790 lay->addWidget( GroupC1 );
792 StdMeshers::StdMeshers_NumberOfSegments_var h =
793 StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
795 QGridLayout* argGroupLayout = new QGridLayout( GroupC1 );
796 argGroupLayout->setSpacing( SPACING );
797 argGroupLayout->setMargin( MARGIN );
798 argGroupLayout->setColumnStretch( 0, 0 );
799 argGroupLayout->setColumnStretch( 1, 1 );
806 myName = new QLineEdit( GroupC1 );
807 argGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
808 argGroupLayout->addWidget( myName, row, 1 );
813 argGroupLayout->addWidget( new QLabel( tr( "THRESHOLD" ), GroupC1 ), row, 0 );
814 myThreshold = new SMESHGUI_SpinBox( GroupC1 );
815 myThreshold->setAcceptNames( false ); // No Notebook variables allowed
816 myThreshold->RangeStepAndValidator( 1.00001, 1e+10, 1., "length_precision" );
817 argGroupLayout->addWidget( myThreshold, row, 1 );
820 // 2) "Implement edges"
821 myAddEdges = new QCheckBox( tr("ADD_EDGES"), GroupC1 );
822 argGroupLayout->addWidget( myAddEdges, row, 0, 1, 2 );
824 myCreateFaces = new QCheckBox( tr("CREATE_FACES"), GroupC1 );
825 argGroupLayout->addWidget( myCreateFaces, row, 0, 1, 2 );
827 myConsiderInternalFaces = new QCheckBox( tr("CONSIDER_INTERNAL_FACES"), GroupC1 );
828 argGroupLayout->addWidget( myConsiderInternalFaces, row, 0, 1, 2 );
830 myUseThresholdForInternalFaces = new QCheckBox( tr("USE_THRESHOLD_FOR_INTERNAL_FACES"), GroupC1 );
831 argGroupLayout->addWidget( myUseThresholdForInternalFaces, row, 0, 1, 2 );
834 // 3) Grid definition
835 QTabWidget* tabWdg = new QTabWidget( fr );
836 myAxisTabs[ 0 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 0 );
837 myAxisTabs[ 1 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 1 );
838 myAxisTabs[ 2 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 2 );
839 tabWdg->addTab( myAxisTabs[ 0 ], tr( "AXIS_X" ) );
840 tabWdg->addTab( myAxisTabs[ 1 ], tr( "AXIS_Y" ) );
841 tabWdg->addTab( myAxisTabs[ 2 ], tr( "AXIS_Z" ) );
842 argGroupLayout->addWidget( tabWdg, row, 0, 1, 2 );
845 QPixmap aPix = SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT"));
848 myFixedPointGrp = new QGroupBox( tr("FIXED_POINT"), fr );
849 myFixedPointGrp->setCheckable( true );
850 //QPushButton* pointBtn = new QPushButton( QIcon(aPix), "", myFixedPointGrp );
851 QLabel* pXLbl = new QLabel( tr("SMESH_X"), myFixedPointGrp );
852 QLabel* pYLbl = new QLabel( tr("SMESH_Y"), myFixedPointGrp );
853 QLabel* pZLbl = new QLabel( tr("SMESH_Z"), myFixedPointGrp );
854 for ( int i = 0; i < 3; ++i )
856 myPointSpin[i] = new SMESHGUI_SpinBox( myFixedPointGrp );
857 myPointSpin[i]->RangeStepAndValidator( -1e20, 1e20, 10 );
858 myPointSpin[i]->SetValue( 0. );
860 QHBoxLayout* aFixedPointLay = new QHBoxLayout( myFixedPointGrp );
861 aFixedPointLay->addWidget( pXLbl, 0, Qt::AlignRight );
862 aFixedPointLay->addWidget( myPointSpin[0], 1 );
863 aFixedPointLay->addWidget( pYLbl, 0, Qt::AlignRight );
864 aFixedPointLay->addWidget( myPointSpin[1], 1 );
865 aFixedPointLay->addWidget( pZLbl, 0, Qt::AlignRight );
866 aFixedPointLay->addWidget( myPointSpin[2], 1 );
867 argGroupLayout->addWidget( myFixedPointGrp, row, 0, 1, 2 );
871 QGroupBox* axesDirGrp = new QGroupBox( tr("AXES_DIRECTION"), fr );
872 QGridLayout* axisDirLay = new QGridLayout( axesDirGrp );
873 axisDirLay->setSpacing( SPACING );
874 axisDirLay->setMargin( MARGIN );
875 axisDirLay->setColumnStretch( 0, 2 );
877 myOrthogonalChk = new QCheckBox( tr("ORTHOGONAL_AXES"), axesDirGrp );
878 axisDirLay->addWidget( myOrthogonalChk, 0, 0, 1, 7 );
881 axisLbl[0] = new QLabel( tr( "AXIS_X"), axesDirGrp );
882 axisLbl[1] = new QLabel( tr( "AXIS_Y"), axesDirGrp );
883 axisLbl[2] = new QLabel( tr( "AXIS_Z"), axesDirGrp );
885 myAxisBtnGrp = new QButtonGroup( axesDirGrp );
887 const char * const precisionType = "len_tol_precision";
888 int minWidth = getMinWidth( precisionType );
889 for ( int i = 0; i < 3; ++i )
891 QPushButton* axisBtn = new QPushButton( QIcon(aPix), "", axesDirGrp );
892 axisBtn->setCheckable( true );
893 myAxisBtnGrp->addButton( axisBtn, i );
894 myXDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
895 myYDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
896 myZDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
897 myXDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
898 myYDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
899 myZDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
900 myXDirSpin[i]->setMinimumWidth( minWidth );
901 myYDirSpin[i]->setMinimumWidth( minWidth );
902 myZDirSpin[i]->setMinimumWidth( minWidth );
903 dLbl[0] = new QLabel( tr("SMESH_DX"), axesDirGrp );
904 dLbl[1] = new QLabel( tr("SMESH_DY"), axesDirGrp );
905 dLbl[2] = new QLabel( tr("SMESH_DZ"), axesDirGrp );
906 axisDirLay->addWidget( axisLbl[i], i+1, 0 );
907 axisDirLay->addWidget( axisBtn, i+1, 1 );
908 axisDirLay->addWidget( dLbl[0], i+1, 2 );
909 axisDirLay->addWidget( dLbl[1], i+1, 4 );
910 axisDirLay->addWidget( dLbl[2], i+1, 6 );
911 axisDirLay->addWidget( myXDirSpin[i], 1, 3+i*2 );
912 axisDirLay->addWidget( myYDirSpin[i], 2, 3+i*2 );
913 axisDirLay->addWidget( myZDirSpin[i], 3, 3+i*2 );
915 axisDirLay->setColumnStretch( 3, 10 );
916 axisDirLay->setColumnStretch( 5, 10 );
917 axisDirLay->setColumnStretch( 7, 10 );
920 QPushButton* optimBtn = new QPushButton( tr("OPTIMAL_AXES"), axesDirGrp );
921 QPushButton* resetBtn = new QPushButton( tr("RESET_AXES"), axesDirGrp );
922 axisDirLay->addWidget( optimBtn, 4, 0, 1, 4 );
923 axisDirLay->addWidget( resetBtn, 4, 4, 1, 4 );
925 argGroupLayout->addWidget( axesDirGrp, row, 0, 1, 2 );
930 LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( SMESHGUI::GetSMESHGUI() );
932 connect( selMgr, SIGNAL( currentSelectionChanged()), SLOT( onSelectionChange()));
933 connect( myOrthogonalChk, SIGNAL( toggled(bool)), SLOT( onOrthogonalAxes(bool)));
934 connect( optimBtn, SIGNAL( clicked(bool)), SLOT( onOptimalAxes(bool)));
935 connect( resetBtn, SIGNAL( clicked(bool)), SLOT( onResetAxes(bool)));
936 connect( myConsiderInternalFaces, SIGNAL( toggled(bool)),
937 myUseThresholdForInternalFaces, SLOT( setEnabled(bool)));
938 for ( int i = 0; i < 3; ++i )
940 connect( myXDirSpin[i], SIGNAL(valueChanged (const QString&)),
941 this, SLOT (onAxisDirChange(const QString&)) );
942 connect( myYDirSpin[i], SIGNAL(valueChanged (const QString&)),
943 this, SLOT (onAxisDirChange(const QString&)) );
944 connect( myZDirSpin[i], SIGNAL(valueChanged (const QString&)),
945 this, SLOT (onAxisDirChange(const QString&)) );
946 connect( myAxisTabs[i], SIGNAL(gridModeChanged(int)),
947 this, SLOT (onGridModeChanged(int)));
951 myAxesLen = 120; // default trihedron size is 100
952 myOrigin[0] = myOrigin[1] = myOrigin[2] = 0.;
954 QString shapeEntry = getMainShapeEntry();
955 if ( !shapeEntry.isEmpty() )
958 GEOM::GEOM_Object_var geomObj = SMESH::EntryToInterface<GEOM::GEOM_Object>( shapeEntry );
959 if ( GEOMBase::GetShape( geomObj, shape ) && !shape.IsNull())
962 BRepBndLib::Add( shape, box );
966 box.Get( myOrigin[0], myOrigin[1], myOrigin[2], max[0], max[1], max[2] );
967 gp_Pnt o( myOrigin[0], myOrigin[1], myOrigin[2] );
968 gp_Pnt x( max[0], max[1], max[2] );
969 myAxesLen = o.Distance( x );
972 while ( step > myAxesLen / 5 )
974 myPointSpin[0]->SetStep( step );
975 myPointSpin[1]->SetStep( step );
976 myPointSpin[2]->SetStep( step );
980 myAxisBtnGrp->button(0)->setEnabled( !shape.IsNull() );
981 myAxisBtnGrp->button(1)->setEnabled( !shape.IsNull() );
982 myAxisBtnGrp->button(2)->setEnabled( !shape.IsNull() );
983 optimBtn->setEnabled( !shape.IsNull() );
990 //================================================================================
992 * \brief Transfer parameters from hypothesis to widgets
994 //================================================================================
996 void StdMeshersGUI_CartesianParamCreator::retrieveParams() const
998 StdMeshers::StdMeshers_CartesianParameters3D_var h =
999 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( initParamsHypothesis() );
1002 myName->setText( hypName() );
1004 QString varName = getVariableName( "SetSizeThreshold" );
1005 if ( varName.isEmpty() )
1006 myThreshold->setValue( h->GetSizeThreshold() );
1008 myThreshold->setText( varName );
1010 myAddEdges->setChecked( h->GetToAddEdges() );
1011 myCreateFaces->setChecked( h->GetToCreateFaces() );
1012 myConsiderInternalFaces->setChecked( h->GetToConsiderInternalFaces() );
1013 myUseThresholdForInternalFaces->setChecked( h->GetToUseThresholdForInternalFaces() );
1016 for ( int ax = 0; ax < 3; ++ax )
1018 if ( h->IsGridBySpacing( ax ))
1020 SMESH::string_array_var funs;
1021 SMESH::double_array_var intPoints;
1022 h->GetGridSpacing( funs.out(), intPoints.out(), ax );
1023 myAxisTabs[ax]->setSpacing( funs, intPoints );
1027 SMESH::double_array_var coords = h->GetGrid( ax );
1028 myAxisTabs[ax]->setCoordinates( coords );
1033 SMESH::PointStruct fp;
1034 StdMeshersGUI_CartesianParamCreator* me = (StdMeshersGUI_CartesianParamCreator*) this;
1035 if ( h->GetFixedPoint( fp ))
1037 me->myPointSpin[0]->SetValue( fp.x );
1038 me->myPointSpin[1]->SetValue( fp.y );
1039 me->myPointSpin[2]->SetValue( fp.z );
1040 setText( getVariableName("GetFixedPoint"), &me->myPointSpin[0] );
1041 myFixedPointGrp->setChecked( true );
1045 myFixedPointGrp->setChecked( false );
1049 SMESHGUI_SpinBox** spins[3] = { &me->myXDirSpin[0], &me->myYDirSpin[0], &me->myZDirSpin[0] };
1050 SMESH::DirStruct axisDir[3];
1051 h->GetAxesDirs( axisDir[0],
1054 QString vars = getVariableName("GetAxesDirs");
1055 for ( int i = 0; i < 3; ++i )
1057 spins[i][0]->SetValue( axisDir[i].PS.x );
1058 spins[i][1]->SetValue( axisDir[i].PS.y );
1059 spins[i][2]->SetValue( axisDir[i].PS.z );
1060 setText( vars, spins[i] );
1062 // cut off 3 used vars
1063 if ( !vars.isEmpty() )
1066 for ( int j = 0; j < 3; ++j )
1067 if (( ind = vars.indexOf(':', ind+1 )) < 0 )
1072 vars.remove( 0, ind+1 );
1077 dlg()->setMinimumSize( dlg()->minimumSizeHint().width(),
1078 dlg()->minimumSizeHint().height() );
1081 //================================================================================
1083 * \brief Transfer parameters from widgets to hypothesis
1085 //================================================================================
1087 QString StdMeshersGUI_CartesianParamCreator::storeParams() const
1089 StdMeshers::StdMeshers_CartesianParameters3D_var h =
1090 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
1095 SMESH::SetName( SMESH::FindSObject( h ), myName->text().toUtf8().constData() );
1098 h->SetVarParameter( myThreshold->text().toLatin1().constData(), "SetSizeThreshold" );
1099 h->SetSizeThreshold( myThreshold->text().toDouble() );
1100 h->SetToAddEdges( myAddEdges->isChecked() );
1101 h->SetToCreateFaces( myCreateFaces->isChecked() );
1102 h->SetToConsiderInternalFaces( myConsiderInternalFaces->isChecked() );
1103 h->SetToUseThresholdForInternalFaces( myUseThresholdForInternalFaces->isChecked() );
1106 for ( int ax = 0; ax < 3; ++ax )
1108 if ( myAxisTabs[ax]->isGridBySpacing())
1110 SMESH::double_array_var intPoints;
1111 SMESH::string_array_var funs;
1112 myAxisTabs[ax]->getSpacing( funs.out(), intPoints.out() );
1113 h->SetGridSpacing( funs, intPoints, ax );
1117 SMESH::double_array_var coords = myAxisTabs[ax]->getCoordinates();
1118 h->SetGrid( coords, ax );
1124 params << myPointSpin[0]->text();
1125 params << myPointSpin[1]->text();
1126 params << myPointSpin[2]->text();
1127 h->SetVarParameter( params.join(":").toUtf8().constData(), "SetFixedPoint" );
1130 SMESH::PointStruct ps;
1131 ps.x = myPointSpin[0]->GetValue();
1132 ps.y = myPointSpin[1]->GetValue();
1133 ps.z = myPointSpin[2]->GetValue();
1134 h->SetFixedPoint( ps, !myFixedPointGrp->isEnabled() || !myFixedPointGrp->isChecked() );
1137 SMESHGUI_SpinBox* const * spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1138 for ( int ax = 0; ax < 3; ++ax )
1140 params << spins[ax][0]->text();
1141 params << spins[ax][1]->text();
1142 params << spins[ax][2]->text();
1144 h->SetVarParameter( params.join(":").toUtf8().constData(), "SetAxesDirs" );
1146 SMESH::DirStruct axDir[3];
1147 for ( int ax = 0; ax < 3; ++ax )
1149 axDir[ax].PS.x = spins[ax][0]->GetValue();
1150 axDir[ax].PS.y = spins[ax][1]->GetValue();
1151 axDir[ax].PS.z = spins[ax][2]->GetValue();
1153 h->SetAxesDirs( axDir[0], axDir[1], axDir[2] );
1156 catch(const SALOME::SALOME_Exception& ex)
1158 SalomeApp_Tools::QtCatchCorbaException(ex);
1163 //================================================================================
1165 * \brief Returns a name of help page
1167 //================================================================================
1169 QString StdMeshersGUI_CartesianParamCreator::helpPage() const
1171 return "cartesian_algo.html#cartesian-hyp-anchor";
1174 //================================================================================
1176 * \brief Show axes if they are OK
1178 //================================================================================
1180 bool StdMeshersGUI_CartesianParamCreator::updateAxesPreview()
1184 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1185 for ( int i = 0; i < 3 && isOk; ++i )
1187 gp_XYZ dir( spins[i][0]->GetValue(),
1188 spins[i][1]->GetValue(),
1189 spins[i][2]->GetValue());
1190 if (( isOk = ( dir.Modulus() > 1e-100 )))
1191 axes[i].SetDirection( gp_Dir( dir ));
1193 axes[i].SetLocation ( gp_Pnt( myOrigin[0],
1197 gp_Vec norm01 = axes[0].Direction().XYZ() ^ axes[1].Direction().XYZ();
1198 gp_Vec norm12 = axes[1].Direction().XYZ() ^ axes[2].Direction().XYZ();
1200 isOk = ( !axes[0].Direction().IsParallel( axes[1].Direction(), theAngTol ) &&
1201 !axes[1].Direction().IsParallel( axes[2].Direction(), theAngTol ) &&
1202 !axes[2].Direction().IsParallel( axes[0].Direction(), theAngTol ) &&
1203 !norm01.IsParallel( norm12, theAngTol ) );
1205 myAxesPreview->SetArrows( axes, myAxesLen );
1207 myAxesPreview->SetVisibility( isOk );
1212 //================================================================================
1214 * \brief Makes axes orthogonal if necessary
1216 //================================================================================
1218 void StdMeshersGUI_CartesianParamCreator::onOrthogonalAxes(bool isOrtho)
1222 updateAxesPreview();
1226 std::multimap< int, int > ageOfAxis;
1228 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1230 for ( int iAx = 0; iAx < 3; ++iAx )
1232 dirs[iAx].SetCoord( spins[iAx][0]->GetValue(),
1233 spins[iAx][1]->GetValue(),
1234 spins[iAx][2]->GetValue());
1235 if (( isOk = ( dirs[iAx].Modulus() > 1e-100 )))
1236 ageOfAxis.insert( std::make_pair( myDirTic[iAx], iAx ));
1238 ageOfAxis.insert( std::make_pair( -1, iAx ));
1245 dirs[0].SetCoord( 1, 0, 0 );
1246 dirs[1].SetCoord( 0, 1, 0 );
1247 dirs[2].SetCoord( 0, 0, 1 );
1252 int iOk = ageOfAxis.rbegin()->second;
1253 get3Dirs( iOk, dirs );
1257 std::multimap< int, int >::reverse_iterator ag2ax = ageOfAxis.rbegin();
1258 int iOk1 = ag2ax->second;
1259 int iOk2 = (++ag2ax)->second;
1260 int iKo = (++ag2ax)->second;
1261 if ( gp_Vec( dirs[ iOk1 ]).IsParallel( gp_Vec( dirs[ iOk2 ]), theAngTol ))
1262 std::swap( iOk2, iKo );
1263 if ( gp_Vec( dirs[ iOk1 ]).IsParallel( gp_Vec( dirs[ iOk2 ]), theAngTol ))
1265 get3Dirs( iOk1, dirs );
1269 dirs[ iKo ] = dirs[ iOk1 ] ^ dirs[ iOk2 ];
1270 dirs[ iOk2 ] = dirs[ iKo ] ^ dirs[ iOk1 ];
1271 if ( ( iOk1+1 ) % 3 != iOk2 )
1272 dirs[ iKo ].Reverse();
1276 for ( int iAx = 0; iAx < 3; ++iAx )
1278 double size = dirs[iAx].Modulus();
1279 if ( size > 1e-100 )
1281 for (int i = 0; i < 3; ++i )
1283 bool isBlocked = spins[iAx][i]->blockSignals( true );
1284 spins[iAx][i]->SetValue( dirs[iAx].Coord( i+1 ));
1285 spins[iAx][i]->blockSignals( isBlocked );
1289 updateAxesPreview();
1292 //================================================================================
1294 * \brief Increment myDirTic and update the preview of axes
1296 //================================================================================
1298 void StdMeshersGUI_CartesianParamCreator::onAxisDirChange(const QString&)
1300 QObject* changedSpin = sender();
1301 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1302 for ( int iAx = 0; iAx < 3; ++iAx )
1303 if ( spins[iAx][0] == changedSpin ||
1304 spins[iAx][1] == changedSpin ||
1305 spins[iAx][2] == changedSpin )
1307 myDirTic[ iAx ] = 1 + Max( Max( myDirTic[0], myDirTic[1] ), myDirTic[2] );
1311 onOrthogonalAxes( myOrthogonalChk->isChecked() );
1314 //================================================================================
1316 * \brief Sets axis direction by a selected EDGE
1318 //================================================================================
1320 void StdMeshersGUI_CartesianParamCreator::onSelectionChange()
1322 int iAxis = myAxisBtnGrp->checkedId();
1326 SALOME_ListIO aList;
1327 SMESHGUI::GetSMESHGUI()->selectionMgr()->selectedObjects(aList);
1329 TopoDS_Shape edge, shape;
1330 for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
1332 GEOM::GEOM_Object_var go = SMESH::IObjectToInterface<GEOM::GEOM_Object>( anIt.Value() );
1333 if ( GEOMBase::GetShape( go, shape ) && shape.ShapeType() == TopAbs_EDGE )
1335 if ( !edge.IsNull() )
1336 return; // several EDGEs selected
1340 if ( edge.IsNull() )
1344 TopoDS_Iterator vIt( edge );
1345 for ( ; vIt.More() && vv[1].IsNull(); vIt.Next() )
1346 vv[ !vv[0].IsNull() ] = vIt.Value();
1349 if ( !GEOMBase::VertexToPoint( vv[0], pp[0] ) ||
1350 !GEOMBase::VertexToPoint( vv[1], pp[1] ))
1353 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1355 gp_Vec newDir( pp[0], pp[1] );
1356 gp_Vec curDir( spins[iAxis][0]->GetValue(),
1357 spins[iAxis][1]->GetValue(),
1358 spins[iAxis][2]->GetValue());
1359 if ( newDir * curDir < 0 )
1362 double size = newDir.Magnitude();
1363 if ( size < 1e-100 )
1367 for (int i = 0; i < 3; ++i )
1369 bool isBlocked = spins[iAxis][i]->blockSignals( true );
1370 spins[iAxis][i]->SetValue( newDir.Coord( i+1 ));
1371 spins[iAxis][i]->blockSignals( isBlocked );
1373 myDirTic[ iAxis ] = 1 + Max( Max( myDirTic[0], myDirTic[1] ), myDirTic[2] );
1375 onOrthogonalAxes( myOrthogonalChk->isChecked() );
1378 //================================================================================
1380 * \brief Sets axes at which number of hexahedra is maximal
1382 //================================================================================
1384 void StdMeshersGUI_CartesianParamCreator::onOptimalAxes(bool)
1386 StdMeshers::StdMeshers_CartesianParameters3D_var h =
1387 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
1391 QString shapeEntry = getMainShapeEntry();
1392 if ( shapeEntry.isEmpty() )
1395 GEOM::GEOM_Object_var geomObj = SMESH::EntryToInterface<GEOM::GEOM_Object>( shapeEntry );
1396 if ( geomObj->_is_nil() )
1399 SMESH::DirStruct axDirs[3];
1400 h->ComputeOptimalAxesDirs( geomObj,
1401 myOrthogonalChk->isChecked(),
1406 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1407 for ( int iAx = 0; iAx < 3; ++iAx )
1409 double coords[3] = { axDirs[iAx].PS.x, axDirs[iAx].PS.y, axDirs[iAx].PS.z };
1410 for (int i = 0; i < 3; ++i )
1412 bool isBlocked = spins[iAx][i]->blockSignals( true );
1413 spins[iAx][i]->SetValue( coords[ i ]);
1414 spins[iAx][i]->blockSignals( isBlocked );
1417 updateAxesPreview();
1420 //================================================================================
1422 * \brief Sets axes || to the axes of global CS
1424 //================================================================================
1426 void StdMeshersGUI_CartesianParamCreator::onResetAxes(bool)
1428 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1429 for ( int iAx = 0; iAx < 3; ++iAx )
1431 for (int i = 0; i < 3; ++i )
1433 bool isBlocked = spins[iAx][i]->blockSignals( true );
1434 spins[iAx][i]->SetValue( iAx == i ? 1. : 0. );
1435 spins[iAx][i]->blockSignals( isBlocked );
1439 updateAxesPreview();
1442 //================================================================================
1444 * \brief SLOT called when the grid definition mode changes
1446 //================================================================================
1448 void StdMeshersGUI_CartesianParamCreator::onGridModeChanged(int)
1450 bool haveSpacing = ( myAxisTabs[0]->isGridBySpacing() ||
1451 myAxisTabs[1]->isGridBySpacing() ||
1452 myAxisTabs[2]->isGridBySpacing() );
1454 myFixedPointGrp->setEnabled( haveSpacing );