1 // Copyright (C) 2007-2016 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 : SMESHGUI_Measurements.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_Measurements.h"
27 #include "SMESH_Actor.h"
29 #include "SMESHGUI_IdValidator.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32 #include <SMESH_TypeFilter.hxx>
33 #include <SMESH_LogicalFilter.hxx>
35 #include <LightApp_SelectionMgr.h>
36 #include <SUIT_OverrideCursor.h>
37 #include <SUIT_ResourceMgr.h>
38 #include <SVTK_ViewWindow.h>
39 #include <SALOME_ListIO.hxx>
41 #include <QButtonGroup>
42 #include <QGridLayout>
44 #include <QHBoxLayout>
48 #include <QPushButton>
49 #include <QRadioButton>
51 #include <QVBoxLayout>
53 #include <vtkPoints.h>
54 #include <vtkUnstructuredGrid.h>
55 #include <vtkIdList.h>
56 #include <vtkCellArray.h>
57 #include <vtkUnsignedCharArray.h>
58 #include <vtkDataSetMapper.h>
59 #include <VTKViewer_CellLocationsArray.h>
60 #include <vtkProperty.h>
62 #include <SALOMEconfig.h>
63 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
64 #include CORBA_SERVER_HEADER(SMESH_Measurements)
66 const int SPACING = 6; // layout spacing
67 const int MARGIN = 9; // layout margin
68 const int MAX_NB_FOR_EDITOR = 40; // max nb of items in the ID list editor field
70 // Uncomment as soon as elements are supported by Min Distance operation
71 //#define MINDIST_ENABLE_ELEMENT
73 // Uncomment as soon as objects are supported by Min Distance operation
74 //#define MINDIST_ENABLE_OBJECT
77 \class SMESHGUI_MinDistance
78 \brief Minimum distance measurement widget.
80 Widget to calculate minimum distance between two objects.
85 \param parent parent widget
87 SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent )
88 : QWidget( parent ), myCurrentTgt( FirstTgt ), myFirstActor( 0 ), mySecondActor( 0 ), myPreview( 0 )
90 QGroupBox* aFirstTgtGrp = new QGroupBox( tr( "FIRST_TARGET" ), this );
91 QRadioButton* aFNode = new QRadioButton( tr( "NODE" ), aFirstTgtGrp );
92 QRadioButton* aFElem = new QRadioButton( tr( "ELEMENT" ), aFirstTgtGrp );
93 QRadioButton* aFObject = new QRadioButton( tr( "OBJECT" ), aFirstTgtGrp );
94 myFirstTgt = new QLineEdit( aFirstTgtGrp );
96 QGridLayout* fl = new QGridLayout( aFirstTgtGrp );
97 fl->setMargin( MARGIN );
98 fl->setSpacing( SPACING );
99 fl->addWidget( aFNode, 0, 0 );
100 fl->addWidget( aFElem, 0, 1 );
101 fl->addWidget( aFObject, 0, 2 );
102 fl->addWidget( myFirstTgt, 1, 0, 1, 3 );
104 myFirst = new QButtonGroup( this );
105 myFirst->addButton( aFNode, NodeTgt );
106 myFirst->addButton( aFElem, ElementTgt );
107 myFirst->addButton( aFObject, ObjectTgt );
109 QGroupBox* aSecondTgtGrp = new QGroupBox( tr( "SECOND_TARGET" ), this );
110 QRadioButton* aSOrigin = new QRadioButton( tr( "ORIGIN" ), aSecondTgtGrp );
111 QRadioButton* aSNode = new QRadioButton( tr( "NODE" ), aSecondTgtGrp );
112 QRadioButton* aSElem = new QRadioButton( tr( "ELEMENT" ), aSecondTgtGrp );
113 QRadioButton* aSObject = new QRadioButton( tr( "OBJECT" ), aSecondTgtGrp );
114 mySecondTgt = new QLineEdit( aSecondTgtGrp );
116 QGridLayout* sl = new QGridLayout( aSecondTgtGrp );
117 sl->setMargin( MARGIN );
118 sl->setSpacing( SPACING );
119 sl->addWidget( aSOrigin, 0, 0 );
120 sl->addWidget( aSNode, 0, 1 );
121 sl->addWidget( aSElem, 0, 2 );
122 sl->addWidget( aSObject, 0, 3 );
123 sl->addWidget( mySecondTgt, 1, 0, 1, 4 );
125 mySecond = new QButtonGroup( this );
126 mySecond->addButton( aSOrigin, OriginTgt );
127 mySecond->addButton( aSNode, NodeTgt );
128 mySecond->addButton( aSElem, ElementTgt );
129 mySecond->addButton( aSObject, ObjectTgt );
131 QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
133 QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this );
134 QLabel* aDxLab = new QLabel( "dX", aResults );
135 myDX = new QLineEdit( aResults );
136 QLabel* aDyLab = new QLabel( "dY", aResults );
137 myDY = new QLineEdit( aResults );
138 QLabel* aDzLab = new QLabel( "dZ", aResults );
139 myDZ = new QLineEdit( aResults );
140 QLabel* aDistLab = new QLabel( tr( "DISTANCE" ), aResults );
141 myDistance = new QLineEdit( aResults );
143 QGridLayout* rl = new QGridLayout( aResults );
144 rl->setMargin( MARGIN );
145 rl->setSpacing( SPACING );
146 rl->addWidget( aDxLab, 0, 0 );
147 rl->addWidget( myDX, 0, 1 );
148 rl->addWidget( aDyLab, 1, 0 );
149 rl->addWidget( myDY, 1, 1 );
150 rl->addWidget( aDzLab, 2, 0 );
151 rl->addWidget( myDZ, 2, 1 );
152 rl->addWidget( aDistLab, 0, 2 );
153 rl->addWidget( myDistance, 0, 3 );
155 QGridLayout* l = new QGridLayout( this );
156 l->setMargin( MARGIN );
157 l->setSpacing( SPACING );
159 l->addWidget( aFirstTgtGrp, 0, 0, 1, 2 );
160 l->addWidget( aSecondTgtGrp, 1, 0, 1, 2 );
161 l->addWidget( aCompute, 2, 0 );
162 l->addWidget( aResults, 3, 0, 1, 2 );
163 l->setColumnStretch( 1, 5 );
164 l->setRowStretch( 4, 5 );
166 aFNode->setChecked( true );
167 aSOrigin->setChecked( true );
168 #ifndef MINDIST_ENABLE_ELEMENT
169 aFElem->setEnabled( false ); // NOT AVAILABLE YET
170 aSElem->setEnabled( false ); // NOT AVAILABLE YET
172 #ifndef MINDIST_ENABLE_OBJECT
173 aFObject->setEnabled( false ); // NOT AVAILABLE YET
174 aSObject->setEnabled( false ); // NOT AVAILABLE YET
176 myDX->setReadOnly( true );
177 myDY->setReadOnly( true );
178 myDZ->setReadOnly( true );
179 myDistance->setReadOnly( true );
181 myValidator = new SMESHGUI_IdValidator( this, 1 );
183 myFirstTgt->installEventFilter( this );
184 mySecondTgt->installEventFilter( this );
186 connect( myFirst, SIGNAL( buttonClicked( int ) ), this, SLOT( firstChanged() ) );
187 connect( mySecond, SIGNAL( buttonClicked( int ) ), this, SLOT( secondChanged() ) );
188 connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) );
189 connect( myFirstTgt, SIGNAL( textEdited( QString ) ), this, SLOT( firstEdited() ) );
190 connect( mySecondTgt, SIGNAL( textEdited( QString ) ), this, SLOT( secondEdited() ) );
192 QList<SUIT_SelectionFilter*> filters;
193 filters.append( new SMESH_TypeFilter( SMESH::MESHorSUBMESH ) );
194 filters.append( new SMESH_TypeFilter( SMESH::GROUP ) );
195 myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
197 mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt );
200 //setTarget( FirstTgt );
207 SMESHGUI_MinDistance::~SMESHGUI_MinDistance()
218 \return \c true if event is filtered or \c false otherwise
220 bool SMESHGUI_MinDistance::eventFilter( QObject* o, QEvent* e )
222 if ( e->type() == QEvent::FocusIn ) {
223 if ( o == myFirstTgt )
224 setTarget( FirstTgt );
225 else if ( o == mySecondTgt )
226 setTarget( SecondTgt );
228 return QWidget::eventFilter( o, e );
232 \brief Setup selection mode depending on the current widget state
234 void SMESHGUI_MinDistance::updateSelection()
236 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
238 disconnect( selMgr, 0, this, 0 );
239 selMgr->clearFilters();
241 bool nodeMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == NodeTgt ) ||
242 ( myCurrentTgt == SecondTgt && mySecond->checkedId() == NodeTgt );
243 bool elemMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ElementTgt ) ||
244 ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ElementTgt );
245 bool objMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ObjectTgt ) ||
246 ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ObjectTgt ) ||
247 ( myCurrentTgt == NoTgt );
250 SMESH::SetPointRepresentation( true );
251 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
252 aViewWindow->SetSelectionMode( NodeSelection );
254 else if ( elemMode ) {
255 SMESH::SetPointRepresentation( false );
256 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
257 aViewWindow->SetSelectionMode( CellSelection );
259 else if ( objMode ) {
260 SMESH::SetPointRepresentation( false );
261 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
262 aViewWindow->SetSelectionMode( ActorSelection );
263 selMgr->installFilter( myFilter );
266 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
268 if ( myCurrentTgt == FirstTgt )
270 else if ( myCurrentTgt == SecondTgt )
273 //selectionChanged();
277 \brief Deactivate widget
279 void SMESHGUI_MinDistance::deactivate()
281 disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
285 \brief Set current target for selection
286 \param target new target ID
288 void SMESHGUI_MinDistance::setTarget( int target )
290 if ( myCurrentTgt != target ) {
291 myCurrentTgt = target;
297 \brief Erase preview actor
299 void SMESHGUI_MinDistance::erasePreview()
301 SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
302 if ( aViewWindow && myPreview ) {
303 aViewWindow->RemoveActor( myPreview );
304 aViewWindow->Repaint();
309 \brief Display preview actor
311 void SMESHGUI_MinDistance::displayPreview()
313 SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
314 if ( aViewWindow && myPreview ) {
315 aViewWindow->AddActor( myPreview );
316 aViewWindow->Repaint();
321 \brief Create preview actor
322 \param x1 X coordinate of first point
323 \param y1 X coordinate of first point
324 \param z1 Y coordinate of first point
325 \param x2 Y coordinate of second point
326 \param y2 Z coordinate of second point
327 \param z2 Z coordinate of second point
329 void SMESHGUI_MinDistance::createPreview( double x1, double y1, double z1, double x2, double y2, double z2 )
334 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
336 vtkPoints* aPoints = vtkPoints::New();
337 aPoints->SetNumberOfPoints( 2 );
338 aPoints->SetPoint( 0, x1, y1, z1 );
339 aPoints->SetPoint( 1, x2, y2, z2 );
340 aGrid->SetPoints( aPoints );
343 vtkIdList* anIdList = vtkIdList::New();
344 anIdList->SetNumberOfIds( 2 );
345 vtkCellArray* aCells = vtkCellArray::New();
346 aCells->Allocate( 2, 0);
347 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
348 aCellTypesArray->SetNumberOfComponents( 1 );
349 aCellTypesArray->Allocate( 1 );
350 anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 );
351 aCells->InsertNextCell( anIdList );
352 aCellTypesArray->InsertNextValue( VTK_LINE );
354 VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
355 aCellLocationsArray->SetNumberOfComponents( 1 );
356 aCellLocationsArray->SetNumberOfTuples( 1 );
357 aCells->InitTraversal();
358 for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ )
359 aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) );
360 aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
361 aCellLocationsArray->Delete();
362 aCellTypesArray->Delete();
365 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
366 aMapper->SetInputData( aGrid );
368 myPreview = SALOME_Actor::New();
369 myPreview->PickableOff();
370 myPreview->SetMapper( aMapper );
371 myPreview->SetResolveCoincidentTopology(true);
373 vtkProperty* aProp = vtkProperty::New();
374 aProp->SetRepresentationToWireframe();
375 aProp->SetColor( 250, 0, 250 );
376 aProp->SetPointSize( 5 );
377 aProp->SetLineWidth( 3 );
378 myPreview->SetProperty( aProp );
383 \brief Called when selection is changed
385 void SMESHGUI_MinDistance::selectionChanged()
387 SUIT_OverrideCursor wc;
389 SALOME_ListIO selected;
390 SMESHGUI::selectionMgr()->selectedObjects( selected );
392 if ( selected.Extent() == 1 ) {
393 Handle(SALOME_InteractiveObject) IO = selected.First();
394 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
395 if ( !CORBA::is_nil( obj ) ) {
396 if ( myCurrentTgt == FirstTgt ) {
398 myFirstActor = SMESH::FindActorByEntry( IO->getEntry() );
399 if ( myFirst->checkedId() == ObjectTgt ) {
401 SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
402 myFirstTgt->setText( aName );
405 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
408 if ( myFirstActor && selector ) {
409 nb = myFirst->checkedId() == NodeTgt ?
410 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
411 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
414 myFirstTgt->setText( ID.trimmed() );
419 else if ( myCurrentTgt == SecondTgt ) {
421 mySecondActor = SMESH::FindActorByEntry( IO->getEntry() );
422 if ( mySecond->checkedId() == ObjectTgt ) {
424 SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
425 mySecondTgt->setText( aName );
428 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
431 if ( mySecondActor && selector ) {
432 nb = mySecond->checkedId() == NodeTgt ?
433 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
434 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
437 mySecondTgt->setText( ID.trimmed() );
439 mySecondTgt->clear();
448 \brief Called when first target mode is changed by the user
450 void SMESHGUI_MinDistance::firstChanged()
452 myFirstSrc = SMESH::SMESH_IDSource::_nil();
454 myFirstTgt->setReadOnly( myFirst->checkedId() == ObjectTgt );
455 myFirstTgt->setValidator( myFirst->checkedId() == ObjectTgt ? 0 : myValidator );
456 setTarget( FirstTgt );
462 \brief Called when second target mode is changed by the user
464 void SMESHGUI_MinDistance::secondChanged()
466 mySecondSrc = SMESH::SMESH_IDSource::_nil();
467 mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt );
468 mySecondTgt->setReadOnly( mySecond->checkedId() == ObjectTgt );
469 mySecondTgt->setValidator( mySecond->checkedId() == ObjectTgt ? 0 : myValidator );
470 mySecondTgt->clear();
471 setTarget( mySecond->checkedId() != OriginTgt ? SecondTgt : NoTgt );
477 \brief Called when first target is edited by the user
479 void SMESHGUI_MinDistance::firstEdited()
481 setTarget( FirstTgt );
482 if ( sender() == myFirstTgt )
484 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
485 if ( myFirstActor && selector ) {
486 Handle(SALOME_InteractiveObject) IO = myFirstActor->getIO();
487 if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) {
488 TColStd_MapOfInteger ID;
489 ID.Add( myFirstTgt->text().toLong() );
490 selector->AddOrRemoveIndex( IO, ID, false );
492 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
493 aViewWindow->highlight( IO, true, true );
498 \brief Called when second target is edited by the user
500 void SMESHGUI_MinDistance::secondEdited()
502 setTarget( SecondTgt );
503 if ( sender() == mySecondTgt )
505 QString text = mySecondTgt->text();
506 if ( !mySecondActor )
509 mySecondTgt->setText( text );
511 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
512 if ( mySecondActor && selector ) {
513 Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO();
514 if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
515 if ( !text.isEmpty() ) {
516 TColStd_MapOfInteger ID;
517 ID.Add( text.toLong() );
518 selector->AddOrRemoveIndex( IO, ID, false );
521 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
522 aViewWindow->highlight( IO, true, true );
527 \brief Compute the minimum distance between targets
529 void SMESHGUI_MinDistance::compute()
531 SUIT_OverrideCursor wc;
532 SMESH::IDSource_wrap s1;
533 SMESH::IDSource_wrap s2;
534 bool isOrigin = mySecond->checkedId() == OriginTgt;
536 // process first target
537 if ( !CORBA::is_nil( myFirstSrc ) ) {
538 if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) {
539 SMESH::SMESH_Mesh_var m = myFirstSrc->GetMesh();
540 long id = myFirstTgt->text().toLong();
541 if ( !CORBA::is_nil( m ) && id ) {
542 SMESH::long_array_var ids = new SMESH::long_array();
545 SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
546 s1 = me->MakeIDSource( ids.in(), myFirst->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE );
555 // process second target
556 if ( !CORBA::is_nil( mySecondSrc ) ) {
557 if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
558 SMESH::SMESH_Mesh_var m = mySecondSrc->GetMesh();
559 long id = mySecondTgt->text().toLong();
560 if ( !CORBA::is_nil( m ) && id ) {
561 SMESH::long_array_var ids = new SMESH::long_array();
564 SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
565 s2 = me->MakeIDSource( ids.in(), mySecond->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE );
574 if ( !CORBA::is_nil( s1 ) && ( !CORBA::is_nil( s2 ) || isOrigin ) ) {
575 // compute min distance
576 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
577 SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
578 SMESH::Measure result = measure->MinDistance( s1.in(), s2.in() );
579 measure->UnRegister();
580 myDX->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
581 myDY->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
582 myDZ->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
583 myDistance->setText( QString::number( result.value, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
584 // update preview actor
586 double x1, y1, z1, x2, y2, z2;
587 SMESH::double_array_var coord = s1->GetMesh()->GetNodeXYZ( result.node1 );
588 x1 = coord[0]; y1 = coord[1]; z1 = coord[2];
593 coord = s2->GetMesh()->GetNodeXYZ( result.node2 );
594 x2 = coord[0]; y2 = coord[1]; z2 = coord[2];
596 createPreview( x1, y1, z1, x2, y2, z2 );
605 \brief Reset the widget to the initial state (nullify result fields)
607 void SMESHGUI_MinDistance::clear()
617 \class SMESHGUI_BoundingBox
618 \brief Bounding box measurement widget.
620 Widget to calculate bounding box of the selected object(s).
625 \param parent parent widget
627 SMESHGUI_BoundingBox::SMESHGUI_BoundingBox( QWidget* parent )
628 : QWidget( parent ), myActor( 0 ), myPreview( 0 )
630 QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE" ), this );
631 QRadioButton* aObjects = new QRadioButton( tr( "OBJECTS" ), aSourceGrp );
632 QRadioButton* aNodes = new QRadioButton( tr( "NODES" ), aSourceGrp );
633 QRadioButton* aElements = new QRadioButton( tr( "ELEMENTS" ), aSourceGrp );
634 mySource = new QLineEdit( aSourceGrp );
636 QGridLayout* fl = new QGridLayout( aSourceGrp );
637 fl->setMargin( MARGIN );
638 fl->setSpacing( SPACING );
639 fl->addWidget( aObjects, 0, 0 );
640 fl->addWidget( aNodes, 0, 1 );
641 fl->addWidget( aElements, 0, 2 );
642 fl->addWidget( mySource, 1, 0, 1, 3 );
644 mySourceMode = new QButtonGroup( this );
645 mySourceMode->addButton( aObjects, ObjectsSrc );
646 mySourceMode->addButton( aNodes, NodesSrc );
647 mySourceMode->addButton( aElements, ElementsSrc );
649 QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
651 QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this );
652 QLabel* aXminLab = new QLabel( "Xmin", aResults );
653 myXmin = new QLineEdit( aResults );
654 QLabel* aXmaxLab = new QLabel( "Xmax", aResults );
655 myXmax = new QLineEdit( aResults );
656 QLabel* aDxLab = new QLabel( "dX", aResults );
657 myDX = new QLineEdit( aResults );
658 QLabel* aYminLab = new QLabel( "Ymin", aResults );
659 myYmin = new QLineEdit( aResults );
660 QLabel* aYmaxLab = new QLabel( "Ymax", aResults );
661 myYmax = new QLineEdit( aResults );
662 QLabel* aDyLab = new QLabel( "dY", aResults );
663 myDY = new QLineEdit( aResults );
664 QLabel* aZminLab = new QLabel( "Zmin", aResults );
665 myZmin = new QLineEdit( aResults );
666 QLabel* aZmaxLab = new QLabel( "Zmax", aResults );
667 myZmax = new QLineEdit( aResults );
668 QLabel* aDzLab = new QLabel( "dZ", aResults );
669 myDZ = new QLineEdit( aResults );
671 QGridLayout* rl = new QGridLayout( aResults );
672 rl->setMargin( MARGIN );
673 rl->setSpacing( SPACING );
674 rl->addWidget( aXminLab, 0, 0 );
675 rl->addWidget( myXmin, 0, 1 );
676 rl->addWidget( aXmaxLab, 0, 2 );
677 rl->addWidget( myXmax, 0, 3 );
678 rl->addWidget( aDxLab, 0, 4 );
679 rl->addWidget( myDX, 0, 5 );
680 rl->addWidget( aYminLab, 1, 0 );
681 rl->addWidget( myYmin, 1, 1 );
682 rl->addWidget( aYmaxLab, 1, 2 );
683 rl->addWidget( myYmax, 1, 3 );
684 rl->addWidget( aDyLab, 1, 4 );
685 rl->addWidget( myDY, 1, 5 );
686 rl->addWidget( aZminLab, 2, 0 );
687 rl->addWidget( myZmin, 2, 1 );
688 rl->addWidget( aZmaxLab, 2, 2 );
689 rl->addWidget( myZmax, 2, 3 );
690 rl->addWidget( aDzLab, 2, 4 );
691 rl->addWidget( myDZ, 2, 5 );
693 QGridLayout* l = new QGridLayout( this );
694 l->setMargin( MARGIN );
695 l->setSpacing( SPACING );
697 l->addWidget( aSourceGrp, 0, 0, 1, 2 );
698 l->addWidget( aCompute, 1, 0 );
699 l->addWidget( aResults, 2, 0, 1, 2 );
700 l->setColumnStretch( 1, 5 );
701 l->setRowStretch( 3, 5 );
703 aObjects->setChecked( true );
704 myXmin->setReadOnly( true );
705 myXmax->setReadOnly( true );
706 myDX->setReadOnly( true );
707 myYmin->setReadOnly( true );
708 myYmax->setReadOnly( true );
709 myDY->setReadOnly( true );
710 myZmin->setReadOnly( true );
711 myZmax->setReadOnly( true );
712 myDZ->setReadOnly( true );
714 myValidator = new SMESHGUI_IdValidator( this );
716 connect( mySourceMode, SIGNAL( buttonClicked( int ) ), this, SLOT( sourceChanged() ) );
717 connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) );
718 connect( mySource, SIGNAL( textEdited( QString ) ), this, SLOT( sourceEdited() ) );
720 QList<SUIT_SelectionFilter*> filters;
721 filters.append( new SMESH_TypeFilter( SMESH::MESHorSUBMESH ) );
722 filters.append( new SMESH_TypeFilter( SMESH::GROUP ) );
723 myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
731 SMESHGUI_BoundingBox::~SMESHGUI_BoundingBox()
739 \brief Setup selection mode depending on the current widget state
741 void SMESHGUI_BoundingBox::updateSelection()
743 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
745 disconnect( selMgr, 0, this, 0 );
746 selMgr->clearFilters();
748 bool nodeMode = mySourceMode->checkedId() == NodesSrc;
749 bool elemMode = mySourceMode->checkedId() == ElementsSrc;
750 bool objMode = mySourceMode->checkedId() == ObjectsSrc;
753 SMESH::SetPointRepresentation( true );
754 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
755 aViewWindow->SetSelectionMode( NodeSelection );
757 else if ( elemMode ) {
758 SMESH::SetPointRepresentation( false );
759 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
760 aViewWindow->SetSelectionMode( CellSelection );
762 else if ( objMode ) {
763 SMESH::SetPointRepresentation( false );
764 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
765 aViewWindow->SetSelectionMode( ActorSelection );
766 selMgr->installFilter( myFilter );
769 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
773 if ( mySource->text().isEmpty() )
778 \brief Deactivate widget
780 void SMESHGUI_BoundingBox::deactivate()
782 disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
786 \brief Erase preview actor
788 void SMESHGUI_BoundingBox::erasePreview()
790 SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
791 if ( aViewWindow && myPreview ) {
792 aViewWindow->RemoveActor( myPreview );
793 aViewWindow->Repaint();
798 \brief Display preview actor
800 void SMESHGUI_BoundingBox::displayPreview()
802 SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
803 if ( aViewWindow && myPreview ) {
804 aViewWindow->AddActor( myPreview );
805 aViewWindow->Repaint();
810 \brief Create preview actor
811 \param minX min X coordinate of bounding box
812 \param maxX max X coordinate of bounding box
813 \param minY min Y coordinate of bounding box
814 \param maxY max Y coordinate of bounding box
815 \param minZ min Z coordinate of bounding box
816 \param maxZ max Z coordinate of bounding box
818 void SMESHGUI_BoundingBox::createPreview( double minX, double maxX, double minY, double maxY, double minZ, double maxZ )
823 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
825 vtkPoints* aPoints = vtkPoints::New();
826 aPoints->SetNumberOfPoints( 8 );
827 aPoints->SetPoint( 0, minX, minY, minZ );
828 aPoints->SetPoint( 1, maxX, minY, minZ );
829 aPoints->SetPoint( 2, minX, maxY, minZ );
830 aPoints->SetPoint( 3, maxX, maxY, minZ );
831 aPoints->SetPoint( 4, minX, minY, maxZ );
832 aPoints->SetPoint( 5, maxX, minY, maxZ );
833 aPoints->SetPoint( 6, minX, maxY, maxZ );
834 aPoints->SetPoint( 7, maxX, maxY, maxZ );
835 aGrid->SetPoints( aPoints );
838 // connectivity: 0-1 0-4 0-2 1-5 1-3 2-6 2-3 3-7 4-6 4-5 5-7 6-7
839 vtkIdList* anIdList = vtkIdList::New();
840 anIdList->SetNumberOfIds( 2 );
841 vtkCellArray* aCells = vtkCellArray::New();
842 aCells->Allocate( 2*12, 0);
843 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
844 aCellTypesArray->SetNumberOfComponents( 1 );
845 aCellTypesArray->Allocate( 12 );
846 anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 );
847 aCells->InsertNextCell( anIdList );
848 aCellTypesArray->InsertNextValue( VTK_LINE );
849 anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 4 );
850 aCells->InsertNextCell( anIdList );
851 aCellTypesArray->InsertNextValue( VTK_LINE );
852 anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 2 );
853 aCells->InsertNextCell( anIdList );
854 aCellTypesArray->InsertNextValue( VTK_LINE );
855 anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 5 );
856 aCells->InsertNextCell( anIdList );
857 aCellTypesArray->InsertNextValue( VTK_LINE );
858 anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 3 );
859 aCells->InsertNextCell( anIdList );
860 aCellTypesArray->InsertNextValue( VTK_LINE );
861 anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 6 );
862 aCells->InsertNextCell( anIdList );
863 aCellTypesArray->InsertNextValue( VTK_LINE );
864 anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 3 );
865 aCells->InsertNextCell( anIdList );
866 aCellTypesArray->InsertNextValue( VTK_LINE );
867 anIdList->SetId( 0, 3 ); anIdList->SetId( 1, 7 );
868 aCells->InsertNextCell( anIdList );
869 aCellTypesArray->InsertNextValue( VTK_LINE );
870 anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 6 );
871 aCells->InsertNextCell( anIdList );
872 aCellTypesArray->InsertNextValue( VTK_LINE );
873 anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 5 );
874 aCells->InsertNextCell( anIdList );
875 aCellTypesArray->InsertNextValue( VTK_LINE );
876 anIdList->SetId( 0, 5 ); anIdList->SetId( 1, 7 );
877 aCells->InsertNextCell( anIdList );
878 aCellTypesArray->InsertNextValue( VTK_LINE );
879 anIdList->SetId( 0, 6 ); anIdList->SetId( 1, 7 );
880 aCells->InsertNextCell( anIdList );
881 aCellTypesArray->InsertNextValue( VTK_LINE );
883 VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
884 aCellLocationsArray->SetNumberOfComponents( 1 );
885 aCellLocationsArray->SetNumberOfTuples( 12 );
886 aCells->InitTraversal();
887 for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ )
888 aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) );
889 aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
890 aCellLocationsArray->Delete();
891 aCellTypesArray->Delete();
894 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
895 aMapper->SetInputData( aGrid );
897 myPreview = SALOME_Actor::New();
898 myPreview->PickableOff();
899 myPreview->SetMapper( aMapper );
901 vtkProperty* aProp = vtkProperty::New();
902 aProp->SetRepresentationToWireframe();
903 aProp->SetColor( 250, 0, 250 );
904 aProp->SetPointSize( 5 );
905 aProp->SetLineWidth( 3 );
906 myPreview->SetProperty( aProp );
911 \brief Called when selection is changed
913 void SMESHGUI_BoundingBox::selectionChanged()
915 SUIT_OverrideCursor wc;
917 SALOME_ListIO selected;
918 SMESHGUI::selectionMgr()->selectedObjects( selected );
920 if ( selected.Extent() == 1 ) {
921 Handle(SALOME_InteractiveObject) IO = selected.First();
922 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
923 if ( !CORBA::is_nil( obj ) ) {
926 myActor = SMESH::FindActorByEntry( IO->getEntry() );
927 if ( mySourceMode->checkedId() == ObjectsSrc ) {
929 SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
930 mySource->setText( aName );
933 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
936 if ( myActor && selector ) {
937 nb = mySourceMode->checkedId() == NodesSrc ?
938 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
939 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
942 myIDs = ID.trimmed();
943 if ( nb < MAX_NB_FOR_EDITOR ) {
944 mySource->setReadOnly( false );
945 if ( mySource->validator() != myValidator )
946 mySource->setValidator( myValidator );
947 mySource->setText( ID.trimmed() );
950 mySource->setReadOnly( true );
951 mySource->setValidator( 0 );
952 mySource->setText( tr( "SELECTED_NB_OBJ" ).arg( nb )
953 .arg( mySourceMode->checkedId() == NodesSrc ? tr( "NB_NODES" ) : tr( "NB_ELEMENTS") ) );
959 mySource->setReadOnly( false );
960 mySource->setValidator( myValidator );
965 else if ( selected.Extent() > 1 ) {
967 SALOME_ListIteratorOfListIO It( selected );
970 if ( mySourceMode->checkedId() == ObjectsSrc ) {
971 for( ; It.More(); It.Next()){
972 Handle(SALOME_InteractiveObject) IO = It.Value();
973 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
974 if ( !CORBA::is_nil( obj ) ) {
979 SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
980 mySource->setText( aName );
990 \brief Called when source mode is changed by the user
992 void SMESHGUI_BoundingBox::sourceChanged()
996 mySource->setReadOnly( mySourceMode->checkedId() == ObjectsSrc );
997 mySource->setValidator( mySourceMode->checkedId() == ObjectsSrc ? 0 : myValidator );
1003 \brief Called when source mode is edited by the user
1005 void SMESHGUI_BoundingBox::sourceEdited()
1007 if ( sender() == mySource )
1009 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
1010 if ( myActor && selector ) {
1011 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
1012 if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) {
1013 TColStd_MapOfInteger ID;
1014 if ( !mySource->isReadOnly() )
1015 myIDs = mySource->text();
1016 QStringList ids = myIDs.split( " ", QString::SkipEmptyParts );
1017 foreach ( QString id, ids )
1018 ID.Add( id.trimmed().toLong() );
1019 selector->AddOrRemoveIndex( IO, ID, false );
1021 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
1022 aViewWindow->highlight( IO, true, true );
1027 \brief Calculate bounding box of the selected object(s)
1029 void SMESHGUI_BoundingBox::compute()
1031 SUIT_OverrideCursor wc;
1032 SMESH::ListOfIDSources_var srcList = new SMESH::ListOfIDSources();
1033 if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) {
1034 if ( mySrc.count() > 0 && !CORBA::is_nil( mySrc[0] ) ) {
1035 SMESH::SMESH_Mesh_var m = mySrc[0]->GetMesh();
1036 QStringList ids = myIDs.split( " ", QString::SkipEmptyParts );
1037 if ( !CORBA::is_nil( m ) && ids.count() > 0 ) {
1038 SMESH::long_array_var ids_in = new SMESH::long_array();
1039 ids_in->length( ids.count() );
1040 for( int i = 0; i < ids.count(); i++ )
1041 ids_in[i] = ids[i].trimmed().toLong();
1042 SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
1043 SMESH::SMESH_IDSource_var s = me->MakeIDSource( ids_in.in(), mySourceMode->checkedId() == NodesSrc ? SMESH::NODE : SMESH::FACE );
1044 srcList->length( 1 );
1050 srcList->length( mySrc.count() );
1051 for( int i = 0; i < mySrc.count(); i++ ) {
1052 srcList[i] = mySrc[i];
1053 mySrc[i]->Register();
1056 if ( srcList->length() > 0 ) {
1057 // compute bounding box
1058 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1059 SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
1060 SMESH::Measure result = measure->BoundingBox( srcList.in() );
1061 SALOME::UnRegister( srcList );
1062 measure->UnRegister();
1063 myXmin->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1064 myXmax->setText( QString::number( result.maxX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1065 myDX->setText( QString::number( result.maxX-result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1066 myYmin->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1067 myYmax->setText( QString::number( result.maxY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1068 myDY->setText( QString::number( result.maxY-result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1069 myZmin->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1070 myZmax->setText( QString::number( result.maxZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1071 myDZ->setText( QString::number( result.maxZ-result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1072 // update preview actor
1074 createPreview( result.minX, result.maxX, result.minY, result.maxY, result.minZ, result.maxZ );
1083 \brief Reset the widget to the initial state (nullify result fields)
1085 void SMESHGUI_BoundingBox::clear()
1100 \class SMESHGUI_BasicProperties
1101 \brief basic properties measurement widget.
1103 Widget to calculate length, area or volume for the selected object(s).
1108 \param parent parent widget
1110 SMESHGUI_BasicProperties::SMESHGUI_BasicProperties( QWidget* parent )
1113 // Property (length, area or volume)
1114 QGroupBox* aPropertyGrp = new QGroupBox( tr( "PROPERTY" ), this );
1116 QRadioButton* aLength = new QRadioButton( tr( "LENGTH" ), aPropertyGrp );
1117 QRadioButton* anArea = new QRadioButton( tr( "AREA" ), aPropertyGrp );
1118 QRadioButton* aVolume = new QRadioButton( tr( "VOLUME" ), aPropertyGrp );
1120 myMode = new QButtonGroup( this );
1121 myMode->addButton( aLength, Length );
1122 myMode->addButton( anArea, Area );
1123 myMode->addButton( aVolume, Volume );
1125 QHBoxLayout* aPropertyLayout = new QHBoxLayout;
1126 aPropertyLayout->addWidget( aLength );
1127 aPropertyLayout->addWidget( anArea );
1128 aPropertyLayout->addWidget( aVolume );
1130 aPropertyGrp->setLayout( aPropertyLayout );
1133 QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE_MESH_SUBMESH_GROUP" ), this );
1135 mySource = new QLineEdit( aSourceGrp );
1136 mySource->setReadOnly( true );
1138 QHBoxLayout* aSourceLayout = new QHBoxLayout;
1139 aSourceLayout->addWidget( mySource );
1141 aSourceGrp->setLayout( aSourceLayout );
1144 QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
1146 // Result of computation (length, area or volume)
1147 myResultGrp = new QGroupBox( this );
1149 myResult = new QLineEdit;
1150 myResult->setReadOnly( true );
1152 QHBoxLayout* aResultLayout = new QHBoxLayout;
1153 aResultLayout->addWidget( myResult );
1155 myResultGrp->setLayout( aResultLayout );
1158 QGridLayout* aMainLayout = new QGridLayout( this );
1159 aMainLayout->setMargin( MARGIN );
1160 aMainLayout->setSpacing( SPACING );
1162 aMainLayout->addWidget( aPropertyGrp, 0, 0, 1, 2 );
1163 aMainLayout->addWidget( aSourceGrp, 1, 0, 1, 2 );
1164 aMainLayout->addWidget( aCompute, 2, 0 );
1165 aMainLayout->addWidget( myResultGrp, 3, 0, 1, 2 );
1166 aMainLayout->setColumnStretch( 1, 5 );
1167 aMainLayout->setRowStretch( 4, 5 );
1173 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged( int ) ) );
1174 connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) );
1177 QList<SUIT_SelectionFilter*> filters;
1178 filters.append( new SMESH_TypeFilter( SMESH::MESHorSUBMESH ) );
1179 filters.append( new SMESH_TypeFilter( SMESH::GROUP ) );
1180 myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
1186 SMESHGUI_BasicProperties::~SMESHGUI_BasicProperties()
1191 \brief Sets the measurement mode.
1192 \param theMode the mode to set (length, area or volume meausurement)
1194 void SMESHGUI_BasicProperties::setMode( const Mode theMode )
1196 QRadioButton* aButton = qobject_cast<QRadioButton*>( myMode->button( theMode ) );
1198 aButton->setChecked( true );
1199 modeChanged( theMode );
1204 \brief Setup the selection mode.
1206 void SMESHGUI_BasicProperties::updateSelection()
1208 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
1210 disconnect( selMgr, 0, this, 0 );
1211 selMgr->clearFilters();
1213 SMESH::SetPointRepresentation( false );
1214 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
1215 aViewWindow->SetSelectionMode( ActorSelection );
1217 selMgr->installFilter( myFilter );
1219 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
1221 if ( mySource->text().isEmpty() )
1226 \brief Deactivate widget
1228 void SMESHGUI_BasicProperties::deactivate()
1230 disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
1234 \brief Called when selection is changed
1236 void SMESHGUI_BasicProperties::selectionChanged()
1238 SUIT_OverrideCursor wc;
1240 SALOME_ListIO selected;
1241 SMESHGUI::selectionMgr()->selectedObjects( selected );
1243 if ( selected.Extent() == 1 ) {
1244 Handle(SALOME_InteractiveObject) IO = selected.First();
1245 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
1246 if ( !CORBA::is_nil( obj ) ) {
1250 SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
1251 mySource->setText( aName );
1259 \brief Called when the measurement mode selection is changed.
1260 \param theMode the selected mode
1262 void SMESHGUI_BasicProperties::modeChanged( int theMode )
1266 if ( theMode == Length ) {
1267 myResultGrp->setTitle( tr("LENGTH") );
1268 } else if ( theMode == Area ) {
1269 myResultGrp->setTitle( tr("AREA") );
1270 } else if ( theMode == Volume ) {
1271 myResultGrp->setTitle( tr("VOLUME") );
1276 \brief Calculate length, area or volume for the selected object(s)
1278 void SMESHGUI_BasicProperties::compute()
1280 SUIT_OverrideCursor wc;
1282 SMESH::SMESH_IDSource_var source;
1284 if ( !CORBA::is_nil( mySrc ) ) {
1286 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1287 SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
1291 if ( myMode->checkedId() == Length ) {
1292 result = measure->Length( mySrc.in() );
1293 } else if ( myMode->checkedId() == Area ) {
1294 result = measure->Area( mySrc.in() );
1295 } else if ( myMode->checkedId() == Volume ) {
1296 result = measure->Volume( mySrc.in() );
1299 measure->UnRegister();
1301 myResult->setText( QString::number( result, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1308 \brief Reset the widget to the initial state (nullify the result field)
1310 void SMESHGUI_BasicProperties::clear()
1316 \class SMESHGUI_MeshInfoDlg
1317 \brief Centralized dialog box for the measurements
1322 \param parent parent widget
1323 \param page specifies the dialog page to be shown at the start-up
1325 SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page )
1329 setAttribute( Qt::WA_DeleteOnClose, true );
1330 setWindowTitle( tr( "MEASUREMENTS" ) );
1331 setSizeGripEnabled( true );
1333 SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
1335 myTabWidget = new QTabWidget( this );
1339 myMinDist = new SMESHGUI_MinDistance( myTabWidget );
1340 int aMinDistInd = myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) );
1344 myBndBox = new SMESHGUI_BoundingBox( myTabWidget );
1345 int aBndBoxInd = myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) );
1349 myBasicProps = new SMESHGUI_BasicProperties( myTabWidget );
1350 int aBasicPropInd = myTabWidget->addTab( myBasicProps, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BASIC_PROPS" ) ), tr( "BASIC_PROPERTIES" ) );
1353 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
1354 okBtn->setAutoDefault( true );
1355 okBtn->setDefault( true );
1357 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
1358 helpBtn->setAutoDefault( true );
1360 QHBoxLayout* btnLayout = new QHBoxLayout;
1361 btnLayout->setSpacing( SPACING );
1362 btnLayout->setMargin( 0 );
1363 btnLayout->addWidget( okBtn );
1364 btnLayout->addStretch( 10 );
1365 btnLayout->addWidget( helpBtn );
1367 QVBoxLayout* l = new QVBoxLayout ( this );
1368 l->setMargin( MARGIN );
1369 l->setSpacing( SPACING );
1370 l->addWidget( myTabWidget );
1372 l->addLayout( btnLayout );
1375 if ( page == MinDistance ) {
1376 anInd = aMinDistInd;
1377 } else if ( page == BoundingBox ) {
1379 } else if ( page == Length || page == Area || page == Volume ) {
1380 myBasicProps->setMode( (SMESHGUI_BasicProperties::Mode)(page - Length) );
1381 anInd = aBasicPropInd;
1385 myTabWidget->setCurrentIndex( anInd );
1388 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
1389 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
1390 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
1391 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
1392 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
1400 SMESHGUI_MeasureDlg::~SMESHGUI_MeasureDlg()
1405 \brief Perform clean-up actions on the dialog box closing.
1407 void SMESHGUI_MeasureDlg::reject()
1409 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
1410 selMgr->clearFilters();
1411 SMESH::SetPointRepresentation( false );
1412 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
1413 aViewWindow->SetSelectionMode( ActorSelection );
1418 \brief Process keyboard event
1419 \param e key press event
1421 void SMESHGUI_MeasureDlg::keyPressEvent( QKeyEvent* e )
1423 QDialog::keyPressEvent( e );
1424 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
1431 \brief Reactivate dialog box, when mouse pointer goes into it.
1433 void SMESHGUI_MeasureDlg::enterEvent( QEvent* )
1439 \brief Setup selection mode depending on the current dialog box state.
1441 void SMESHGUI_MeasureDlg::updateSelection()
1443 if ( myTabWidget->currentIndex() == MinDistance )
1444 myMinDist->updateSelection();
1445 else if ( myTabWidget->currentIndex() == BoundingBox )
1446 myBndBox->updateSelection();
1448 myBndBox->erasePreview();
1449 myBasicProps->updateSelection();
1454 \brief Show help page
1456 void SMESHGUI_MeasureDlg::help()
1459 if ( myTabWidget->currentIndex() == MinDistance ) {
1460 aHelpFile = "measurements_page.html#min_distance_anchor";
1461 } else if ( myTabWidget->currentIndex() == BoundingBox ) {
1462 aHelpFile = "measurements_page.html#bounding_box_anchor";
1464 aHelpFile = "measurements_page.html#basic_properties_anchor";
1467 SMESH::ShowHelpFile( aHelpFile );
1471 \brief Activate dialog box
1473 void SMESHGUI_MeasureDlg::activate()
1475 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
1476 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
1477 myTabWidget->setEnabled( true );
1482 \brief Deactivate dialog box
1484 void SMESHGUI_MeasureDlg::deactivate()
1486 myBasicProps->deactivate();
1487 myMinDist->deactivate();
1488 myBndBox->deactivate();
1489 myTabWidget->setEnabled( false );
1490 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );