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_MeshInfo.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_MeshInfo.h"
27 #include "SMDS_Mesh.hxx"
28 #include "SMDS_VolumeTool.hxx"
29 #include "SMESH_Actor.h"
31 #include "SMESHGUI_FilterUtils.h"
32 #include "SMESHGUI_IdPreview.h"
33 #include "SMESHGUI_IdValidator.h"
34 #include "SMESHGUI_SpinBox.h"
35 #include "SMESHGUI_Utils.h"
36 #include "SMESHGUI_VTKUtils.h"
38 #include <SUIT_FileDlg.h>
39 #include <SUIT_OverrideCursor.h>
40 #include <SUIT_ResourceMgr.h>
41 #include <SUIT_Session.h>
42 #include <SVTK_ViewWindow.h>
43 #include <LightApp_SelectionMgr.h>
45 #include <SALOMEDSClient_Study.hxx>
47 #include <QApplication>
48 #include <QButtonGroup>
51 #include <QContextMenuEvent>
52 #include <QGridLayout>
53 #include <QHBoxLayout>
54 #include <QHeaderView>
55 #include <QItemDelegate>
60 #include <QPushButton>
61 #include <QRadioButton>
62 #include <QStackedWidget>
63 #include <QStandardItemModel>
65 #include <QTextBrowser>
66 #include <QTextStream>
67 #include <QToolButton>
68 #include <QTreeWidget>
69 #include <QVBoxLayout>
73 const int SPACING = 6;
84 TypeRole = Qt::UserRole + 10,
90 NodeConnectivity = 100,
95 \brief Get item's depth in the tree.
96 \param item Tree widget item.
97 \return Item's depth in the tree widget (top-level item has zero depth).
100 int itemDepth( QTreeWidgetItem* item )
102 QList<QTreeWidgetItem*> parents;
104 while ( parents.last()->parent() )
105 parents << parents.last()->parent();
106 return parents.size()-1;
110 \brief Get chunk size.
120 \brief Get spacer for data information.
121 \return Spacer string.
127 static QChar spacer = ' ';
128 return QString( size, spacer );
132 \brief Get indent for data information.
133 \param length Indent size. Defaults to 1.
134 \return Indentation string.
137 QString indent( int length = 1 )
140 static QChar spacer = ' ';
141 return QString( size * length, spacer );
145 \brief Get group separator for data information.
146 \param length Length of ruler (number of symbols). Defaults to 80.
147 \return Ruler string.
150 QString ruler( int length = 80 )
152 static QChar ruler = '-';
153 return QString( length, ruler );
157 \brief Get text value from label.
158 \param w Widget (QLabel).
159 \return Value string.
162 QString widgetValue( QWidget* w )
165 if ( qobject_cast<QLabel*>( w ) )
166 v = qobject_cast<QLabel*>( w )->text();
169 } // end of anonymous namespace
171 ////////////////////////////////////////////////////////////////////////////////
173 /// \brief Field widget.
175 ////////////////////////////////////////////////////////////////////////////////
177 class Field : public QLabel
180 Field( QWidget*, const QString& = QString() );
181 bool event( QEvent* );
186 \param parent Parent widget.
187 \param name Field name. Defauls to null string.
189 Field::Field( QWidget* parent, const QString& name ): QLabel( parent )
191 setFrameStyle( QLabel::StyledPanel | QLabel::Sunken );
192 setAlignment( Qt::AlignCenter );
193 setAutoFillBackground( true );
194 QPalette pal = palette();
195 QColor base = QApplication::palette().color( QPalette::Active, QPalette::Base );
196 pal.setColor( QPalette::Window, base );
198 setMinimumWidth( 60 );
199 if ( !name.isEmpty() )
200 setObjectName( name );
204 \brief Event handler. Redefined from QLabel.
206 bool Field::event( QEvent* e )
208 if ( e->type() == QEvent::DynamicPropertyChange )
210 QDynamicPropertyChangeEvent* ce = (QDynamicPropertyChangeEvent*)e;
211 if ( ce->propertyName() == "value" && property( "value" ).isValid() )
213 setText( QString::number( property( "value" ).toInt() ) );
214 setProperty( "value", QVariant() );
218 return QLabel::event( e );
221 ////////////////////////////////////////////////////////////////////////////////
222 /// \class SMESHGUI_Info
223 /// \brief Base widget for all information panes.
224 ////////////////////////////////////////////////////////////////////////////////
228 \param parent Parent widget. Defaults to 0.
230 SMESHGUI_Info::SMESHGUI_Info( QWidget* parent ): QWidget( parent )
235 \brief Get font for given options.
236 \param options Font attributes.
239 QFont SMESHGUI_Info::fontFromOptions( int options )
242 f.setBold( options & Bold );
243 f.setItalic( options & Italic );
248 \brief Set font attributes to given widget.
250 \param options Font attributes.
252 void SMESHGUI_Info::setFontAttributes( QWidget* w, int options )
255 w->setFont( fontFromOptions( options ) );
259 \brief Set font attributes to given tree item.
260 \param item Tree widget item.
261 \param options Font attributes.
263 void SMESHGUI_Info::setFontAttributes( QTreeWidgetItem* item, int options )
265 if ( item && item->treeWidget() )
267 for ( int i = 0; i < item->treeWidget()->columnCount(); i++ )
269 if ( i == 0 || options & AllColumns )
270 item->setFont( i, fontFromOptions( options) );
277 \param parent Parent widget.
278 \param options Label options. Defaults to 0 (none).
281 QLabel* SMESHGUI_Info::createLabel( QWidget* parent, int options )
283 QLabel* lab = new QLabel( parent );
284 setFontAttributes( lab, options );
290 \param text Label text.
291 \param parent Parent widget.
292 \param options Label options. Defaults to 0 (none).
295 QLabel* SMESHGUI_Info::createLabel( const QString& text, QWidget* parent, int options )
297 QLabel* lab = createLabel( parent, options );
298 lab->setText( text );
303 \brief Create information field.
304 \param parent Parent widget.
305 \param name Field's object. Default to null string.
308 QLabel* SMESHGUI_Info::createField( QWidget* parent, const QString& name )
310 return new Field( parent, name );
314 \brief Create information field.
315 \param parent Parent widget.
316 \param options Label options.
317 \param name Field's object. Default to null string.
320 QLabel* SMESHGUI_Info::createField( QWidget* parent, int options, const QString& name )
322 QLabel* field = createField( parent, name );
323 setFontAttributes( field, options );
329 \param parent Parent widget.
330 \param orientation Ruler orientation. Defaults to horizontal.
333 QWidget* SMESHGUI_Info::createSeparator( QWidget* parent, Qt::Orientation orientation )
335 QFrame* line = new QFrame( parent );
336 line->setFrameShape( orientation == Qt::Horizontal ? QFrame::HLine : QFrame::HLine );
337 line->setFrameShadow( QFrame::Sunken );
341 ////////////////////////////////////////////////////////////////////////////////
342 /// \class ExtraWidget
343 /// \brief Auxiliary widget to browse between chunks of information.
345 ////////////////////////////////////////////////////////////////////////////////
347 class ExtraWidget : public QWidget
350 ExtraWidget( QWidget*, bool = false );
351 void updateControls( int, int );
362 \param parent Parent widget.
363 \param briefSummary Show summary in brief format. Defaults to \c false.
365 ExtraWidget::ExtraWidget( QWidget* parent, bool briefSummary ): QWidget( parent ), brief( briefSummary )
367 current = new QLabel( this );
368 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
369 prev = new QPushButton( "<<", this );
370 next = new QPushButton( ">>", this );
371 QHBoxLayout* hbl = new QHBoxLayout( this );
373 hbl->setSpacing( SPACING );
375 hbl->addWidget( current );
376 hbl->addWidget( prev );
377 hbl->addWidget( next );
381 \brief Update controls.
382 \param total Total number of items.
383 \param index Current index.
385 void ExtraWidget::updateControls( int total, int index )
387 setVisible( total > blockSize() );
388 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
389 current->setText( format.arg( index*blockSize()+1 ).arg( qMin( index*blockSize()+blockSize(), total ) ).arg( total ) );
390 prev->setEnabled( index > 0 );
391 next->setEnabled( (index+1)*blockSize() < total );
394 ////////////////////////////////////////////////////////////////////////////////
395 /// \class DumpFileDlg
396 /// \brief Save file dialog box, customized for dump info operation.
398 ////////////////////////////////////////////////////////////////////////////////
400 class DumpFileDlg : public SUIT_FileDlg
402 QMap<int, QCheckBox*> myControls;
404 DumpFileDlg( QWidget*, bool = true );
405 bool isChecked( int ) const;
406 void setChecked( int, bool );
411 \param parent Parent widget.
412 \param showControls Show additional controls. Defaults to \c true.
415 DumpFileDlg::DumpFileDlg( QWidget* parent, bool showControls ): SUIT_FileDlg( parent, false, true, true )
419 QWidget* hB = new QWidget( this );
420 myControls[SMESHGUI_MeshInfoDlg::BaseInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
421 myControls[SMESHGUI_MeshInfoDlg::ElemInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
422 myControls[SMESHGUI_MeshInfoDlg::AddInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
423 myControls[SMESHGUI_MeshInfoDlg::CtrlInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
425 QGridLayout* layout = new QGridLayout( hB );
426 layout->setMargin( 0 );
427 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::BaseInfo], 0, 0 );
428 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::ElemInfo], 0, 1 );
429 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::AddInfo], 1, 0 );
430 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::CtrlInfo], 1, 1 );
432 addWidgets( 0, hB, 0 );
437 \brief Get control's value.
438 \param option Control identifier.
439 \return Control value.
442 bool DumpFileDlg::isChecked( int option ) const
444 return myControls.contains( option ) ? myControls[option]->isChecked() : false;
448 \brief Set control's initial value.
449 \param option Control identifier.
450 \param value Control value.
453 void DumpFileDlg::setChecked( int option, bool value )
455 if ( myControls.contains( option ) )
456 myControls[option]->setChecked( value );
459 ////////////////////////////////////////////////////////////////////////////////
460 /// \class SMESHGUI_BaseInfo
461 /// \brief Show basic information on selected object.
463 /// Displays the base information about selected object: mesh, sub-mesh, group
464 /// or arbitrary ID source.
465 /// \todo Hide unnecessary widgets (e.g. for mesh group).
466 ////////////////////////////////////////////////////////////////////////////////
470 \param parent Parent widget. Defaults to 0.
472 SMESHGUI_BaseInfo::SMESHGUI_BaseInfo( QWidget* parent ): SMESHGUI_Info( parent )
474 QGridLayout* l = new QGridLayout( this );
475 l->setMargin( MARGIN );
476 l->setSpacing( SPACING );
480 addWidget( createLabel( tr( "NAME_LAB" ), this, Bold ), iName, iLabel );
481 addWidget( createField( this, "meshName" ), iName, iSingle, 4 )->setMinimumWidth( 150 );
483 addWidget( createLabel( tr( "OBJECT_LAB" ), this, Bold ), iObject, iLabel );
484 addWidget( createField( this, "meshType" ), iObject, iSingle, 4 )->setMinimumWidth( 150 );
486 addWidget( createSeparator( this ), iObjectEnd, iLabel, 5 );
490 addWidget( createLabel( tr( "NODES_LAB" ), this, Bold ), iNodes, iLabel );
491 addWidget( createField( this, "nbNodes" ), iNodes, iTotal );
493 addWidget( createSeparator( this ), iNodesEnd, iLabel, 5 );
497 addWidget( createLabel( tr( "ELEMENTS_LAB" ), this, Bold ), iElementsTitle, iLabel );
498 addWidget( createLabel( tr( "TOTAL_LAB" ), this, Italic ), iElementsTitle, iTotal );
499 addWidget( createLabel( tr( "LINEAR_LAB" ), this, Italic ), iElementsTitle, iLinear );
500 addWidget( createLabel( tr( "QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iQuadratic );
501 addWidget( createLabel( tr( "BI_QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iBiQuadratic );
503 addWidget( createSeparator( this ), iElementsTitleEnd, iTotal, 4 );
505 addWidget( createField( this, "totalNbElems" ), iElementsTotal, iTotal );
506 addWidget( createField( this, "totalNbLinearElems" ), iElementsTotal, iLinear );
507 addWidget( createField( this, "totalNbQuadraticElems" ), iElementsTotal, iQuadratic );
508 addWidget( createField( this, "totalNbBiQuadraticElems" ), iElementsTotal, iBiQuadratic );
510 addWidget( createSeparator( this ), iElementsTotalEnd, iTotal, 4 );
511 // - 0D elements info
512 addWidget( createLabel( tr( "0D_LAB" ), this, Bold | Italic ), i0D, iLabel );
513 addWidget( createField( this, "nb0D" ), i0D, iTotal );
515 addWidget( createSeparator( this ), i0DEnd, iTotal, 4 );
517 addWidget( createLabel( tr( "BALL_LAB" ), this, Bold | Italic ), iBalls, iLabel );
518 addWidget( createField( this, "nbBall" ), iBalls, iTotal );
520 addWidget( createSeparator( this ), iBallsEnd, iTotal, 4 );
521 // - 1D elements info
522 addWidget( createLabel( tr( "1D_LAB" ), this, Bold | Italic ), i1D, iLabel );
523 addWidget( createField( this, "nb1D" ), i1D, iTotal );
524 addWidget( createField( this, "nbLinear1D" ), i1D, iLinear );
525 addWidget( createField( this, "nbQuadratic1D" ), i1D, iQuadratic );
527 addWidget( createSeparator( this ), i1DEnd, iTotal, 4 );
528 // - 2D elements info
530 addWidget( createLabel( tr( "2D_LAB" ), this, Bold | Italic ), i2D, iLabel );
531 addWidget( createField( this, "nb2D" ), i2D, iTotal );
532 addWidget( createField( this, "nbLinear2D" ), i2D, iLinear );
533 addWidget( createField( this, "nbQuadratic2D" ), i2D, iQuadratic );
534 addWidget( createField( this, "nbBiQuadratic2D" ), i2D, iBiQuadratic );
536 addWidget( createLabel( tr( "TRIANGLES_LAB" ), this, Italic ), i2DTriangles, iLabel );
537 addWidget( createField( this, Italic, "nbTriangle" ), i2DTriangles, iTotal );
538 addWidget( createField( this, Italic, "nbLinearTriangle" ), i2DTriangles, iLinear );
539 addWidget( createField( this, Italic, "nbQuadraticTriangle" ), i2DTriangles, iQuadratic );
540 addWidget( createField( this, Italic, "nbBiQuadraticTriangle" ), i2DTriangles, iBiQuadratic );
542 addWidget( createLabel( tr( "QUADRANGLES_LAB" ), this, Italic ), i2DQuadrangles, iLabel );
543 addWidget( createField( this, Italic, "nbQuadrangle" ), i2DQuadrangles, iTotal );
544 addWidget( createField( this, Italic, "nbLinearQuadrangle" ), i2DQuadrangles, iLinear );
545 addWidget( createField( this, Italic, "nbQuadraticQuadrangle" ), i2DQuadrangles, iQuadratic );
546 addWidget( createField( this, Italic, "nbBiQuadraticQuadrangle" ), i2DQuadrangles, iBiQuadratic );
548 addWidget( createLabel( tr( "POLYGONS_LAB" ), this, Italic ), i2DPolygons, iLabel );
549 addWidget( createField( this, Italic, "nbPolygon" ), i2DPolygons, iTotal );
550 addWidget( createField( this, Italic, "nbLinearPolygon" ), i2DPolygons, iLinear );
551 addWidget( createField( this, Italic, "nbQuadraticPolygon" ), i2DPolygons, iQuadratic );
553 addWidget( createSeparator( this ), i2DEnd, iTotal, 4 );
554 // - 3D elements info
556 addWidget( createLabel( tr( "3D_LAB" ), this, Bold | Italic ), i3D, iLabel );
557 addWidget( createField( this, "nb3D" ), i3D, iTotal );
558 addWidget( createField( this, "nbLinear3D" ), i3D, iLinear );
559 addWidget( createField( this, "nbQuadratic3D" ), i3D, iQuadratic );
560 addWidget( createField( this, "nbBiQuadratic3D" ), i3D, iBiQuadratic );
562 addWidget( createLabel( tr( "TETRAHEDRONS_LAB" ), this, Italic ), i3DTetrahedrons, iLabel );
563 addWidget( createField( this, Italic, "nbTetrahedron" ), i3DTetrahedrons, iTotal );
564 addWidget( createField( this, Italic, "nbLinearTetrahedron" ), i3DTetrahedrons, iLinear );
565 addWidget( createField( this, Italic, "nbQudraticTetrahedron" ), i3DTetrahedrons, iQuadratic );
567 addWidget( createLabel( tr( "HEXAHEDONRS_LAB" ), this, Italic ), i3DHexahedrons, iLabel );
568 addWidget( createField( this, Italic, "nbHexahedron" ), i3DHexahedrons, iTotal );
569 addWidget( createField( this, Italic, "nbLinearHexahedron" ), i3DHexahedrons, iLinear );
570 addWidget( createField( this, Italic, "nbQuadraticHexahedron" ), i3DHexahedrons, iQuadratic );
571 addWidget( createField( this, Italic, "nbBiQuadraticHexahedron" ), i3DHexahedrons, iBiQuadratic );
573 addWidget( createLabel( tr( "PYRAMIDS_LAB" ), this, Italic ), i3DPyramids, iLabel );
574 addWidget( createField( this, Italic, "nbPyramid" ), i3DPyramids, iTotal );
575 addWidget( createField( this, Italic, "nbLinearPyramid" ), i3DPyramids, iLinear );
576 addWidget( createField( this, Italic, "nbQuadraticPyramid" ), i3DPyramids, iQuadratic );
578 addWidget( createLabel( tr( "PRISMS_LAB" ), this, Italic ), i3DPrisms, iLabel );
579 addWidget( createField( this, Italic, "nbPrism" ), i3DPrisms, iTotal );
580 addWidget( createField( this, Italic, "nbLinearPrism" ), i3DPrisms, iLinear );
581 addWidget( createField( this, Italic, "nbQuadraticPrism" ), i3DPrisms, iQuadratic );
582 addWidget( createField( this, Italic, "nbBiQuadraticPrism" ), i3DPrisms, iBiQuadratic );
583 // --+ hexagonal prisms
584 addWidget( createLabel( tr( "HEX_PRISMS_LAB" ), this, Italic ), i3DHexaPrisms, iLabel );
585 addWidget( createField( this, Italic, "nbHexagonalPrism" ), i3DHexaPrisms, iTotal );
587 addWidget( createLabel( tr( "POLYHEDRONS_LAB" ), this, Italic ), i3DPolyhedrons, iLabel );
588 addWidget( createField( this, Italic, "nbPolyhedron" ), i3DPolyhedrons, iTotal );
591 QPushButton* loadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
592 loadBtn->setAutoDefault( true );
593 connect( loadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
594 addWidget( loadBtn, iEnd, iSingle, 4 );
596 // additional layout set-up
597 l->setColumnStretch( iLabel, 0 );
598 l->setColumnStretch( iTotal, 5 );
599 l->setColumnStretch( iLinear, 5 );
600 l->setColumnStretch( iQuadratic, 5 );
601 l->setColumnStretch( iBiQuadratic, 5 );
602 l->setRowStretch( iElementsEnd, 5 );
604 // set initial values
611 SMESHGUI_BaseInfo::~SMESHGUI_BaseInfo()
616 \brief Show information on given object.
617 \param proxy Object to show information on (mesh, sub-mesh, group, ID source).
619 void SMESHGUI_BaseInfo::showInfo( const SMESHGUI_SelectionProxy& proxy )
624 // then fill panel with data if object is not null
629 SMESHGUI_MeshInfo info = proxy.meshInfo();
633 widget( iName, iSingle )->setProperty( "text", proxy.name() );
636 SMESHGUI_SelectionProxy::Type type = proxy.type();
637 if ( type == SMESHGUI_SelectionProxy::Mesh )
639 typeName = tr( "OBJECT_MESH" );
641 else if ( type == SMESHGUI_SelectionProxy::Submesh )
643 typeName = tr( "OBJECT_SUBMESH" );
645 else if ( type >= SMESHGUI_SelectionProxy::Group )
647 switch( proxy.elementType() )
649 case SMESH::NODE: typeName = tr( "OBJECT_GROUP_NODES" ); break;
650 case SMESH::EDGE: typeName = tr( "OBJECT_GROUP_EDGES" ); break;
651 case SMESH::FACE: typeName = tr( "OBJECT_GROUP_FACES" ); break;
652 case SMESH::VOLUME: typeName = tr( "OBJECT_GROUP_VOLUMES" ); break;
653 case SMESH::ELEM0D: typeName = tr( "OBJECT_GROUP_0DELEMS" ); break;
654 case SMESH::BALL: typeName = tr( "OBJECT_GROUP_BALLS" ); break;
655 default: typeName = tr( "OBJECT_GROUP" ); break;
658 if ( type == SMESHGUI_SelectionProxy::GroupStd )
659 subType = tr( "OBJECT_GROUP_STANDALONE" );
660 else if ( type == SMESHGUI_SelectionProxy::GroupGeom )
661 subType = tr( "OBJECT_GROUP_GEOM" );
662 else if ( type == SMESHGUI_SelectionProxy::GroupFilter )
663 subType = tr( "OBJECT_GROUP_FILTER" );
664 if ( !subType.isEmpty() )
665 typeName = QString( "%1 %2" ).arg( typeName, subType );
667 widget( iObject, iSingle )->setProperty( "text", typeName );
670 uint nbNodes = info[SMDSEntity_Node];
671 widget( iNodes, iTotal )->setProperty( "value", nbNodes );
674 // - 0D elements info
675 uint nb0d = info[SMDSEntity_0D];
676 widget( i0D, iTotal )->setProperty( "value", nb0d );
678 uint nbBalls = info[SMDSEntity_Ball];
679 widget( iBalls, iTotal )->setProperty( "value", nbBalls );
680 // - 1D elements info
681 uint nb1dLin = info[SMDSEntity_Edge];
682 uint nb1dQua = info[SMDSEntity_Quad_Edge];
683 uint nb1d = nb1dLin + nb1dQua;
684 widget( i1D, iLinear )->setProperty( "value", nb1dLin );
685 widget( i1D, iQuadratic )->setProperty( "value", nb1dQua );
686 widget( i1D, iTotal )->setProperty( "value", nb1d );
687 // - 2D elements info
689 uint nbTriLin = info[SMDSEntity_Triangle];
690 uint nbTriQua = info[SMDSEntity_Quad_Triangle];
691 uint nbTriBiq = info[SMDSEntity_BiQuad_Triangle];
692 uint nbTri = nbTriLin + nbTriQua + nbTriBiq;
693 widget( i2DTriangles, iLinear )->setProperty( "value", nbTriLin );
694 widget( i2DTriangles, iQuadratic )->setProperty( "value", nbTriQua );
695 widget( i2DTriangles, iBiQuadratic )->setProperty( "value", nbTriBiq );
696 widget( i2DTriangles, iTotal )->setProperty( "value", nbTri );
698 uint nbQuadLin = info[SMDSEntity_Quadrangle];
699 uint nbQuadQua = info[SMDSEntity_Quad_Quadrangle];
700 uint nbQuadBiq = info[SMDSEntity_BiQuad_Quadrangle];
701 uint nbQuad = nbQuadLin + nbQuadQua + nbQuadBiq;
702 widget( i2DQuadrangles, iLinear )->setProperty( "value", nbQuadLin );
703 widget( i2DQuadrangles, iQuadratic )->setProperty( "value", nbQuadQua );
704 widget( i2DQuadrangles, iBiQuadratic )->setProperty( "value", nbQuadBiq );
705 widget( i2DQuadrangles, iTotal )->setProperty( "value", nbQuad );
707 uint nbPolyLin = info[SMDSEntity_Polygon];
708 uint nbPolyQua = info[SMDSEntity_Quad_Polygon];
709 uint nbPoly = nbPolyLin + nbPolyQua;
710 widget( i2DPolygons, iLinear )->setProperty( "value", nbPolyLin );
711 widget( i2DPolygons, iQuadratic )->setProperty( "value", nbPolyQua );
712 widget( i2DPolygons, iTotal )->setProperty( "value", nbPoly );
714 uint nb2dLin = nbTriLin + nbQuadLin + nbPolyLin;
715 uint nb2dQua = nbTriQua + nbQuadQua + nbPolyQua;
716 uint nb2dBiq = nbTriBiq + nbQuadBiq;
717 uint nb2d = nb2dLin + nb2dQua + nb2dBiq;
718 widget( i2D, iLinear )->setProperty( "value", nb2dLin );
719 widget( i2D, iQuadratic )->setProperty( "value", nb2dQua );
720 widget( i2D, iBiQuadratic )->setProperty( "value", nb2dBiq );
721 widget( i2D, iTotal )->setProperty( "value", nb2d );
722 // - 3D elements info
724 uint nbTetraLin = info[SMDSEntity_Tetra];
725 uint nbTetraQua = info[SMDSEntity_Quad_Tetra];
726 uint nbTetra = nbTetraLin + nbTetraQua;
727 widget( i3DTetrahedrons, iLinear )->setProperty( "value", nbTetraLin );
728 widget( i3DTetrahedrons, iQuadratic )->setProperty( "value", nbTetraQua );
729 widget( i3DTetrahedrons, iTotal )->setProperty( "value", nbTetra );
731 uint nbHexaLin = info[SMDSEntity_Hexa];
732 uint nbHexaQua = info[SMDSEntity_Quad_Hexa];
733 uint nbHexaBiq = info[SMDSEntity_TriQuad_Hexa];
734 uint nbHexa = nbHexaLin + nbHexaQua + nbHexaBiq;
735 widget( i3DHexahedrons, iLinear )->setProperty( "value", nbHexaLin );
736 widget( i3DHexahedrons, iQuadratic )->setProperty( "value", nbHexaQua );
737 widget( i3DHexahedrons, iBiQuadratic )->setProperty( "value", nbHexaBiq );
738 widget( i3DHexahedrons, iTotal )->setProperty( "value", nbHexa );
740 uint nbPyraLin = info[SMDSEntity_Pyramid];
741 uint nbPyraQua = info[SMDSEntity_Quad_Pyramid];
742 uint nbPyra = nbPyraLin + nbPyraQua;
743 widget( i3DPyramids, iLinear )->setProperty( "value", nbPyraLin );
744 widget( i3DPyramids, iQuadratic )->setProperty( "value", nbPyraQua );
745 widget( i3DPyramids, iTotal )->setProperty( "value", nbPyra );
747 uint nbPentaLin = info[SMDSEntity_Penta];
748 uint nbPentaQua = info[SMDSEntity_Quad_Penta];
749 uint nbPentaBiq = info[SMDSEntity_BiQuad_Penta];
750 uint nbPenta = nbPentaLin + nbPentaQua + nbPentaBiq;
751 widget( i3DPrisms, iLinear )->setProperty( "value", nbPentaLin );
752 widget( i3DPrisms, iQuadratic )->setProperty( "value", nbPentaQua );
753 widget( i3DPrisms, iBiQuadratic )->setProperty( "value", nbPentaBiq );
754 widget( i3DPrisms, iTotal )->setProperty( "value", nbPenta );
755 // --+ hexagonal prisms
756 uint nbHexaPri = info[SMDSEntity_Hexagonal_Prism];
757 widget( i3DHexaPrisms, iTotal )->setProperty( "value", nbHexaPri );
759 uint nbPolyhedra = info[SMDSEntity_Polyhedra];
760 widget( i3DPolyhedrons, iTotal )->setProperty( "value", nbPolyhedra );
762 uint nb3dLin = nbTetraLin + nbHexaLin + nbPyraLin + nbPentaLin + nbHexaPri + nbPolyhedra;
763 uint nb3dQua = nbTetraQua + nbHexaQua + nbPyraQua + nbPentaQua;
764 uint nb3dBiq = nbHexaBiq + nbPentaBiq;
765 uint nb3d = nb3dLin + nb3dQua + nb3dBiq;
766 widget( i3D, iLinear )->setProperty( "value", nb3dLin );
767 widget( i3D, iQuadratic )->setProperty( "value", nb3dQua );
768 widget( i3D, iBiQuadratic )->setProperty( "value", nb3dBiq );
769 widget( i3D, iTotal )->setProperty( "value", nb3d );
771 uint nbElemLin = nb1dLin + nb2dLin + nb3dLin;
772 uint nbElemQua = nb1dQua + nb2dQua + nb3dQua;
773 uint nbElemBiq = nb2dBiq + nb3dBiq;
774 uint nbElem = nb0d + nbBalls + nb1d + nb2d + nb3d;
775 widget( iElementsTotal, iLinear )->setProperty( "value", nbElemLin );
776 widget( iElementsTotal, iQuadratic )->setProperty( "value", nbElemQua );
777 widget( iElementsTotal, iBiQuadratic )->setProperty( "value", nbElemBiq );
778 widget( iElementsTotal, iTotal )->setProperty( "value", nbElem );
780 // show 'Load' button if data was not loaded yet
781 widget( iEnd, iSingle )->setVisible( !proxy.isValid() );
783 // until data is loaded from study file, type of elements in a sub-mesh or group
784 // can be undefined in some cases
785 if ( !proxy.isValid() )
787 // two cases are possible:
788 // 1. type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
789 // 2. there is no info at all (for a group on geom or on filter)
790 if ( info.count( SMDSEntity_Node, SMDSEntity_Last ) > 0 ) // believe it is a sub-mesh
792 if ( nb2dLin + nb2dQua + nb2dBiq > 0 )
794 // we know nothing about triangles, quadranges and polygons
795 for ( int i = i2DTriangles; i < i2DEnd; i++ )
797 for ( int j = iTotal; j < iNbColumns; j++ )
799 if ( widget( i, j ) )
800 widget( i, j )->setProperty( "text", "?" );
803 // we don't know if elements are linear, quadratic or bi-quadratic
804 for ( int j = iLinear; j < iNbColumns; j++ )
806 if ( widget( i2D, j ) )
807 widget( i2D, j )->setProperty( "text", "?" );
808 if ( widget( iElementsTotal, j ) )
809 widget( iElementsTotal, j )->setProperty( "text", "?" );
812 else if ( nb3dLin + nb3dQua + nb3dBiq > 0 )
814 // we know nothing about tetras, hexas, etc.
815 for ( int i = i3DTetrahedrons; i < i3DEnd; i++ )
817 for ( int j = iTotal; j < iNbColumns; j++ )
819 if ( widget( i, j ) )
820 widget( i, j )->setProperty( "text", "?" );
823 // we don't know if elements are linear, quadratic or bi-quadratic
824 for ( int j = iLinear; j < iNbColumns; j++ )
826 if ( widget( i3D, j ) )
827 widget( i3D, j )->setProperty( "text", "?" );
828 if ( widget( iElementsTotal, j ) )
829 widget( iElementsTotal, j )->setProperty( "text", "?" );
835 // we know nothing about nodes :(
836 widget( iNodes, iTotal )->setProperty( "text", "?" );
837 // we know nothing about elements :(
838 for ( int i = iElementsTotal; i < iElementsEnd; i++ )
840 for ( int j = iTotal; j < iNbColumns; j++ )
842 if ( widget( i, j ) )
843 widget( i, j )->setProperty( "text", "?" );
852 \brief Update information in panel.
854 void SMESHGUI_BaseInfo::updateInfo()
860 \brief Load mesh from a study file.
862 void SMESHGUI_BaseInfo::loadMesh()
864 SUIT_OverrideCursor wc;
873 \brief Reset panel (clear all data).
875 void SMESHGUI_BaseInfo::clear()
878 widget( iName, iSingle )->setProperty( "text", QString() );
880 widget( iObject, iSingle )->setProperty( "text", QString() );
882 widget( iNodes, iTotal )->setProperty( "value", 0 );
884 for ( int i = iElementsTotal; i < iElementsEnd; i++ )
886 for ( int j = iTotal; j < iNbColumns; j++ )
888 if ( widget( i, j ) )
889 widget( i, j )->setProperty( "value", 0 );
895 \brief Register widget in a grid.
896 \param w Widget being added.
897 \param row Row index in a grid.
898 \param column Column index in a grid.
899 \param colspan Number of columns to span in a grid. Defaults to 1.
900 \return Just added widget.
902 QWidget* SMESHGUI_BaseInfo::addWidget( QWidget* w, int row, int column, int colspan )
904 if ( !myWidgets.contains( row ) )
905 myWidgets[row] = wlist();
906 myWidgets[row][column] = w;
907 dynamic_cast<QGridLayout*>( layout() )->addWidget( w, row, column, 1, colspan );
912 \brief Get registered widget.
913 \param row Row index in a grid.
914 \param column Column index in a grid.
915 \return Widget stored in a given grid cell (0 if there's no widget).
917 QWidget* SMESHGUI_BaseInfo::widget( int row, int column ) const
919 return myWidgets.contains( row ) && myWidgets[row].contains( column ) ? myWidgets[row][column] : 0;
923 \brief Get text value from registered widget.
924 \param row Row index in a grid.
925 \param column Column index in a grid.
926 \return Value string (empty string if no label in given cell).
928 QString SMESHGUI_BaseInfo::value( int row, int column ) const
930 return widgetValue( widget( row, column ) );
934 \brief Show/hide group(s) of widgets.
935 \param startRow Starting grid row.
936 \param lastRow Last grid row.
937 \param on Visibility flag.
939 void SMESHGUI_BaseInfo::setFieldsVisible( int startRow, int lastRow, bool on )
941 startRow = qMax( 0, startRow );
942 lastRow = qMin( lastRow, (int)iEnd );
943 for ( int i = startRow; i <= lastRow; i++ )
945 wlist widgets = myWidgets[i];
946 foreach ( QWidget* w, widgets )
952 \brief Write information from panel to ouput stream.
953 \param out Text stream output.
955 void SMESHGUI_BaseInfo::saveInfo( QTextStream& out )
958 QString title = tr( "BASE_INFO" );
959 out << ruler( title.size() ) << endl;
960 out << title << endl;
961 out << ruler( title.size() ) << endl;
966 out << tr( "NAME_LAB" ) << spacing() << value( iName, iSingle ) << endl;
968 out << tr( "OBJECT_LAB" ) << spacing() << value( iObject, iSingle ) << endl;
973 out << tr( "NODES_LAB" ) << spacing() << value( iNodes, iTotal ) << endl;
978 QString lin = tr( "LINEAR_LAB" ) + ":" + spacing();
979 QString qua = tr( "QUADRATIC_LAB" ) + ":" + spacing();
980 QString biq = tr( "BI_QUADRATIC_LAB" ) + ":" + spacing();
982 out << tr( "ELEMENTS_LAB" ) << spacing() << value( iElementsTotal, iTotal ) << endl;
983 out << indent(1) << lin << value( iElementsTotal, iLinear ) << endl;
984 out << indent(1) << qua << value( iElementsTotal, iQuadratic ) << endl;
985 out << indent(1) << biq << value( iElementsTotal, iBiQuadratic ) << endl;
988 // - 0D elements info
989 out << indent(1) << tr( "0D_LAB" ) << spacing() << value( i0D, iTotal ) << endl;
993 out << indent(1) << tr( "BALL_LAB" ) << spacing() << value( iBalls, iTotal ) << endl;
996 // - 1D elements info
997 out << indent(1) << tr( "1D_LAB" ) << spacing() << value( i1D, iTotal ) << endl;
998 out << indent(2) << lin << value( i1D, iLinear ) << endl;
999 out << indent(2) << qua << value( i1D, iQuadratic ) << endl;
1000 // - --- (separator)
1002 // - 2D elements info
1004 out << indent(1) << tr( "2D_LAB" ) << spacing() << value( i2D, iTotal ) << endl;
1005 out << indent(2) << lin << value( i2D, iLinear ) << endl;
1006 out << indent(2) << qua << value( i2D, iQuadratic ) << endl;
1007 out << indent(2) << biq << value( i2D, iBiQuadratic ) << endl;
1008 // - --- (separator)
1011 out << indent(2) << tr( "TRIANGLES_LAB" ) << spacing() << value( i2DTriangles, iTotal ) << endl;
1012 out << indent(3) << lin << value( i2DTriangles, iLinear ) << endl;
1013 out << indent(3) << qua << value( i2DTriangles, iQuadratic ) << endl;
1014 out << indent(3) << biq << value( i2DTriangles, iBiQuadratic ) << endl;
1016 out << indent(2) << tr( "QUADRANGLES_LAB" ) << spacing() << value( i2DQuadrangles, iTotal ) << endl;
1017 out << indent(3) << lin << value( i2DQuadrangles, iLinear ) << endl;
1018 out << indent(3) << qua << value( i2DQuadrangles, iQuadratic ) << endl;
1019 out << indent(3) << biq << value( i2DQuadrangles, iBiQuadratic ) << endl;
1021 out << indent(2) << tr( "POLYGONS_LAB" ) << spacing() << value( i2DPolygons, iTotal ) << endl;
1022 out << indent(3) << lin << value( i2DPolygons, iLinear ) << endl;
1023 out << indent(3) << qua << value( i2DPolygons, iQuadratic ) << endl;
1024 // - --- (separator)
1026 // - 3D elements info
1028 out << indent(1) << tr( "3D_LAB" ) << spacing() << value( i3D, iTotal ) << endl;
1029 out << indent(2) << lin << value( i3D, iLinear ) << endl;
1030 out << indent(2) << qua << value( i3D, iQuadratic ) << endl;
1031 out << indent(2) << biq << value( i3D, iBiQuadratic ) << endl;
1032 // - --- (separator)
1035 out << indent(2) << tr( "TETRAHEDRONS_LAB" ) << spacing() << value( i3DTetrahedrons, iTotal ) << endl;
1036 out << indent(3) << lin << value( i3DTetrahedrons, iLinear ) << endl;
1037 out << indent(3) << qua << value( i3DTetrahedrons, iQuadratic ) << endl;
1039 out << indent(2) << tr( "HEXAHEDONRS_LAB" ) << spacing() << value( i3DHexahedrons, iTotal ) << endl;
1040 out << indent(3) << lin << value( i3DHexahedrons, iLinear ) << endl;
1041 out << indent(3) << qua << value( i3DHexahedrons, iQuadratic ) << endl;
1042 out << indent(3) << biq << value( i3DHexahedrons, iBiQuadratic ) << endl;
1044 out << indent(2) << tr( "PYRAMIDS_LAB" ) << spacing() << value( i3DPyramids, iTotal ) << endl;
1045 out << indent(3) << lin << value( i3DPyramids, iLinear ) << endl;
1046 out << indent(3) << qua << value( i3DPyramids, iQuadratic ) << endl;
1048 out << indent(2) << tr( "PRISMS_LAB" ) << spacing() << value( i3DPrisms, iTotal ) << endl;
1049 out << indent(3) << lin << value( i3DPrisms, iLinear ) << endl;
1050 out << indent(3) << qua << value( i3DPrisms, iQuadratic ) << endl;
1051 out << indent(3) << biq << value( i3DPrisms, iBiQuadratic ) << endl;
1052 // --+ hexagonal prisms
1053 out << indent(2) << tr( "HEX_PRISMS_LAB" ) << spacing() << value( i3DHexaPrisms, iTotal ) << endl;
1055 out << indent(2) << tr( "POLYHEDRONS_LAB" ) << spacing() << value( i3DPolyhedrons, iTotal ) << endl;
1056 // - --- (separator)
1060 ////////////////////////////////////////////////////////////////////////////////
1061 /// \class SMESHGUI_ElemInfo
1062 /// \brief Base class for the mesh element information widget.
1063 ////////////////////////////////////////////////////////////////////////////////
1067 \param parent Parent widget. Defaults to 0.
1069 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ): SMESHGUI_Info( parent ), myWhat( ShowNone )
1071 myFrame = new QWidget( this );
1072 myExtra = new ExtraWidget( this );
1074 QVBoxLayout* vbl = new QVBoxLayout( this );
1075 vbl->setMargin( 0 );
1076 vbl->setSpacing( SPACING );
1077 vbl->addWidget( myFrame );
1078 vbl->addWidget( myExtra );
1080 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
1081 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
1089 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
1094 \brief Show information on given node / element.
1095 \param proxy Object to compute information on (mesh, sub-mesh, group, ID source).
1096 \param id Mesh node / element ID.
1097 \param isElement If \c true, show element info; otherwise show node info.
1099 void SMESHGUI_ElemInfo::showInfo( const SMESHGUI_SelectionProxy& proxy, uint id, bool isElement )
1103 showInfo( proxy, ids, isElement );
1107 \brief Show information on given nodes / elements.
1108 \param proxy Object to compute information on (mesh, sub-mesh, group, ID source).
1109 \param ids Mesh nodes / elements IDs.
1110 \param isElement If \c true, show element info; otherwise show node info.
1112 void SMESHGUI_ElemInfo::showInfo( const SMESHGUI_SelectionProxy& proxy, QSet<uint> ids, bool isElement )
1120 QList<uint> newIds = ids.toList();
1122 int what = isElement ? ShowElements : ShowNodes;
1124 if ( myProxy == proxy && myIDs == newIds && myWhat == what )
1128 myProxy.refresh(); // try to re-initialize actor
1137 information( myIDs.mid( myIndex*blockSize(), blockSize() ));
1141 \brief Show information on given group.
1142 \param proxy Object to compute information on (group).
1144 void SMESHGUI_ElemInfo::showInfo( const SMESHGUI_SelectionProxy& proxy )
1146 if ( !proxy || proxy.elementType() == SMESH::ALL ) // null proxy or not a group
1152 showInfo( proxy, proxy.ids(), proxy.elementType() != SMESH::NODE );
1156 \brief Clear mesh element information widget
1158 void SMESHGUI_ElemInfo::clear()
1167 \brief Get central area widget
1168 \return central widget
1170 QWidget* SMESHGUI_ElemInfo::frame() const
1176 \brief Get current info mode.
1177 \return Current panel mode.
1179 int SMESHGUI_ElemInfo::what() const
1185 \brief Get current mesh proxy object information is shown on.
1186 \return Current proxy.
1188 SMESHGUI_SelectionProxy SMESHGUI_ElemInfo::proxy() const
1194 \fn void SMESHGUI_ElemInfo::information( const QList<uint>& ids )
1195 \brief Show information on the specified nodes / elements
1197 This function is to be redefined in sub-classes.
1199 \param ids nodes / elements identifiers information is to be shown on
1203 \brief Internal clean-up (reset widget)
1205 void SMESHGUI_ElemInfo::clearInternal()
1210 \brief Get node connectivity
1211 \param node mesh node
1212 \return node connectivity map
1214 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1218 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1219 while ( it && it->more() ) {
1220 const SMDS_MeshElement* ne = it->next();
1221 elmap[ ne->GetType() ] << ne->GetID();
1228 \brief Format connectivity data to string representation
1229 \param connectivity connetivity map
1230 \param type element type
1231 \return string representation of the connectivity
1233 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1236 if ( connectivity.contains( type )) {
1237 QList<int> elements = connectivity[ type ];
1239 foreach( int id, elements )
1240 str << QString::number( id );
1242 return str.join( " " );
1246 \brief Calculate gravity center of the mesh element
1247 \param element mesh element
1249 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1253 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1254 while ( nodeIt->more() ) {
1255 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1256 xyz.add( node->X(), node->Y(), node->Z() );
1258 xyz.divide( element->NbNodes() );
1264 \brief Calculate gravity center of the mesh element
1265 \param element mesh element
1267 gp_XYZ SMESHGUI_ElemInfo::getGravityCenter( const SMDS_MeshElement* element )
1269 return gravityCenter( element );
1273 \brief Calculate normal vector to the mesh face
1274 \param element mesh face
1276 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1278 gp_XYZ n = SMESH::getNormale( SMDS_Mesh::DownCast<SMDS_MeshFace>( element ));
1279 return XYZ(n.X(), n.Y(), n.Z());
1283 \brief This slot is called from "Show Previous" button click.
1284 Shows information on the previous group of the items.
1286 void SMESHGUI_ElemInfo::showPrevious()
1288 myIndex = qMax( 0, myIndex-1 );
1290 information( myIDs.mid( myIndex*blockSize(), blockSize() ));
1294 \brief This slot is called from "Show Next" button click.
1295 Shows information on the next group of the items.
1297 void SMESHGUI_ElemInfo::showNext()
1299 myIndex = qMin( myIndex+1, myIDs.count() / blockSize() );
1301 information( myIDs.mid( myIndex*blockSize(), blockSize() ));
1305 \brief Update widgets state
1307 void SMESHGUI_ElemInfo::updateControls()
1309 myExtra->updateControls( myIDs.count(), myIndex );
1313 \class SMESHGUI_SimpleElemInfo
1314 \brief Represents mesh element information in the simple text area.
1319 \param parent parent widget
1321 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1322 : SMESHGUI_ElemInfo( parent )
1324 myInfo = new QTextBrowser( frame() );
1325 QVBoxLayout* l = new QVBoxLayout( frame() );
1327 l->addWidget( myInfo );
1331 \brief Show mesh element information
1332 \param ids mesh nodes / elements identifiers
1334 void SMESHGUI_SimpleElemInfo::information( const QList<uint>& ids )
1338 SMESH_Actor* actor = proxy().actor();
1341 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1342 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1343 int cprecision = -1;
1344 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1345 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1346 foreach ( uint id, ids ) {
1347 if ( what() == ShowNodes ) {
1351 const SMDS_MeshNode* node = actor->GetObject()->GetMesh()->FindNode( id );
1352 if ( !node ) return;
1355 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id ));
1357 myInfo->append( "" );
1359 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1360 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1361 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1362 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1364 myInfo->append( "" );
1366 Connectivity connectivity = nodeConnectivity( node );
1367 if ( !connectivity.isEmpty() ) {
1368 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1369 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1370 if ( !con.isEmpty() )
1371 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1372 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1373 if ( !con.isEmpty() )
1374 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1375 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1376 if ( !con.isEmpty() )
1377 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con ));
1378 con = formatConnectivity( connectivity, SMDSAbs_Face );
1379 if ( !con.isEmpty() )
1380 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1381 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1382 if ( !con.isEmpty() )
1383 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1386 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1389 SMESH::SMESH_Mesh_ptr aMeshPtr = actor->GetObject()->GetMeshServer();
1390 if ( !CORBA::is_nil( aMeshPtr )) {
1391 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1392 int shapeID = pos->shapeID;
1393 if ( shapeID > 0 ) {
1395 double u = 0, v = 0;
1396 switch ( pos->shapeType ) {
1398 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1399 if ( pos->params.length() == 1 )
1403 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1404 if ( pos->params.length() == 2 ) {
1410 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1413 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1417 myInfo->append( "" );
1418 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) );
1419 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ));
1420 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1421 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )).
1422 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1423 if ( pos->shapeType == GEOM::FACE ) {
1424 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )).
1425 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1430 // groups node belongs to
1431 SMESH::SMESH_Mesh_ptr aMesh = actor->GetObject()->GetMeshServer();
1432 if ( !CORBA::is_nil( aMesh )) {
1433 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1434 myInfo->append( "" ); // separator
1435 bool top_created = false;
1436 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1437 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1438 if ( CORBA::is_nil( aGrp )) continue;
1439 QString aName = (char*) (CORBA::String_var) aGrp->GetName();
1440 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1441 if ( !top_created ) {
1442 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1445 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1446 if ( grp_details ) {
1447 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1448 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1449 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1451 // type : group on geometry, standalone group, group on filter
1452 if ( !CORBA::is_nil( aStdGroup )) {
1453 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1454 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1456 else if ( !CORBA::is_nil( aGeomGroup )) {
1457 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1458 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1459 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1460 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1462 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1463 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1466 else if ( !CORBA::is_nil( aFltGroup )) {
1467 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1468 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1472 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1473 arg( QString::number( aGrp->Size() )) );
1476 SALOMEDS::Color color = aGrp->GetColor();
1477 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1478 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1484 else if ( what() == ShowElements ) {
1486 // show element info
1488 const SMDS_MeshElement* e = actor->GetObject()->GetMesh()->FindElement( id );
1489 SMESH::Controls::NumericalFunctorPtr afunctor;
1492 // Element ID && Type
1494 switch( e->GetType() ) {
1495 case SMDSAbs_0DElement:
1496 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1498 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1500 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1502 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1503 case SMDSAbs_Volume:
1504 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1508 if ( stype.isEmpty() ) return;
1509 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ));
1511 myInfo->append( "" );
1515 switch( e->GetEntityType() ) {
1516 case SMDSEntity_Triangle:
1517 case SMDSEntity_Quad_Triangle:
1518 case SMDSEntity_BiQuad_Triangle:
1519 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1520 case SMDSEntity_Quadrangle:
1521 case SMDSEntity_Quad_Quadrangle:
1522 case SMDSEntity_BiQuad_Quadrangle:
1523 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1524 case SMDSEntity_Polygon:
1525 case SMDSEntity_Quad_Polygon:
1526 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1527 case SMDSEntity_Tetra:
1528 case SMDSEntity_Quad_Tetra:
1529 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1530 case SMDSEntity_Pyramid:
1531 case SMDSEntity_Quad_Pyramid:
1532 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1533 case SMDSEntity_Hexa:
1534 case SMDSEntity_Quad_Hexa:
1535 case SMDSEntity_TriQuad_Hexa:
1536 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1537 case SMDSEntity_Penta:
1538 case SMDSEntity_Quad_Penta:
1539 case SMDSEntity_BiQuad_Penta:
1540 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1541 case SMDSEntity_Hexagonal_Prism:
1542 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1543 case SMDSEntity_Polyhedra:
1544 case SMDSEntity_Quad_Polyhedra:
1545 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1549 if ( !gtype.isEmpty() )
1550 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype ));
1552 // Quadratic flag (any element except 0D)
1553 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1554 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) );
1556 if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast<SMDS_BallElement>( e )) {
1558 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() ));
1561 myInfo->append( "" );
1564 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1565 for ( int idx = 1; nodeIt->more(); idx++ ) {
1566 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1567 // node number and ID
1568 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ));
1570 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1571 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1572 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1573 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1574 // node connectivity
1575 Connectivity connectivity = nodeConnectivity( node );
1576 if ( !connectivity.isEmpty() ) {
1577 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1578 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1579 if ( !con.isEmpty() )
1580 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1581 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1582 if ( !con.isEmpty() )
1583 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1584 con = formatConnectivity( connectivity, SMDSAbs_Face );
1585 if ( !con.isEmpty() )
1586 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1587 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1588 if ( !con.isEmpty() )
1589 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1592 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1596 myInfo->append( "" );
1599 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) );
1601 if ( e->GetType() == SMDSAbs_Edge ) {
1602 afunctor.reset( new SMESH::Controls::Length() );
1603 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1604 afunctor->SetPrecision( cprecision );
1605 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) );
1607 if( e->GetType() == SMDSAbs_Face ) {
1609 afunctor.reset( new SMESH::Controls::Area() );
1610 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1611 afunctor->SetPrecision( cprecision );
1612 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1614 afunctor.reset( new SMESH::Controls::Taper() );
1615 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1616 afunctor->SetPrecision( cprecision );
1617 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1619 afunctor.reset( new SMESH::Controls::AspectRatio() );
1620 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1621 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1623 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1624 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1625 afunctor->SetPrecision( cprecision );
1626 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1628 afunctor.reset( new SMESH::Controls::Warping() );
1629 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1630 afunctor->SetPrecision( cprecision );
1631 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1633 afunctor.reset( new SMESH::Controls::Skew() );
1634 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1635 afunctor->SetPrecision( cprecision );
1636 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1638 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1639 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1640 afunctor->SetPrecision( cprecision );
1641 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) );
1643 afunctor.reset( new SMESH::Controls::Length2D() );
1644 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1645 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MIN_ELEM_EDGE" )).arg( afunctor->GetValue( id )) );
1647 if( e->GetType() == SMDSAbs_Volume ) {
1649 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1650 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1651 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1653 afunctor.reset( new SMESH::Controls::Volume() );
1654 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1655 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1657 afunctor.reset( new SMESH::Controls::Volume() );
1658 afunctor->SetMesh( actor->GetObject()->GetMesh() );
1659 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) );
1662 myInfo->append( "" );
1665 XYZ gc = gravityCenter( e );
1666 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1669 if( e->GetType() == SMDSAbs_Face ) {
1670 XYZ gc = normal( e );
1671 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1675 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1676 SMESH::SMESH_Mesh_ptr aMesh = actor->GetObject()->GetMeshServer();
1677 if ( !CORBA::is_nil( aMesh )) {
1678 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1679 int shapeID = pos.shapeID;
1680 if ( shapeID > 0 ) {
1681 myInfo->append( "" ); // separator
1683 switch ( pos.shapeType ) {
1684 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1685 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1686 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1687 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1688 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1689 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1691 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID ));
1696 // Groups the element belongs to
1697 SMESH::SMESH_Mesh_ptr aMesh = actor->GetObject()->GetMeshServer();
1698 if ( !CORBA::is_nil( aMesh )) {
1699 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1700 myInfo->append( "" ); // separator
1701 bool top_created = false;
1702 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1703 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1704 if ( CORBA::is_nil( aGrp )) continue;
1705 QString aName = (char*) (CORBA::String_var) aGrp->GetName();
1706 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1707 if ( !top_created ) {
1708 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1711 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1712 if ( grp_details ) {
1713 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1714 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1715 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1717 // type : group on geometry, standalone group, group on filter
1718 if ( !CORBA::is_nil( aStdGroup )) {
1719 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1720 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1722 else if ( !CORBA::is_nil( aGeomGroup )) {
1723 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1724 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1725 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1726 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1728 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1729 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1732 else if ( !CORBA::is_nil( aFltGroup )) {
1733 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1734 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1737 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1738 arg( QString::number( aGrp->Size() )) );
1741 SALOMEDS::Color color = aGrp->GetColor();
1742 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1743 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1750 if ( ids.count() > 1 ) {
1751 myInfo->append( "" );
1752 myInfo->append( "------" );
1753 myInfo->append( "" );
1760 \brief Internal clean-up (reset widget)
1762 void SMESHGUI_SimpleElemInfo::clearInternal()
1767 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1769 out << ruler( 12 ) << endl;
1770 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << endl;
1771 out << ruler( 12 ) << endl;
1772 out << myInfo->toPlainText();
1778 \class SMESHGUI_TreeElemInfo::ItemDelegate
1779 \brief Item delegate for tree mesh info widget
1782 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1785 ItemDelegate( QObject* );
1786 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1793 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ): QItemDelegate( parent )
1798 \brief Create item editor widget
1801 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1803 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1804 if ( qobject_cast<QLineEdit*>( w )) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1809 \class SMESHGUI_TreeElemInfo
1810 \brief Represents mesh element information in the tree-like form.
1815 \param parent parent widget
1817 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1818 : SMESHGUI_ElemInfo( parent )
1820 myInfo = new QTreeWidget( frame() );
1821 myInfo->setColumnCount( 2 );
1822 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1823 myInfo->header()->setStretchLastSection( true );
1824 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1825 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1827 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1829 myInfo->setItemDelegate( new ItemDelegate( myInfo ));
1830 QVBoxLayout* l = new QVBoxLayout( frame() );
1832 l->addWidget( myInfo );
1833 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) );
1834 connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1835 connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1839 \brief Show mesh element information
1840 \param ids mesh nodes / elements identifiers
1842 void SMESHGUI_TreeElemInfo::information( const QList<uint>& ids )
1849 bool hasShapeToMesh = proxy().hasShapeToMesh();
1850 SMESH_Actor* actor = proxy().actor();
1853 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1854 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1855 int cprecision = -1;
1856 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1857 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1858 foreach ( uint id, ids ) {
1859 if ( what() == ShowNodes ) {
1863 const SMDS_MeshElement* e = actor->GetObject()->GetMesh()->FindNode( id );
1865 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1868 QTreeWidgetItem* nodeItem = createItem( 0, Bold | AllColumns );
1869 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ));
1870 nodeItem->setText( 1, QString( "#%1" ).arg( id ));
1872 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1873 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
1874 QTreeWidgetItem* xItem = createItem( coordItem );
1875 xItem->setText( 0, "X" );
1876 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1877 QTreeWidgetItem* yItem = createItem( coordItem );
1878 yItem->setText( 0, "Y" );
1879 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1880 QTreeWidgetItem* zItem = createItem( coordItem );
1881 zItem->setText( 0, "Z" );
1882 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1884 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1885 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1886 Connectivity connectivity = nodeConnectivity( node );
1887 if ( !connectivity.isEmpty() ) {
1888 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1889 if ( !con.isEmpty() ) {
1890 QTreeWidgetItem* i = createItem( conItem );
1891 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
1892 i->setText( 1, con );
1894 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1895 if ( !con.isEmpty() ) {
1896 QTreeWidgetItem* i = createItem( conItem );
1897 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
1898 i->setText( 1, con );
1899 i->setData( 1, TypeRole, NodeConnectivity );
1901 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1902 if ( !con.isEmpty() ) {
1903 QTreeWidgetItem* i = createItem( conItem );
1904 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
1905 i->setText( 1, con );
1906 i->setData( 1, TypeRole, NodeConnectivity );
1908 con = formatConnectivity( connectivity, SMDSAbs_Face );
1909 if ( !con.isEmpty() ) {
1910 QTreeWidgetItem* i = createItem( conItem );
1911 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
1912 i->setText( 1, con );
1913 i->setData( 1, TypeRole, NodeConnectivity );
1915 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1916 if ( !con.isEmpty() ) {
1917 QTreeWidgetItem* i = createItem( conItem );
1918 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
1919 i->setText( 1, con );
1920 i->setData( 1, TypeRole, NodeConnectivity );
1924 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ));
1927 SMESH::SMESH_Mesh_ptr aMeshPtr = actor->GetObject()->GetMeshServer();
1928 if ( !CORBA::is_nil( aMeshPtr )) {
1929 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1930 int shapeID = pos->shapeID;
1931 if ( shapeID > 0 ) {
1933 double u = 0, v = 0;
1934 switch ( pos->shapeType ) {
1936 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1937 if ( pos->params.length() == 1 )
1941 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1942 if ( pos->params.length() == 2 ) {
1948 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1951 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1954 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1955 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1956 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1957 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1958 QTreeWidgetItem* uItem = createItem( posItem );
1959 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1960 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1961 if ( pos->shapeType == GEOM::FACE ) {
1962 QTreeWidgetItem* vItem = createItem( posItem );
1963 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1964 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1969 // groups node belongs to
1970 SMESH::SMESH_Mesh_ptr aMesh = actor->GetObject()->GetMeshServer();
1971 if ( !CORBA::is_nil( aMesh )) {
1972 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1973 QTreeWidgetItem* groupsItem = 0;
1974 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1975 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1976 if ( CORBA::is_nil( aGrp )) continue;
1977 QString aName = (char*) (CORBA::String_var) aGrp->GetName();
1978 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1979 if ( !groupsItem ) {
1980 groupsItem = createItem( nodeItem, Bold );
1981 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
1983 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1984 it->setText( 0, aName.trimmed() );
1985 if ( grp_details ) {
1986 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1987 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1988 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1990 // type : group on geometry, standalone group, group on filter
1991 QTreeWidgetItem* typeItem = createItem( it );
1992 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
1993 if ( !CORBA::is_nil( aStdGroup )) {
1994 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
1996 else if ( !CORBA::is_nil( aGeomGroup )) {
1997 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
1998 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1999 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2001 QTreeWidgetItem* gobjItem = createItem( typeItem );
2002 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2003 gobjItem->setText( 1, sobj->GetName().c_str() );
2006 else if ( !CORBA::is_nil( aFltGroup )) {
2007 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2011 QTreeWidgetItem* sizeItem = createItem( it );
2012 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2013 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2016 SALOMEDS::Color color = aGrp->GetColor();
2017 QTreeWidgetItem* colorItem = createItem( it );
2018 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2019 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2025 if ( what() == ShowElements ) {
2027 // show element info
2029 const SMDS_MeshElement* e = actor->GetObject()->GetMesh()->FindElement( id );
2030 SMESH::Controls::NumericalFunctorPtr afunctor;
2033 // element ID && type
2035 switch( e->GetType() ) {
2036 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
2037 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
2038 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
2039 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
2040 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
2043 if ( stype.isEmpty() ) return;
2044 QTreeWidgetItem* elemItem = createItem( 0, Bold | AllColumns );
2045 elemItem->setText( 0, stype );
2046 elemItem->setText( 1, QString( "#%1" ).arg( id ));
2049 switch( e->GetEntityType() ) {
2050 case SMDSEntity_Triangle:
2051 case SMDSEntity_Quad_Triangle:
2052 case SMDSEntity_BiQuad_Triangle:
2053 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
2054 case SMDSEntity_Quadrangle:
2055 case SMDSEntity_Quad_Quadrangle:
2056 case SMDSEntity_BiQuad_Quadrangle:
2057 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
2058 case SMDSEntity_Polygon:
2059 case SMDSEntity_Quad_Polygon:
2060 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
2061 case SMDSEntity_Tetra:
2062 case SMDSEntity_Quad_Tetra:
2063 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
2064 case SMDSEntity_Pyramid:
2065 case SMDSEntity_Quad_Pyramid:
2066 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
2067 case SMDSEntity_Hexa:
2068 case SMDSEntity_Quad_Hexa:
2069 case SMDSEntity_TriQuad_Hexa:
2070 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
2071 case SMDSEntity_Penta:
2072 case SMDSEntity_Quad_Penta:
2073 case SMDSEntity_BiQuad_Penta:
2074 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
2075 case SMDSEntity_Hexagonal_Prism:
2076 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
2077 case SMDSEntity_Polyhedra:
2078 case SMDSEntity_Quad_Polyhedra:
2079 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
2083 if ( !gtype.isEmpty() ) {
2084 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
2085 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ));
2086 typeItem->setText( 1, gtype );
2088 // quadratic flag (for edges, faces and volumes)
2089 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2091 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
2092 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ));
2093 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ));
2095 if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast< SMDS_BallElement >( e )) {
2097 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
2098 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ));
2099 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
2102 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
2103 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2106 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
2107 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
2108 for ( int idx = 1; nodeIt->more(); idx++ ) {
2109 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
2110 nodeInfo( node, idx, e->NbNodes(), conItem );
2114 SMDS_NodeIteratorPtr nodeIt = e->nodeIterator();
2115 std::set< const SMDS_MeshNode* > addedNodes;
2116 QList<const SMDS_MeshElement*> uniqueNodes;
2117 while ( nodeIt->more() ) {
2118 const SMDS_MeshNode* node = nodeIt->next();
2119 if ( addedNodes.insert( node ).second )
2120 uniqueNodes.append( nodeIt->next() );
2122 SMDS_VolumeTool vtool( e );
2123 const int nbFaces = vtool.NbFaces();
2124 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
2125 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
2126 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces ));
2127 faceItem->setExpanded( true );
2129 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
2130 const int nbNodes = vtool.NbFaceNodes ( face_id );
2131 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
2132 const SMDS_MeshNode* node = aNodeIds[node_id];
2133 nodeInfo( node, uniqueNodes.indexOf(node) + 1, uniqueNodes.size(), faceItem );
2138 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
2139 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ));
2141 if( e->GetType()==SMDSAbs_Edge){
2142 afunctor.reset( new SMESH::Controls::Length() );
2143 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2144 afunctor->SetPrecision( cprecision );
2145 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
2146 lenItem->setText( 0, tr( "LENGTH_EDGES" ));
2147 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2149 if( e->GetType() == SMDSAbs_Face ) {
2151 afunctor.reset( new SMESH::Controls::Area() );
2152 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2153 afunctor->SetPrecision( cprecision );
2154 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
2155 areaItem->setText( 0, tr( "AREA_ELEMENTS" ));
2156 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ));
2158 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
2160 afunctor.reset( new SMESH::Controls::Taper() );
2161 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2162 afunctor->SetPrecision( cprecision );
2163 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
2164 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ));
2165 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2167 afunctor.reset( new SMESH::Controls::Warping() );
2168 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2169 afunctor->SetPrecision( cprecision );
2170 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
2171 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
2172 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2177 afunctor.reset( new SMESH::Controls::AspectRatio() );
2178 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2179 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
2180 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2181 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2184 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2185 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2186 afunctor->SetPrecision( cprecision );
2187 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2188 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ));
2189 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2191 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2193 afunctor.reset( new SMESH::Controls::Skew() );
2194 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2195 afunctor->SetPrecision( cprecision );
2196 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2197 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ));
2198 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2201 if ( hasShapeToMesh )
2203 afunctor.reset( new SMESH::Controls::Deflection2D() );
2204 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2205 QTreeWidgetItem* deflItem = createItem( cntrItem, Bold );
2206 deflItem->setText( 0, tr( "DEFLECTION_2D" ));
2207 deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2212 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2213 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2214 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2215 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2216 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2219 if( e->GetType() == SMDSAbs_Volume ) {
2223 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2224 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2225 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2226 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ));
2227 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2230 afunctor.reset( new SMESH::Controls::Volume() );
2231 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2232 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2233 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ));
2234 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2236 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2237 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2238 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2239 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ));
2240 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2244 afunctor.reset( new SMESH::Controls::Length2D() );
2245 afunctor->SetMesh( actor->GetObject()->GetMesh() );
2246 QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold );
2247 minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" ));
2248 SMESH::Controls::TSequenceOfXYZ points;
2249 afunctor->GetPoints( e, points ); // "non-standard" way, to make it work for all elem types
2250 minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( points )) );
2253 XYZ gc = gravityCenter( e );
2254 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2255 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ));
2256 QTreeWidgetItem* xItem = createItem( gcItem );
2257 xItem->setText( 0, "X" );
2258 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2259 QTreeWidgetItem* yItem = createItem( gcItem );
2260 yItem->setText( 0, "Y" );
2261 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2262 QTreeWidgetItem* zItem = createItem( gcItem );
2263 zItem->setText( 0, "Z" );
2264 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2267 if( e->GetType() == SMDSAbs_Face ) {
2268 XYZ gc = normal( e );
2269 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2270 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ));
2271 QTreeWidgetItem* xItem = createItem( nItem );
2272 xItem->setText( 0, "X" );
2273 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2274 QTreeWidgetItem* yItem = createItem( nItem );
2275 yItem->setText( 0, "Y" );
2276 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2277 QTreeWidgetItem* zItem = createItem( nItem );
2278 zItem->setText( 0, "Z" );
2279 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2283 SMESH::SMESH_Mesh_ptr aMesh = actor->GetObject()->GetMeshServer();
2284 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2285 if ( !CORBA::is_nil( aMesh )) {
2286 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2287 int shapeID = pos.shapeID;
2288 if ( shapeID > 0 ) {
2289 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2291 switch ( pos.shapeType ) {
2292 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2293 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2294 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2295 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2296 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2297 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2299 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ));
2300 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ));
2304 // groups element belongs to
2305 if ( !CORBA::is_nil( aMesh )) {
2306 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2307 QTreeWidgetItem* groupsItem = 0;
2308 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2309 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2310 if ( CORBA::is_nil( aGrp )) continue;
2311 QString aName = (char*) (CORBA::String_var) aGrp->GetName();
2312 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
2313 if ( !groupsItem ) {
2314 groupsItem = createItem( elemItem, Bold );
2315 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
2317 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2318 it->setText( 0, aName.trimmed() );
2319 if ( grp_details ) {
2320 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2321 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2322 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2324 // type : group on geometry, standalone group, group on filter
2325 QTreeWidgetItem* typeItem = createItem( it );
2326 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
2327 if ( !CORBA::is_nil( aStdGroup )) {
2328 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
2330 else if ( !CORBA::is_nil( aGeomGroup )) {
2331 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
2332 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2333 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2335 QTreeWidgetItem* gobjItem = createItem( typeItem );
2336 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2337 gobjItem->setText( 1, sobj->GetName().c_str() );
2340 else if ( !CORBA::is_nil( aFltGroup )) {
2341 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2345 QTreeWidgetItem* sizeItem = createItem( it );
2346 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2347 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2350 SALOMEDS::Color color = aGrp->GetColor();
2351 QTreeWidgetItem* colorItem = createItem( it );
2352 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2353 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2364 \brief Show node information
2365 \param node mesh node for showing
2366 \param index index of current node
2367 \param nbNodes number of unique nodes in element
2368 \param parentItem parent item of tree
2370 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2371 int nbNodes, QTreeWidgetItem* parentItem )
2373 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2374 // node number and ID
2375 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2376 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2377 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2378 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2379 nodeItem->setData( 1, IdRole, node->GetID() );
2380 nodeItem->setExpanded( false );
2382 QTreeWidgetItem* coordItem = createItem( nodeItem );
2383 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2384 QTreeWidgetItem* xItem = createItem( coordItem );
2385 xItem->setText( 0, "X" );
2386 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2387 QTreeWidgetItem* yItem = createItem( coordItem );
2388 yItem->setText( 0, "Y" );
2389 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2390 QTreeWidgetItem* zItem = createItem( coordItem );
2391 zItem->setText( 0, "Z" );
2392 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2393 // node connectivity
2394 QTreeWidgetItem* nconItem = createItem( nodeItem );
2395 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2396 Connectivity connectivity = nodeConnectivity( node );
2397 if ( !connectivity.isEmpty() ) {
2398 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2399 if ( !con.isEmpty() ) {
2400 QTreeWidgetItem* i = createItem( nconItem );
2401 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2402 i->setText( 1, con );
2404 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2405 if ( !con.isEmpty() ) {
2406 QTreeWidgetItem* i = createItem( nconItem );
2407 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2408 i->setText( 1, con );
2409 i->setData( 1, TypeRole, NodeConnectivity );
2411 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2412 if ( !con.isEmpty() ) {
2413 QTreeWidgetItem* i = createItem( nconItem );
2414 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2415 i->setText( 1, con );
2416 i->setData( 1, TypeRole, NodeConnectivity );
2418 con = formatConnectivity( connectivity, SMDSAbs_Face );
2419 if ( !con.isEmpty() ) {
2420 QTreeWidgetItem* i = createItem( nconItem );
2421 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2422 i->setText( 1, con );
2423 i->setData( 1, TypeRole, NodeConnectivity );
2425 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2426 if ( !con.isEmpty() ) {
2427 QTreeWidgetItem* i = createItem( nconItem );
2428 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2429 i->setText( 1, con );
2430 i->setData( 1, TypeRole, NodeConnectivity );
2435 \brief Internal clean-up (reset widget)
2437 void SMESHGUI_TreeElemInfo::clearInternal()
2444 \brief Create new tree item.
2445 \param parent parent tree widget item
2446 \param flags item flag
2447 \return new tree widget item
2449 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2451 QTreeWidgetItem* item;
2453 item = new QTreeWidgetItem( parent );
2455 item = new QTreeWidgetItem( myInfo );
2457 item->setFlags( item->flags() | Qt::ItemIsEditable );
2459 QFont f = item->font( 0 );
2461 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2462 if ( ( flags & Bold ) && ( i == 0 || flags & AllColumns ))
2463 item->setFont( i, f );
2466 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2468 QString resName = expandedResource( parent );
2469 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2472 item->setExpanded( true );
2476 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2478 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2479 if ( widgets.isEmpty() ) return;
2480 QTreeWidgetItem* aTreeItem = widgets.first();
2481 int type = aTreeItem->data( 1, TypeRole ).toInt();
2482 int id = aTreeItem->data( 1, IdRole ).toInt();
2484 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2485 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2486 emit( itemInfo( id ));
2487 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2488 emit( itemInfo( aTreeItem->text( 1 )) );
2491 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2494 int type = theItem->data( 1, TypeRole ).toInt();
2495 int id = theItem->data( 1, IdRole ).toInt();
2496 if ( type == ElemConnectivity && id > 0 )
2497 emit( itemInfo( id ));
2498 else if ( type == NodeConnectivity )
2499 emit( itemInfo( theItem->text( 1 )) );
2503 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2506 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2509 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2515 suffix = "N_"; break;
2517 suffix = "E_"; break;
2521 return QString( "Expanded_" ) + suffix + theItem->text( 0 );
2524 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2526 out << ruler( 12 ) << endl;
2527 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << endl;
2528 out << ruler( 12 ) << endl;
2530 QTreeWidgetItemIterator it( myInfo );
2532 if ( !( *it )->text(0).isEmpty() ) {
2533 out << indent( itemDepth( *it ) ) << ( *it )->text(0);
2534 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2542 ////////////////////////////////////////////////////////////////////////////////
2543 /// \class InfoComputor
2544 /// \brief Mesh information computor.
2547 /// The class is created for different computation operations. Currently it is
2548 /// used to compute size and number of underlying nodes for given group.
2549 ////////////////////////////////////////////////////////////////////////////////
2553 \param parent Parent object.
2554 \param proxy Object to compute information on (group).
2555 \param item Tree widget item, referenced by this computer.
2556 \param operation Value to compute.
2559 InfoComputor::InfoComputor( QObject* parent, const SMESHGUI_SelectionProxy& proxy, int operation )
2560 : QObject( parent ), myProxy( proxy ), myOperation( operation )
2565 \brief Compute requested information.
2568 void InfoComputor::compute()
2572 SUIT_OverrideCursor wc;
2573 switch ( myOperation )
2576 myProxy.size( true ); // force size computation
2580 myProxy.nbNodes( true ); // force size computation
2589 ////////////////////////////////////////////////////////////////////////////////
2590 /// \class SMESHGUI_AddInfo
2591 /// \brief Show additional information on selected object.
2593 /// Displays an additional information about selected object: mesh, sub-mesh
2596 /// \todo Rewrite saveInfo() method to print all data, not currently shown only.
2597 ////////////////////////////////////////////////////////////////////////////////
2601 \param parent Parent widget. Defaults to 0.
2603 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ): SMESHGUI_Info( parent )
2605 QVBoxLayout* l = new QVBoxLayout( this );
2607 l->setSpacing( SPACING );
2609 myTree = new QTreeWidget( this );
2611 myTree->setColumnCount( 2 );
2612 myTree->header()->setStretchLastSection( true );
2613 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2614 myTree->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2616 myTree->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2618 myTree->header()->hide();
2620 l->addWidget( myTree );
2626 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2631 \brief Show information on given object.
2632 \param proxy Object to show information on (mesh, sub-mesh, group).
2634 void SMESHGUI_AddInfo::showInfo( const SMESHGUI_SelectionProxy& proxy )
2637 setProperty( "group_index", 0 );
2638 setProperty( "submesh_index", 0 );
2639 myComputors.clear();
2642 // then fill panel with data if object is not null
2648 QTreeWidgetItem* nameItem = createItem( 0, Bold | AllColumns );
2649 nameItem->setText( 0, tr( "NAME" ) );
2650 nameItem->setText( 1, proxy.name() );
2653 if ( proxy.type() == SMESHGUI_SelectionProxy::Mesh )
2654 meshInfo( proxy, nameItem );
2655 else if ( proxy.type() == SMESHGUI_SelectionProxy::Submesh )
2656 subMeshInfo( proxy, nameItem );
2657 else if ( proxy.type() >= SMESHGUI_SelectionProxy::Group )
2658 groupInfo( proxy, nameItem );
2663 \brief Update information in panel.
2665 void SMESHGUI_AddInfo::updateInfo()
2667 showInfo( myProxy );
2671 \brief Reset panel (clear all data).
2673 void SMESHGUI_AddInfo::clear()
2679 \brief Create new item and add it to the tree.
2680 \param parent Parent tree widget item. Defaults to 0 (top-level item).
2681 \param options Item flags. Defaults to 0 (none).
2682 \return New tree widget item.
2684 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int options )
2686 QTreeWidgetItem* item;
2688 item = new QTreeWidgetItem( parent );
2690 item = new QTreeWidgetItem( myTree );
2691 setFontAttributes( item, options );
2692 item->setExpanded( true );
2697 \brief Show information on mesh.
2698 \param proxy Proxy object (mesh).
2699 \param parent Parent tree item.
2701 void SMESHGUI_AddInfo::meshInfo( const SMESHGUI_SelectionProxy& proxy, QTreeWidgetItem* parent )
2706 QString shapeName = proxy.shapeName();
2707 SMESHGUI_MedFileInfo inf = proxy.medFileInfo();
2710 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2711 typeItem->setText( 0, tr( "TYPE" ) );
2712 if ( !shapeName.isEmpty() )
2714 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2716 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2717 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2718 gobjItem->setText( 1, shapeName );
2720 else if ( inf.isValid() )
2722 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2723 // med file information
2724 QTreeWidgetItem* fileItem = createItem( parent, Bold );
2725 fileItem->setText( 0, tr( "FILE_NAME" ) );
2726 fileItem->setText( 1, inf.fileName() );
2727 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2728 sizeItem->setText( 0, tr( "FILE_SIZE" ) );
2729 sizeItem->setText( 1, QString::number( inf.size() ) );
2730 QTreeWidgetItem* versionItem = createItem( parent, Bold );
2731 versionItem->setText( 0, tr( "FILE_VERSION" ) );
2732 versionItem->setText( 1, inf.version() != "0" ? inf.version() : tr( "VERSION_UNKNOWN" ) );
2736 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2740 myGroups = proxy.groups();
2744 mySubMeshes = proxy.submeshes();
2749 \brief Show information on sub-mesh.
2750 \param proxy Proxy object (sub-mesh).
2751 \param parent Parent tree item.
2753 void SMESHGUI_AddInfo::subMeshInfo( const SMESHGUI_SelectionProxy& proxy, QTreeWidgetItem* parent )
2758 bool isShort = parent->parent() != 0;
2763 SMESHGUI_SelectionProxy meshProxy = proxy.mesh();
2766 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2767 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2768 nameItem->setText( 1, meshProxy.name() );
2773 QString shapeName = proxy.shapeName();
2774 if ( !shapeName.isEmpty() )
2776 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2777 gobjItem->setText( 1, shapeName );
2782 \brief Show information on group.
2783 \param proxy Proxy object (group).
2784 \param parent Parent tree item.
2786 void SMESHGUI_AddInfo::groupInfo( const SMESHGUI_SelectionProxy& proxy, QTreeWidgetItem* parent )
2791 bool isShort = parent->parent() != 0;
2796 SMESHGUI_SelectionProxy meshProxy = proxy.mesh();
2799 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2800 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2801 nameItem->setText( 1, meshProxy.name() );
2806 SMESHGUI_SelectionProxy::Type type = proxy.type();
2807 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2808 typeItem->setText( 0, tr( "TYPE" ) );
2809 if ( type == SMESHGUI_SelectionProxy::GroupStd )
2811 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2813 else if ( type == SMESHGUI_SelectionProxy::GroupGeom )
2815 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2817 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2818 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2819 gobjItem->setText( 1, proxy.shapeName() );
2821 else if ( type == SMESHGUI_SelectionProxy::GroupFilter )
2823 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2827 int etype = proxy.elementType();
2830 QString typeName = tr( "UNKNOWN" );
2834 typeName = tr( "NODE" );
2837 typeName = tr( "EDGE" );
2840 typeName = tr( "FACE" );
2843 typeName = tr( "VOLUME" );
2846 typeName = tr( "0DELEM" );
2849 typeName = tr( "BALL" );
2854 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2855 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2856 etypeItem->setText( 1, typeName );
2860 // note: size is not computed for group on filter for performance reasons, see IPAL52831
2861 bool meshLoaded = proxy.isMeshLoaded();
2862 int size = proxy.size();
2864 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2865 sizeItem->setText( 0, tr( "SIZE" ) );
2868 sizeItem->setText( 1, QString::number( size ) );
2872 QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this );
2873 myTree->setItemWidget( sizeItem, 1, btn );
2874 InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpSize );
2875 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2876 connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) );
2877 myComputors.append( comp );
2881 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2882 colorItem->setText( 0, tr( "COLOR" ) );
2883 colorItem->setBackground( 1, proxy.color() );
2885 // nb of underlying nodes
2886 if ( etype != SMESH::NODE )
2888 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2889 nodesItem->setText( 0, tr( "NB_NODES" ) );
2891 int nbNodes = proxy.nbNodes();
2894 nodesItem->setText( 1, QString::number( nbNodes ) );
2898 QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this );
2899 myTree->setItemWidget( nodesItem, 1, btn );
2900 InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpNbNodes );
2901 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2902 connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) );
2903 myComputors.append( comp );
2909 \brief Update information on child groups.
2911 void SMESHGUI_AddInfo::showGroups()
2913 // remove all computors
2914 myComputors.clear();
2916 // tree root should be the first top level item
2917 QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0;
2921 int idx = property( "group_index" ).toInt();
2923 // find sub-meshes top-level container item
2924 QTreeWidgetItem* itemGroups = 0;
2925 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ )
2927 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GroupsId )
2929 itemGroups = parent->child( i );
2931 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( myTree->itemWidget( itemGroups, 1 ) );
2933 extra->updateControls( myGroups.count(), idx );
2934 // clear: remove all group items
2935 while ( itemGroups->childCount() )
2936 delete itemGroups->child( 0 );
2940 QMap<int, QTreeWidgetItem*> grpItems;
2941 for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), (int)myGroups.count() ); i++ )
2943 SMESHGUI_SelectionProxy grp = myGroups[i];
2947 int grpType = grp.elementType();
2949 // create top-level groups container item if it does not exist
2952 itemGroups = createItem( parent, Bold | AllColumns );
2953 itemGroups->setText( 0, tr( "GROUPS" ) );
2954 itemGroups->setData( 0, Qt::UserRole, GroupsId );
2956 // if necessary, create extra widget to show information by chunks
2957 if ( myGroups.count() > blockSize() )
2959 ExtraWidget* extra = new ExtraWidget( this, true );
2960 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2961 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2962 myTree->setItemWidget( itemGroups, 1, extra );
2963 extra->updateControls( myGroups.count(), idx );
2967 // create container item corresponding to particular element type
2968 if ( !grpItems.contains( grpType ) )
2970 grpItems[ grpType ] = createItem( itemGroups, Bold | AllColumns );
2971 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2972 itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); // -1 needed since 0 corresponds to SMESH::ALL
2976 QTreeWidgetItem* nameItem = createItem( grpItems[ grpType ] );
2977 nameItem->setText( 0, grp.name().trimmed() ); // trim name
2980 groupInfo( grp, nameItem );
2985 \brief Update information on child sub-meshes.
2987 void SMESHGUI_AddInfo::showSubMeshes()
2989 // tree root should be the first top level item
2990 QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0;
2994 int idx = property( "submesh_index" ).toInt();
2996 // find sub-meshes top-level container item
2997 QTreeWidgetItem* itemSubMeshes = 0;
2998 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ )
3000 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SubMeshesId )
3002 itemSubMeshes = parent->child( i );
3004 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( myTree->itemWidget( itemSubMeshes, 1 ) );
3006 extra->updateControls( mySubMeshes.count(), idx );
3007 // clear: remove all sub-mesh items
3008 while ( itemSubMeshes->childCount() )
3009 delete itemSubMeshes->child( 0 );
3013 QMap<int, QTreeWidgetItem*> smItems;
3014 for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), mySubMeshes.count() ); i++ )
3016 SMESHGUI_SelectionProxy sm = mySubMeshes[i];
3020 int smType = sm.shapeType();
3023 else if ( smType == GEOM::COMPSOLID )
3024 smType = GEOM::COMPOUND;
3026 // create top-level sub-meshes container item if it does not exist
3027 if ( !itemSubMeshes )
3029 itemSubMeshes = createItem( parent, Bold | AllColumns );
3030 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
3031 itemSubMeshes->setData( 0, Qt::UserRole, SubMeshesId );
3033 // if necessary, create extra widget to show information by chunks
3034 if ( mySubMeshes.count() > blockSize() )
3036 ExtraWidget* extra = new ExtraWidget( this, true );
3037 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
3038 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
3039 myTree->setItemWidget( itemSubMeshes, 1, extra );
3040 extra->updateControls( mySubMeshes.count(), idx );
3044 // create container item corresponding to particular shape type
3045 if ( !smItems.contains( smType ) )
3047 smItems[ smType ] = createItem( itemSubMeshes, Bold | AllColumns );
3048 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
3049 itemSubMeshes->insertChild( smType, smItems[ smType ] );
3053 QTreeWidgetItem* nameItem = createItem( smItems[ smType ] );
3054 nameItem->setText( 0, sm.name().trimmed() ); // trim name
3057 subMeshInfo( sm, nameItem );
3062 \brief Show previous chunk of information on child groups.
3064 void SMESHGUI_AddInfo::showPreviousGroups()
3066 int idx = property( "group_index" ).toInt();
3067 setProperty( "group_index", idx-1 );
3072 \brief Show next chunk of information on child groups.
3074 void SMESHGUI_AddInfo::showNextGroups()
3076 int idx = property( "group_index" ).toInt();
3077 setProperty( "group_index", idx+1 );
3082 \brief Show previous chunk of information on child sub-meshes.
3084 void SMESHGUI_AddInfo::showPreviousSubMeshes()
3086 int idx = property( "submesh_index" ).toInt();
3087 setProperty( "submesh_index", idx-1 );
3092 \brief Show next chunk of information on child sub-meshes.
3094 void SMESHGUI_AddInfo::showNextSubMeshes()
3096 int idx = property( "submesh_index" ).toInt();
3097 setProperty( "submesh_index", idx+1 );
3102 \brief Write information from panel to ouput stream.
3103 \param out Text stream output.
3105 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
3108 QString title = tr( "ADDITIONAL_INFO" );
3109 out << ruler( title.size() ) << endl;
3110 out << title << endl;
3111 out << ruler( title.size() ) << endl;
3115 QTreeWidgetItemIterator it( myTree );
3118 if ( !( ( *it )->text(0) ).isEmpty() )
3120 out << indent( itemDepth( *it ) ) << ( *it )->text(0);
3121 if ( ( *it )->text(0) == tr( "COLOR" ) )
3122 out << ":" << spacing() << ( ( ( *it )->background(1) ).color() ).name();
3123 else if ( !( ( *it )->text(1) ).isEmpty() )
3124 out << ":" << spacing() << ( *it )->text(1);
3132 ////////////////////////////////////////////////////////////////////////////////
3133 /// \class GroupCombo
3134 /// \brief Customized combo box to manage list of mesh groups.
3136 ////////////////////////////////////////////////////////////////////////////////
3138 class GroupCombo: public QComboBox
3140 class Item: public QStandardItem
3143 SMESHGUI_SelectionProxy myGroup;
3144 Item( const SMESHGUI_SelectionProxy& group )
3147 setText( myGroup.name() );
3149 SMESHGUI_SelectionProxy group()
3155 SMESHGUI_SelectionProxy myProxy;
3158 GroupCombo( QWidget* );
3159 void setSource( const SMESHGUI_SelectionProxy& );
3160 SMESHGUI_SelectionProxy currentGroup() const;
3165 \param parent Parent widget.
3168 GroupCombo::GroupCombo( QWidget* parent ): QComboBox( parent )
3170 setModel( new QStandardItemModel( this ) );
3174 \brief Set mesh source.
3175 \param obj Mesh source.
3178 void GroupCombo::setSource( const SMESHGUI_SelectionProxy& proxy )
3180 if ( myProxy == proxy )
3185 bool blocked = blockSignals( true );
3186 QStandardItemModel* m = dynamic_cast<QStandardItemModel*>( model() );
3191 if ( myProxy.type() == SMESHGUI_SelectionProxy::Mesh )
3193 QList<SMESHGUI_SelectionProxy> groups = myProxy.groups();
3194 for ( int i = 0; i < groups.count(); ++i )
3198 QString name = groups[i].name();
3199 if ( !name.isEmpty() )
3200 m->appendRow( new Item( groups[i] ) );
3203 setCurrentIndex( -1 ); // for performance reasons
3205 else if ( myProxy.type() >= SMESHGUI_SelectionProxy::Group )
3207 m->appendRow( new Item( myProxy ) );
3208 setCurrentIndex( 0 );
3212 blockSignals( blocked );
3216 \brief Get currently selected group.
3217 \return Selected group.
3220 SMESHGUI_SelectionProxy GroupCombo::currentGroup() const
3222 SMESHGUI_SelectionProxy group;
3223 QStandardItemModel* m = dynamic_cast<QStandardItemModel*>( model() );
3224 if ( currentIndex() >= 0 )
3225 group = dynamic_cast<Item*>( m->item( currentIndex() ) )->group();
3229 ////////////////////////////////////////////////////////////////////////////////
3230 /// \class SMESHGUI_MeshInfoDlg
3231 /// \brief Mesh information dialog box
3233 /// \todo Move all business logic for element info to SMESHGUI_ElemInfo class.
3234 /// \todo Add selection button to reactivate selection on move from other dlg.
3235 ////////////////////////////////////////////////////////////////////////////////
3239 \param parent Parent widget.
3240 \param page Dialog page to show at start-up. Defaults to \c BaseInfo.
3242 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
3246 setAttribute( Qt::WA_DeleteOnClose, true );
3247 setWindowTitle( tr( "MESH_INFO" ) );
3248 setSizeGripEnabled( true );
3250 myTabWidget = new QTabWidget( this );
3254 myBaseInfo = new SMESHGUI_BaseInfo( myTabWidget );
3255 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
3259 QWidget* w = new QWidget( myTabWidget );
3261 myMode = new QButtonGroup( this );
3262 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
3263 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
3264 myMode->addButton( new QRadioButton( tr( "GROUP_MODE" ), w ), GroupMode );
3265 myMode->button( NodeMode )->setChecked( true );
3266 myID = new QLineEdit( w );
3267 myID->setValidator( new SMESHGUI_IdValidator( this ) );
3268 myGroups = new GroupCombo( w );
3269 QStackedWidget* stack = new QStackedWidget( w );
3270 stack->addWidget( myID );
3271 stack->addWidget( myGroups );
3272 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
3273 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ) );
3275 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
3276 mode = qMin( 1, qMax( 0, mode ) );
3279 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
3281 myElemInfo = new SMESHGUI_TreeElemInfo( w );
3282 stack->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
3284 QGridLayout* elemLayout = new QGridLayout( w );
3285 elemLayout->setMargin( MARGIN );
3286 elemLayout->setSpacing( SPACING );
3287 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
3288 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
3289 elemLayout->addWidget( myMode->button( GroupMode ), 0, 2 );
3290 elemLayout->addWidget( stack, 0, 3 );
3291 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 4 );
3292 elemLayout->addWidget( myElemInfo, 2, 0, 1, 4 );
3294 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
3298 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
3299 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
3303 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
3304 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
3308 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3309 okBtn->setAutoDefault( true );
3310 okBtn->setDefault( true );
3312 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3313 dumpBtn->setAutoDefault( true );
3314 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3315 helpBtn->setAutoDefault( true );
3317 QHBoxLayout* btnLayout = new QHBoxLayout;
3318 btnLayout->setSpacing( SPACING );
3319 btnLayout->setMargin( 0 );
3321 btnLayout->addWidget( okBtn );
3322 btnLayout->addWidget( dumpBtn );
3323 btnLayout->addStretch( 10 );
3324 btnLayout->addWidget( helpBtn );
3328 QVBoxLayout* l = new QVBoxLayout ( this );
3329 l->setMargin( MARGIN );
3330 l->setSpacing( SPACING );
3331 l->addWidget( myTabWidget );
3332 l->addLayout( btnLayout );
3336 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
3338 // set-up connections
3340 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3341 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3342 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3343 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
3344 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
3345 connect( myGroups, SIGNAL( currentIndexChanged( int ) ), this, SLOT( modeChanged() ) );
3346 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
3347 connect( myIDPreviewCheck, SIGNAL( toggled( bool ) ), this, SLOT( idPreviewChange( bool ) ) );
3348 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3349 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3350 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
3351 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
3352 connect( this, SIGNAL( switchMode( int ) ), stack, SLOT( setCurrentIndex( int ) ) );
3356 myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "id_preview_resource", false ) );
3363 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
3369 \brief Show mesh information on given object.
3370 \param io Interactive object.
3372 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io )
3375 showInfo( SMESHGUI_SelectionProxy( io ) );
3379 \brief Show mesh information on given object.
3380 \param proxy Selection proxy.
3382 void SMESHGUI_MeshInfoDlg::showInfo( const SMESHGUI_SelectionProxy& proxy )
3384 SUIT_OverrideCursor wc;
3391 SMESH::SMESH_IDSource_var obj = myProxy.object();
3394 myBaseInfo->showInfo( proxy );
3396 // "Additional info" tab
3397 myAddInfo->showInfo( proxy );
3399 // "Quality info" tab
3400 // Note: for performance reasons we update it only if it is currently active
3401 if ( myTabWidget->currentIndex() == CtrlInfo )
3402 myCtrlInfo->showInfo( proxy );
3404 // "Element info" tab
3405 myGroups->setSource( proxy );
3406 if ( myMode->checkedId() == GroupMode ) {
3407 SMESHGUI_SelectionProxy group = myGroups->currentGroup();
3409 myElemInfo->showInfo( group );
3411 myElemInfo->clear();
3414 SVTK_Selector* selector = SMESH::GetSelector();
3417 if ( myProxy.actor() && selector ) { //todo: actor()?
3418 nb = myMode->checkedId() == NodeMode ?
3419 SMESH::GetNameOfSelectedElements( selector, myProxy.io(), ID ) :
3420 SMESH::GetNameOfSelectedNodes( selector, myProxy.io(), ID );
3423 myID->setText( ID.trimmed() );
3425 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
3426 foreach ( ID, idTxt )
3427 ids << ID.trimmed().toUInt();
3428 myElemInfo->showInfo( proxy, ids, myMode->checkedId() == ElemMode );
3432 myElemInfo->clear();
3438 \brief Update information.
3440 void SMESHGUI_MeshInfoDlg::updateInfo()
3442 SALOME_ListIO selected;
3443 SMESHGUI::selectionMgr()->selectedObjects( selected );
3445 if ( selected.Extent() == 1 )
3446 showInfo( selected.First() );
3448 showInfo( myProxy );
3452 \brief Clean-up on dialog closing.
3454 void SMESHGUI_MeshInfoDlg::reject()
3456 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3457 selMgr->clearFilters();
3458 SMESH::SetPointRepresentation( false );
3459 if ( SVTK_ViewWindow* viewWindow = SMESH::GetViewWindow() )
3460 viewWindow->SetSelectionMode( ActorSelection );
3462 myIDPreview->SetPointsLabeled( false );
3466 \brief Process keyboard event.
3467 \param e Key press event.
3469 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3471 QDialog::keyPressEvent( e );
3472 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3479 \brief Set-up selection mode for currently selected page.
3481 void SMESHGUI_MeshInfoDlg::updateSelection()
3483 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3485 disconnect( selMgr, 0, this, 0 );
3486 selMgr->clearFilters();
3488 int selMode = ActorSelection;
3489 if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == NodeMode )
3490 selMode = NodeSelection;
3491 else if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == ElemMode )
3492 selMode = CellSelection;
3493 SMESH::SetPointRepresentation( selMode == NodeSelection );
3494 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3495 aViewWindow->SetSelectionMode( selMode );
3497 SMESHGUI_SelectionProxy previous = myProxy;
3498 QString ids = myID->text().trimmed();
3501 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3504 if ( myProxy && myProxy == previous && !ids.isEmpty() ) {
3505 myID->setText( ids );
3511 \brief Show documentation on selected dialog page.
3513 void SMESHGUI_MeshInfoDlg::help()
3515 QString helpPage = "mesh_infos.html";
3516 switch ( myTabWidget->currentIndex() )
3519 helpPage += "#advanced-mesh-infos-anchor";
3522 helpPage += "#mesh-element-info-anchor";
3525 helpPage += "#mesh-addition-info-anchor";
3528 helpPage += "#mesh-quality-info-anchor";
3533 SMESH::ShowHelpFile( helpPage );
3537 \brief Deactivate dialog box.
3539 void SMESHGUI_MeshInfoDlg::deactivate()
3541 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3545 \brief Called when users switches between node / element modes.
3547 void SMESHGUI_MeshInfoDlg::modeChanged()
3549 emit( switchMode( myMode->checkedId() == GroupMode ? 1 : 0 ) );
3555 \brief Called when users prints mesh element ID in the corresponding field.
3557 void SMESHGUI_MeshInfoDlg::idChanged()
3559 myIDPreview->SetPointsLabeled( false );
3561 SVTK_Selector* selector = SMESH::GetSelector();
3562 if ( myProxy.actor() && selector ) { //todo: actor()?
3563 Handle(SALOME_InteractiveObject) IO = myProxy.actor()->getIO(); //todo: actor()?
3564 TColStd_MapOfInteger ID;
3566 std::vector<int> idVec;
3567 std::list< gp_XYZ > aGrCentersXYZ;
3568 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3569 foreach ( QString tid, idTxt ) {
3570 long id = tid.trimmed().toUInt();
3571 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3572 myProxy.actor()->GetObject()->GetMesh()->FindElement( id ) : //todo: actor()?
3573 myProxy.actor()->GetObject()->GetMesh()->FindNode( id ); //todo: actor()?
3577 if ( myMode->checkedId() == ElemMode )
3579 idVec.push_back( id );
3580 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ) );
3584 selector->AddOrRemoveIndex( IO, ID, false );
3585 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3587 if ( myMode->checkedId() == NodeMode )
3588 myIDPreview->SetPointsData( myProxy.actor()->GetObject()->GetMesh(), ID ); //todo: actor()?
3590 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3592 bool showIDs = ( !ID.IsEmpty() &&
3593 myIDPreviewCheck->isChecked() &&
3594 myTabWidget->currentIndex() == ElemInfo );
3595 myIDPreview->SetPointsLabeled( showIDs, myProxy.actor()->GetVisibility() ); //todo: actor()?
3597 aViewWindow->highlight( IO, true, true );
3598 aViewWindow->Repaint();
3600 myElemInfo->showInfo( myProxy, ids, myMode->checkedId() == ElemMode );
3605 * \brief Show IDs clicked
3607 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3609 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3610 SMESHGUI::resourceMgr()->setValue("SMESH", "id_preview_resource", isOn );
3611 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3612 aViewWindow->Repaint();
3615 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3617 if ( id > 0 && myProxy.actor()->GetObject()->GetMesh()->FindNode( id ) ) { //todo: actor()?
3618 myMode->button( NodeMode )->click();
3619 myID->setText( QString::number( id ) );
3623 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3625 if ( !theStr.isEmpty() ) {
3626 myMode->button( ElemMode )->click();
3627 myID->setText( theStr );
3632 \brief Dump information to file.
3634 void SMESHGUI_MeshInfoDlg::dump()
3636 DumpFileDlg fd( this );
3637 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3638 fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) );
3639 fd.setChecked( BaseInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_base", true ) );
3640 fd.setChecked( ElemInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_elem", true ) );
3641 fd.setChecked( AddInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_add", true ) );
3642 fd.setChecked( CtrlInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_ctrl", true ) );
3643 if ( fd.exec() == QDialog::Accepted )
3645 QString fileName = fd.selectedFile();
3646 if ( !fileName.isEmpty() ) {
3647 QFile file( fileName );
3648 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
3651 QTextStream out( &file );
3652 if ( fd.isChecked( BaseInfo ) ) myBaseInfo->saveInfo( out );
3653 if ( fd.isChecked( ElemInfo ) ) myElemInfo->saveInfo( out );
3654 if ( fd.isChecked( AddInfo ) ) myAddInfo->saveInfo( out );
3655 if ( fd.isChecked( CtrlInfo ) ) myCtrlInfo->saveInfo( out );
3660 ////////////////////////////////////////////////////////////////////////////////
3661 /// \class SMESHGUI_CtrlInfo
3662 /// \brief Show quality statistics information on selected object.
3664 /// Displays quality controls statistics about selected object: mesh, sub-mesh,
3665 /// group or arbitrary ID source.
3666 ////////////////////////////////////////////////////////////////////////////////
3670 \param parent Parent widget. Defaults to 0.
3672 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ): SMESHGUI_Info( parent )
3674 QGridLayout* l = new QGridLayout( this );
3675 l->setMargin( MARGIN );
3676 l->setSpacing( SPACING );
3678 QIcon aComputeIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3679 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3682 QLabel* aNameLab = createLabel( tr( "NAME_LAB" ), this, Bold );
3683 QLabel* aName = createField( this, "ctrlName" );
3684 aName->setMinimumWidth( 150 );
3688 QLabel* aNodesLab = createLabel( tr( "NODES_INFO" ), this, Bold );
3689 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3690 QLabel* aNodesFree = createField( this, "ctrlNodesFree" );
3691 myWidgets << aNodesFree;
3692 myPredicates << aFilterMgr->CreateFreeNodes();
3694 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3695 QLabel* aNodesNbConn = createField( this, "ctrlNodesCnty" );
3696 myWidgets << aNodesNbConn;
3697 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3699 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3700 QLabel* aNodesDouble = createField( this, "ctrlNodesDouble" );
3701 myWidgets << aNodesDouble;
3702 myPredicates << aFilterMgr->CreateEqualNodes();
3703 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3704 myToleranceWidget = new SMESHGUI_SpinBox( this );
3705 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3706 myToleranceWidget->setAcceptNames( false );
3707 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3710 QLabel* anEdgesLab = createLabel( tr( "EDGES_INFO" ), this, Bold );
3711 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3712 QLabel* anEdgesDouble = createField( this, "ctrlEdgesDouble" );
3713 myWidgets << anEdgesDouble;
3714 myPredicates << aFilterMgr->CreateEqualEdges();
3717 QLabel* aFacesLab = createLabel( tr( "FACES_INFO" ), this, Bold );
3718 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3719 QLabel* aFacesDouble = createField( this, "ctrlFacesDouble" );
3720 myWidgets << aFacesDouble;
3721 myPredicates << aFilterMgr->CreateEqualFaces();
3722 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3723 QLabel* aFacesOver = createField( this, "ctrlFacesOver" );
3724 myWidgets << aFacesOver;
3725 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3726 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3727 myPlot = createPlot( this );
3728 myAspectRatio = aFilterMgr->CreateAspectRatio();
3731 QLabel* aVolumesLab = createLabel( tr( "VOLUMES_INFO" ), this, Bold );
3732 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3733 QLabel* aVolumesDouble = createField( this, "ctrlVolumesDouble" );
3734 myWidgets << aVolumesDouble;
3735 myPredicates << aFilterMgr->CreateEqualVolumes();
3736 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3737 QLabel* aVolumesOver = createField( this, "ctrlVolumesOver" );
3738 myWidgets << aVolumesOver;
3739 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3740 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3741 myPlot3D = createPlot( this );
3742 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3744 QToolButton* aFreeNodesBtn = new QToolButton( this );
3745 aFreeNodesBtn->setIcon(aComputeIcon);
3746 myButtons << aFreeNodesBtn; //0
3748 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3749 aNodesNbConnBtn->setIcon(aComputeIcon);
3750 myButtons << aNodesNbConnBtn; //1
3752 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3753 aDoubleNodesBtn->setIcon(aComputeIcon);
3754 myButtons << aDoubleNodesBtn; //2
3756 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3757 aDoubleEdgesBtn->setIcon(aComputeIcon);
3758 myButtons << aDoubleEdgesBtn; //3
3760 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3761 aDoubleFacesBtn->setIcon(aComputeIcon);
3762 myButtons << aDoubleFacesBtn; //4
3764 QToolButton* aOverContFacesBtn = new QToolButton( this );
3765 aOverContFacesBtn->setIcon(aComputeIcon);
3766 myButtons << aOverContFacesBtn; //5
3768 QToolButton* aComputeFaceBtn = new QToolButton( this );
3769 aComputeFaceBtn->setIcon(aComputeIcon);
3770 myButtons << aComputeFaceBtn; //6
3772 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3773 aDoubleVolumesBtn->setIcon(aComputeIcon);
3774 myButtons << aDoubleVolumesBtn; //7
3776 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3777 aOverContVolumesBtn->setIcon(aComputeIcon);
3778 myButtons << aOverContVolumesBtn; //8
3780 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3781 aComputeVolumeBtn->setIcon(aComputeIcon);
3782 myButtons << aComputeVolumeBtn; //9
3784 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3785 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3786 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3787 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3788 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3789 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3790 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3791 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3792 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3793 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3794 connect( myToleranceWidget, SIGNAL( valueChanged( double ) ), this, SLOT( setTolerance( double ) ) );
3796 l->addWidget( aNameLab, 0, 0 ); //0
3797 l->addWidget( aName, 0, 1, 1, 2 ); //1
3798 l->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3799 l->addWidget( aNodesFreeLab, 2, 0 ); //3
3800 l->addWidget( aNodesFree, 2, 1 ); //4
3801 l->addWidget( aFreeNodesBtn, 2, 2 ); //5
3802 l->addWidget( aNodesNbConnLab, 3, 0 ); //6
3803 l->addWidget( aNodesNbConn, 3, 1 ); //7
3804 l->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3805 l->addWidget( aNodesDoubleLab, 4, 0 ); //9
3806 l->addWidget( aNodesDouble, 4, 1 ); //10
3807 l->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3808 l->addWidget( aToleranceLab, 5, 0 ); //12
3809 l->addWidget( myToleranceWidget, 5, 1 ); //13
3810 l->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3811 l->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3812 l->addWidget( anEdgesDouble, 7, 1 ); //16
3813 l->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3814 l->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3815 l->addWidget( aFacesDoubleLab, 9, 0 ); //19
3816 l->addWidget( aFacesDouble, 9, 1 ); //20
3817 l->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3818 l->addWidget( aFacesOverLab, 10, 0 ); //22
3819 l->addWidget( aFacesOver, 10, 1 ); //23
3820 l->addWidget( aOverContFacesBtn, 10, 2 ); //24
3821 l->addWidget( anAspectRatioLab, 11, 0 ); //25
3822 l->addWidget( aComputeFaceBtn, 11, 2 ); //26
3823 l->addWidget( myPlot, 12, 0, 1, 3 );//27
3824 l->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3825 l->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3826 l->addWidget( aVolumesDouble, 14, 1 ); //30
3827 l->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3828 l->addWidget( aVolumesOverLab, 15, 0 ); //32
3829 l->addWidget( aVolumesOver, 15, 1 ); //33
3830 l->addWidget( aOverContVolumesBtn,15, 2 ); //34
3831 l->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3832 l->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3833 l->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3835 l->setColumnStretch( 0, 0 );
3836 l->setColumnStretch( 1, 5 );
3837 l->setRowStretch ( 12, 5 );
3838 l->setRowStretch ( 17, 5 );
3839 l->setRowStretch ( 18, 1 );
3847 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3852 \brief Create plot widget.
3853 \param parent Parent widget.
3854 \return New plot widget.
3856 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3858 QwtPlot* aPlot = new QwtPlot( parent );
3859 aPlot->setMinimumSize( 100, 100 );
3860 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3861 xFont.setPointSize( 5 );
3862 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3863 yFont.setPointSize( 5 );
3864 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3865 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3871 \brief Show information on given object.
3872 \param proxy Object to show information on (mesh, sub-mesh, group, ID source).
3874 void SMESHGUI_CtrlInfo::showInfo( const SMESHGUI_SelectionProxy& proxy )
3882 SMESH::SMESH_IDSource_var obj = proxy.object();
3884 myWidgets[0]->setText( proxy.name() );
3886 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3887 if ( mesh->_is_nil() ) return;
3889 const bool meshLoaded = mesh->IsLoaded();
3890 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3891 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3892 for ( int i = 0; i < myButtons.count(); ++i )
3893 myButtons[i]->setEnabled( true );
3895 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3896 if ( ! &nbElemsByType.in() ) return;
3898 const CORBA::Long ctrlLimit =
3899 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3902 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3903 // const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3904 // nbElemsByType[ SMESH::FACE ] +
3905 // nbElemsByType[ SMESH::VOLUME ] );
3906 if ( nbNodes > 0 ) {
3907 if ( nbNodes <= ctrlLimit ) {
3909 computeFreeNodesInfo();
3910 // node connectivity number
3911 computeNodesNbConnInfo();
3913 computeDoubleNodesInfo();
3916 myButtons[0]->setEnabled( true );
3917 myButtons[1]->setEnabled( true );
3918 myButtons[2]->setEnabled( true );
3922 for( int i=2; i<=13; i++)
3923 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
3927 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3929 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3930 computeDoubleEdgesInfo();
3932 myButtons[3]->setEnabled( true );
3935 for( int i=14; i<=17; i++)
3936 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
3940 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3941 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3943 computeDoubleFacesInfo();
3944 // over constrained faces
3945 computeOverConstrainedFacesInfo();
3946 // aspect Ratio histogram
3947 computeAspectRatio();
3950 myButtons[4]->setEnabled( true );
3951 myButtons[5]->setEnabled( true );
3952 myButtons[6]->setEnabled( true );
3954 #ifdef DISABLE_PLOT2DVIEWER
3955 for( int i=25; i<=27; i++)
3956 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
3960 for( int i=18; i<=27; i++)
3961 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
3965 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3966 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3968 computeDoubleVolumesInfo();
3969 // over constrained volumes
3970 computeOverConstrainedVolumesInfo();
3971 // aspect Ratio 3D histogram
3972 computeAspectRatio3D();
3975 myButtons[7]->setEnabled( true );
3976 myButtons[8]->setEnabled( true );
3977 myButtons[9]->setEnabled( true );
3979 #ifdef DISABLE_PLOT2DVIEWER
3980 for( int i=35; i<=37; i++)
3981 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
3985 for( int i=28; i<=37; i++)
3986 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
3990 //================================================================================
3992 * \brief Computes and shows nb of elements satisfying a given predicate
3993 * \param [in] ft - a predicate type (SMESH::FunctorType)
3994 * \param [in] iBut - index of one of myButtons to disable
3995 * \param [in] iWdg - index of one of myWidgets to show the computed number
3997 //================================================================================
3999 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
4001 myButtons[ iBut ]->setEnabled( false );
4002 myWidgets[ iWdg ]->setText( "" );
4007 SUIT_OverrideCursor wc;
4009 SMESH::SMESH_IDSource_var obj = myProxy.object();
4010 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
4012 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
4015 showInfo( myProxy ); // try to show all values
4016 if ( !myWidgets[ iWdg ]->text().isEmpty() )
4017 return; // <ft> predicate already computed
4019 // look for a predicate of type <ft>
4020 for ( int i = 0; i < myPredicates.count(); ++i )
4021 if ( myPredicates[i]->GetFunctorType() == ft )
4023 CORBA::Long nb = myPredicates[i]->NbSatisfying( obj );
4024 myWidgets[ iWdg ]->setText( QString::number( nb ) );
4028 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
4030 computeNb( SMESH::FT_FreeNodes, 0, 1 );
4033 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
4035 computeNb( SMESH::FT_EqualNodes, 2, 3 );
4038 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
4040 computeNb( SMESH::FT_EqualEdges, 3, 4 );
4043 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
4045 computeNb( SMESH::FT_EqualFaces, 4, 5 );
4048 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
4050 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
4053 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
4055 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
4058 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
4060 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
4063 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
4065 myButtons[ 1 ]->setEnabled( false );
4066 myWidgets[ 2 ]->setText( "" );
4071 SUIT_OverrideCursor wc;
4073 SMESH::SMESH_IDSource_var obj = myProxy.object();
4074 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
4076 if ( !mesh->IsLoaded() )
4079 showInfo( myProxy ); // try to show all values
4080 if ( !myWidgets[ 2 ]->text().isEmpty() )
4081 return; // already computed
4083 myNodeConnFunctor->SetMesh( mesh );
4084 SMESH::Histogram_var histogram =
4085 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, obj );
4087 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ) );
4090 void SMESHGUI_CtrlInfo::computeAspectRatio()
4092 #ifndef DISABLE_PLOT2DVIEWER
4093 myButtons[6]->setEnabled( false );
4098 SUIT_OverrideCursor wc;
4100 SMESH::SMESH_IDSource_var obj = myProxy.object();
4101 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
4103 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
4104 if ( aHistogram && !aHistogram->isEmpty() ) {
4105 QwtPlotItem* anItem = aHistogram->createPlotItem();
4106 anItem->attach( myPlot );
4113 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
4115 #ifndef DISABLE_PLOT2DVIEWER
4116 myButtons[9]->setEnabled( false );
4121 SUIT_OverrideCursor wc;
4123 SMESH::SMESH_IDSource_var obj = myProxy.object();
4124 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
4126 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
4127 if ( aHistogram && !aHistogram->isEmpty() ) {
4128 QwtPlotItem* anItem = aHistogram->createPlotItem();
4129 anItem->attach( myPlot3D );
4137 \brief Internal clean-up (reset widget)
4139 void SMESHGUI_CtrlInfo::clearInternal()
4141 for( int i=0; i<=37; i++)
4142 dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( true );
4143 for( int i=0; i<=9; i++)
4144 myButtons[i]->setEnabled( false );
4145 myPlot->detachItems();
4146 myPlot3D->detachItems();
4149 myWidgets[0]->setText( QString() );
4150 for ( int i = 1; i < myWidgets.count(); i++ )
4151 myWidgets[i]->setText( "" );
4154 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
4156 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
4157 myButtons[1]->setEnabled( true );
4158 myWidgets[2]->setText("");
4161 #ifndef DISABLE_PLOT2DVIEWER
4162 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
4164 SUIT_OverrideCursor wc;
4166 SMESH::SMESH_IDSource_var obj = myProxy.object();
4167 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
4169 if ( !mesh->IsLoaded() )
4171 aNumFun->SetMesh( mesh );
4173 CORBA::Long cprecision = 6;
4174 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
4175 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
4176 aNumFun->SetPrecision( cprecision );
4178 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
4180 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
4181 /*isLogarithmic=*/false,
4183 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
4184 aHistogram->setColor( palette().color( QPalette::Highlight ) );
4185 if ( &histogramVar.in() )
4187 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
4188 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
4189 if ( histogramVar->length() >= 2 )
4190 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
4196 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
4197 out << ruler( 20 ) << endl;
4198 out << tr( "CTRL_INFO" ) << endl;
4199 out << ruler( 20 ) << endl;
4200 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << endl;
4201 out << tr( "NODES_INFO" ) << endl;
4202 out << indent() << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << endl;
4203 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << endl;
4204 out << tr( "EDGES_INFO" ) << endl;
4205 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << endl;
4206 out << tr( "FACES_INFO" ) << endl;
4207 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << endl;
4208 out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << endl;
4209 out << tr( "VOLUMES_INFO" ) << endl;
4210 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << endl;
4211 out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << endl;
4214 ////////////////////////////////////////////////////////////////////////////////
4215 /// \class SMESHGUI_CtrlInfoDlg
4216 /// \brief Overall Mesh Quality dialog.
4217 /// \todo Add selection button to reactivate selection on move from other dlg.
4218 ////////////////////////////////////////////////////////////////////////////////
4222 \param parent parent widget
4224 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
4227 setAttribute( Qt::WA_DeleteOnClose, true );
4228 setWindowTitle( tr( "CTRL_INFO" ) );
4229 setMinimumSize( 400, 600 );
4231 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
4234 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
4235 okBtn->setAutoDefault( true );
4236 okBtn->setDefault( true );
4238 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
4239 dumpBtn->setAutoDefault( true );
4240 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
4241 helpBtn->setAutoDefault( true );
4243 QHBoxLayout* btnLayout = new QHBoxLayout;
4244 btnLayout->setSpacing( SPACING );
4245 btnLayout->setMargin( 0 );
4247 btnLayout->addWidget( okBtn );
4248 btnLayout->addWidget( dumpBtn );
4249 btnLayout->addStretch( 10 );
4250 btnLayout->addWidget( helpBtn );
4252 QVBoxLayout* l = new QVBoxLayout ( this );
4254 l->setSpacing( SPACING );
4255 l->addWidget( myCtrlInfo );
4256 l->addLayout( btnLayout );
4258 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
4259 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
4260 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
4261 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
4262 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
4270 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
4275 \brief Show mesh quality information on given object.
4276 \param io Interactive object.
4278 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io )
4281 showInfo( SMESHGUI_SelectionProxy( io ) );
4285 \brief Show mesh quality information on given object.
4286 \param proxy Selection proxy.
4288 void SMESHGUI_CtrlInfoDlg::showInfo( const SMESHGUI_SelectionProxy& proxy )
4290 SUIT_OverrideCursor wc;
4296 myCtrlInfo->showInfo( proxy );
4300 \brief Show mesh information
4302 void SMESHGUI_CtrlInfoDlg::updateInfo()
4304 SALOME_ListIO selected;
4305 SMESHGUI::selectionMgr()->selectedObjects( selected );
4307 if ( selected.Extent() == 1 )
4308 showInfo( selected.First() );
4310 showInfo( myProxy );
4314 \brief Perform clean-up actions on the dialog box closing.
4316 void SMESHGUI_CtrlInfoDlg::reject()
4318 SMESH::SetPointRepresentation( false );
4323 \brief Setup selection mode depending on the current dialog box state.
4325 void SMESHGUI_CtrlInfoDlg::updateSelection()
4327 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
4328 disconnect( selMgr, 0, this, 0 );
4329 SMESH::SetPointRepresentation( false );
4330 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
4335 \brief Deactivate dialog box.
4337 void SMESHGUI_CtrlInfoDlg::deactivate()
4339 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
4343 \brief Dump information to file.
4345 void SMESHGUI_CtrlInfoDlg::dump()
4347 DumpFileDlg fd( this, false );
4348 fd.setWindowTitle( tr( "SAVE_INFO" ) );
4349 fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) );
4350 if ( fd.exec() == QDialog::Accepted )
4352 QString fileName = fd.selectedFile();
4353 if ( !fileName.isEmpty() ) {
4354 QFile file( fileName );
4355 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
4358 QTextStream out( &file );
4359 myCtrlInfo->saveInfo( out );
4365 \brief Show documentation on dialog.
4367 void SMESHGUI_CtrlInfoDlg::help()
4369 SMESH::ShowHelpFile( "mesh_infos.html#mesh-quality-info-anchor" );