1 // Copyright (C) 2007-2015 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 "SMDSAbs_ElementType.hxx"
28 #include "SMDS_BallElement.hxx"
29 #include "SMDS_EdgePosition.hxx"
30 #include "SMDS_FacePosition.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_VolumeTool.hxx"
33 #include "SMESHDS_Mesh.hxx"
35 #include "SMESHGUI_FilterUtils.h"
36 #include "SMESHGUI_IdValidator.h"
37 #include "SMESHGUI_SpinBox.h"
38 #include "SMESHGUI_Utils.h"
39 #include "SMESHGUI_VTKUtils.h"
40 #include "SMESH_Actor.h"
42 #include <LightApp_SelectionMgr.h>
43 #include <SUIT_FileDlg.h>
44 #include <SUIT_OverrideCursor.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SVTK_ViewWindow.h>
49 #include <SALOMEDSClient_Study.hxx>
50 #include <SalomeApp_Study.h>
52 #include <QApplication>
53 #include <QButtonGroup>
55 #include <QContextMenuEvent>
56 #include <QGridLayout>
57 #include <QHBoxLayout>
58 #include <QHeaderView>
59 #include <QItemDelegate>
64 #include <QPushButton>
65 #include <QToolButton>
66 #include <QRadioButton>
67 #include <QTextStream>
69 #include <QTextBrowser>
70 #include <QVBoxLayout>
72 #include "utilities.h"
74 #include <SALOMEconfig.h>
75 #include CORBA_SERVER_HEADER(GEOM_Gen)
79 const int SPACING = 6;
81 const int MAXITEMS = 10;
82 const int GROUPS_ID = 100;
83 const int SUBMESHES_ID = 200;
84 const int SPACING_INFO = 2;
87 TypeRole = Qt::UserRole + 10,
92 NodeConnectivity = 100,
101 class ExtraWidget : public QWidget
104 ExtraWidget( QWidget*, bool = false );
107 void updateControls( int, int, int = MAXITEMS );
116 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
118 current = new QLabel( this );
119 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
120 prev = new QPushButton( tr( "<<" ), this );
121 next = new QPushButton( tr( ">>" ), this );
122 QHBoxLayout* hbl = new QHBoxLayout( this );
123 hbl->setContentsMargins( 0, SPACING, 0, 0 );
124 hbl->setSpacing( SPACING );
126 hbl->addWidget( current );
127 hbl->addWidget( prev );
128 hbl->addWidget( next );
131 ExtraWidget::~ExtraWidget()
135 void ExtraWidget::updateControls( int total, int index, int blockSize )
137 setVisible( total > blockSize );
138 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
139 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) );
140 prev->setEnabled( index > 0 );
141 next->setEnabled( (index+1)*blockSize < total );
146 \brief Customization of standard "Save file" dialog box for dump info operation
150 class DumpFileDlg : public SUIT_FileDlg
153 DumpFileDlg( QWidget* parent );
155 QCheckBox* myBaseChk;
156 QCheckBox* myElemChk;
158 QCheckBox* myCtrlChk;
165 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
167 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
169 QWidget* hB = new QWidget( this );
170 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
171 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
172 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
173 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
175 QGridLayout* layout = new QGridLayout( hB );
176 layout->addWidget( myBaseChk, 0, 0 );
177 layout->addWidget( myElemChk, 0, 1 );
178 layout->addWidget( myAddChk, 1, 0 );
179 layout->addWidget( myCtrlChk, 1, 1 );
181 QPushButton* pb = new QPushButton( this );
183 int row = grid->rowCount();
184 grid->addWidget( new QLabel( "", this ), row, 0 );
185 grid->addWidget( hB, row, 1, 1, 3 );
186 grid->addWidget( pb, row, 5 );
193 \brief Get depth of the tree item
195 \param theItem tree widget item
196 \return item's depth in tree widget (where top-level items have zero depth)
198 static int itemDepth( QTreeWidgetItem* item )
201 QTreeWidgetItem* p = item->parent();
210 \class SMESHGUI_MeshInfo
211 \brief Base mesh information widget
213 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
218 \param parent parent widget
220 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
221 : QFrame( parent ), myWidgets( iElementsEnd )
223 setFrameStyle( StyledPanel | Sunken );
225 QGridLayout* l = new QGridLayout( this );
226 l->setMargin( MARGIN );
227 l->setSpacing( SPACING );
232 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
233 QLabel* aName = createField();
234 aName->setMinimumWidth( 150 );
235 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
236 QLabel* aObj = createField();
237 aObj->setMinimumWidth( 150 );
238 myWidgets[ index++ ] << aNameLab << aName;
239 myWidgets[ index++ ] << aObjLab << aObj;
242 QWidget* aNodesLine = createLine();
243 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
244 QLabel* aNodes = createField();
245 myWidgets[ index++ ] << aNodesLine;
246 myWidgets[ index++ ] << aNodesLab << aNodes;
249 QWidget* aElemLine = createLine();
250 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
251 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
252 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
253 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
254 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
255 myWidgets[ index++ ] << aElemLine;
256 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
258 // ... Number elements
259 QWidget* aNbLine = createLine();
260 QLabel* aNbTotal = createField();
261 QLabel* aNbLin = createField();
262 QLabel* aNbQuad = createField();
263 QLabel* aNbBiQuad = createField();
264 myWidgets[ index++ ] << aNbLine;
265 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
268 QWidget* a0DLine = createLine();
269 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
270 QLabel* a0DTotal = createField();
271 myWidgets[ index++ ] << a0DLine;
272 myWidgets[ index++ ] << a0DLab << a0DTotal;
275 QWidget* aBallLine = createLine();
276 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
277 QLabel* aBallTotal = createField();
278 myWidgets[ index++ ] << aBallLine;
279 myWidgets[ index++ ] << aBallLab << aBallTotal;
282 QWidget* a1DLine = createLine();
283 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
284 QLabel* a1DTotal = createField();
285 QLabel* a1DLin = createField();
286 QLabel* a1DQuad = createField();
287 myWidgets[ index++ ] << a1DLine;
288 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
291 QWidget* a2DLine = createLine();
292 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
293 QLabel* a2DTotal = createField();
294 QLabel* a2DLin = createField();
295 QLabel* a2DQuad = createField();
296 QLabel* a2DBiQuad = createField();
297 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
298 QLabel* a2DTriTotal = createField();
299 QLabel* a2DTriLin = createField();
300 QLabel* a2DTriQuad = createField();
301 QLabel* a2DTriBiQuad = createField();
302 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
303 QLabel* a2DQuaTotal = createField();
304 QLabel* a2DQuaLin = createField();
305 QLabel* a2DQuaQuad = createField();
306 QLabel* a2DQuaBiQuad = createField();
307 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
308 QLabel* a2DPolTotal = createField();
309 myWidgets[ index++ ] << a2DLine;
310 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
311 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
312 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
313 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal;
316 QWidget* a3DLine = createLine();
317 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
318 QLabel* a3DTotal = createField();
319 QLabel* a3DLin = createField();
320 QLabel* a3DQuad = createField();
321 QLabel* a3DBiQuad = createField();
322 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
323 QLabel* a3DTetTotal = createField();
324 QLabel* a3DTetLin = createField();
325 QLabel* a3DTetQuad = createField();
326 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
327 QLabel* a3DHexTotal = createField();
328 QLabel* a3DHexLin = createField();
329 QLabel* a3DHexQuad = createField();
330 QLabel* a3DHexBiQuad = createField();
331 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
332 QLabel* a3DPyrTotal = createField();
333 QLabel* a3DPyrLin = createField();
334 QLabel* a3DPyrQuad = createField();
335 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
336 QLabel* a3DPriTotal = createField();
337 QLabel* a3DPriLin = createField();
338 QLabel* a3DPriQuad = createField();
339 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
340 QLabel* a3DHexPriTotal = createField();
341 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
342 QLabel* a3DPolTotal = createField();
343 myWidgets[ index++ ] << a3DLine;
344 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
345 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
346 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
347 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
348 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
349 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
350 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
352 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
353 myLoadBtn->setAutoDefault( true );
354 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
356 setFontAttributes( aNameLab, Bold );
357 setFontAttributes( aObjLab, Bold );
358 setFontAttributes( aNodesLab, Bold );
359 setFontAttributes( aElemLab, Bold );
360 setFontAttributes( aElemTotal, Italic );
361 setFontAttributes( aElemLin, Italic );
362 setFontAttributes( aElemQuad, Italic );
363 setFontAttributes( aElemBiQuad, Italic );
364 setFontAttributes( a0DLab, Bold );
365 setFontAttributes( aBallLab, Bold );
366 setFontAttributes( a1DLab, Bold );
367 setFontAttributes( a2DLab, Bold );
368 setFontAttributes( a3DLab, Bold );
370 l->addWidget( aNameLab, 0, 0 );
371 l->addWidget( aName, 0, 1, 1, 4 );
372 l->addWidget( aObjLab, 1, 0 );
373 l->addWidget( aObj, 1, 1, 1, 4 );
374 l->addWidget( aNodesLine, 2, 0, 1, 5 );
375 l->addWidget( aNodesLab, 3, 0 );
376 l->addWidget( aNodes, 3, 1 );
377 l->addWidget( aElemLine, 4, 0, 1, 5 );
378 l->addWidget( aElemLab, 5, 0 );
379 l->addWidget( aElemTotal, 5, 1 );
380 l->addWidget( aElemLin, 5, 2 );
381 l->addWidget( aElemQuad, 5, 3 );
382 l->addWidget( aElemBiQuad, 5, 4 );
383 l->addWidget( aNbLine, 6, 1, 1, 4 );
384 l->addWidget( aNbTotal, 7, 1 );
385 l->addWidget( aNbLin, 7, 2 );
386 l->addWidget( aNbQuad, 7, 3 );
387 l->addWidget( aNbBiQuad, 7, 4 );
388 l->addWidget( a0DLine, 8, 1, 1, 4 );
389 l->addWidget( a0DLab, 9, 0 );
390 l->addWidget( a0DTotal, 9, 1 );
391 l->addWidget( aBallLine, 10, 1, 1, 4 );
392 l->addWidget( aBallLab, 11, 0 );
393 l->addWidget( aBallTotal, 11, 1 );
394 l->addWidget( a1DLine, 12, 1, 1, 4 );
395 l->addWidget( a1DLab, 13, 0 );
396 l->addWidget( a1DTotal, 13, 1 );
397 l->addWidget( a1DLin, 13, 2 );
398 l->addWidget( a1DQuad, 13, 3 );
399 l->addWidget( a2DLine, 14, 1, 1, 4 );
400 l->addWidget( a2DLab, 15, 0 );
401 l->addWidget( a2DTotal, 15, 1 );
402 l->addWidget( a2DLin, 15, 2 );
403 l->addWidget( a2DQuad, 15, 3 );
404 l->addWidget( a2DBiQuad, 15, 4 );
405 l->addWidget( a2DTriLab, 16, 0 );
406 l->addWidget( a2DTriTotal, 16, 1 );
407 l->addWidget( a2DTriLin, 16, 2 );
408 l->addWidget( a2DTriQuad, 16, 3 );
409 l->addWidget( a2DTriBiQuad, 16, 4 );
410 l->addWidget( a2DQuaLab, 17, 0 );
411 l->addWidget( a2DQuaTotal, 17, 1 );
412 l->addWidget( a2DQuaLin, 17, 2 );
413 l->addWidget( a2DQuaQuad, 17, 3 );
414 l->addWidget( a2DQuaBiQuad, 17, 4 );
415 l->addWidget( a2DPolLab, 18, 0 );
416 l->addWidget( a2DPolTotal, 18, 1 );
417 l->addWidget( a3DLine, 19, 1, 1, 4 );
418 l->addWidget( a3DLab, 20, 0 );
419 l->addWidget( a3DTotal, 20, 1 );
420 l->addWidget( a3DLin, 20, 2 );
421 l->addWidget( a3DQuad, 20, 3 );
422 l->addWidget( a3DBiQuad, 20, 4 );
423 l->addWidget( a3DTetLab, 21, 0 );
424 l->addWidget( a3DTetTotal, 21, 1 );
425 l->addWidget( a3DTetLin, 21, 2 );
426 l->addWidget( a3DTetQuad, 21, 3 );
427 l->addWidget( a3DHexLab, 22, 0 );
428 l->addWidget( a3DHexTotal, 22, 1 );
429 l->addWidget( a3DHexLin, 22, 2 );
430 l->addWidget( a3DHexQuad, 22, 3 );
431 l->addWidget( a3DHexBiQuad, 22, 4 );
432 l->addWidget( a3DPyrLab, 23, 0 );
433 l->addWidget( a3DPyrTotal, 23, 1 );
434 l->addWidget( a3DPyrLin, 23, 2 );
435 l->addWidget( a3DPyrQuad, 23, 3 );
436 l->addWidget( a3DPriLab, 24, 0 );
437 l->addWidget( a3DPriTotal, 24, 1 );
438 l->addWidget( a3DPriLin, 24, 2 );
439 l->addWidget( a3DPriQuad, 24, 3 );
440 l->addWidget( a3DHexPriLab, 25, 0 );
441 l->addWidget( a3DHexPriTotal, 25, 1 );
442 l->addWidget( a3DPolLab, 26, 0 );
443 l->addWidget( a3DPolTotal, 26, 1 );
444 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
446 l->setColumnStretch( 0, 0 );
447 l->setColumnStretch( 1, 5 );
448 l->setColumnStretch( 2, 5 );
449 l->setColumnStretch( 3, 5 );
450 l->setColumnStretch( 4, 5 );
451 l->setRowStretch( 27, 5 );
459 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
464 \brief Show information on the mesh object.
465 \param obj object being processed (mesh, sub-mesh, group, ID source)
467 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
470 if ( !CORBA::is_nil( obj ) ) {
471 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
473 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
474 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
475 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
476 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
477 if ( !aMesh->_is_nil() ) {
478 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
480 else if ( !aSubMesh->_is_nil() ) {
481 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
483 else if ( !aGroup->_is_nil() ) {
485 switch( aGroup->GetType() ) {
486 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
487 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
488 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
489 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
490 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
491 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
492 default: objType = tr( "OBJECT_GROUP" );break;
494 myWidgets[iObject][iSingle]->setProperty( "text", objType );
496 SMESH::long_array_var info = obj->GetMeshInfo();
497 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
498 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
499 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
500 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
501 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
502 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
503 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
504 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
505 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
506 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
507 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle];
508 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
509 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
511 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
512 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
513 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
514 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
515 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
516 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
517 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
518 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
519 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
520 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
521 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
522 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
523 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
524 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
525 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
526 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
527 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
528 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
529 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
530 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
531 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
532 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
533 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
534 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
535 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
536 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
537 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
538 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
539 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
540 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
541 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
542 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
543 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
544 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
545 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
546 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
547 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
548 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
549 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
550 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
551 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
552 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
553 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
554 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
555 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
556 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
557 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
558 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
559 // before full loading from study file, type of elements in a sub-mesh can't be defined
561 bool infoOK = obj->IsMeshInfoCorrect();
562 myLoadBtn->setVisible( !infoOK );
566 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
567 // 2. No info at all (for a group on geom or filter)
568 bool hasAnyInfo = false;
569 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
570 hasAnyInfo = info[i];
571 if ( hasAnyInfo ) // believe it is a sub-mesh
573 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
575 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
576 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
577 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
578 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
579 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
580 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
581 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
582 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
583 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
584 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
585 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
586 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
587 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
588 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
589 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
590 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
592 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
594 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
595 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
596 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
597 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
598 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
599 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
600 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
601 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
602 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
603 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
604 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
605 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
606 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
607 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
608 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
609 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
610 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
611 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
612 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
613 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
614 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
615 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
620 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
621 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
622 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
623 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
624 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
625 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
626 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
627 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
628 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
629 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
630 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
631 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
632 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
633 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
634 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
635 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
636 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
637 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
638 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
639 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
640 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
643 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
644 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
645 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
646 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
647 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
648 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
649 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
650 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
651 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
652 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
653 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
654 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
655 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
656 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
658 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
659 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
660 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
667 \brief Load mesh from a study file
669 void SMESHGUI_MeshInfo::loadMesh()
671 SUIT_OverrideCursor wc;
673 SALOME_ListIO selected;
674 SMESHGUI::selectionMgr()->selectedObjects( selected );
676 if ( selected.Extent() == 1 ) {
677 Handle(SALOME_InteractiveObject) IO = selected.First();
678 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
679 if ( !CORBA::is_nil( obj ) ) {
680 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
681 if ( !mesh->_is_nil() )
691 \brief Reset the widget to the initial state (nullify all fields).
693 void SMESHGUI_MeshInfo::clear()
695 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
696 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
697 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
698 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
699 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
700 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
701 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
702 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
703 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
704 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
705 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
706 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
707 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
708 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
709 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
710 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
711 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
712 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
713 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
714 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
715 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
716 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
717 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
718 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
719 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
720 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
721 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
722 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
723 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
724 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
725 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
726 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
727 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
728 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
729 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
730 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
731 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
732 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
733 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
734 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
735 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
736 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
737 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
738 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
742 \brief Create info field
743 \return new info field
745 QLabel* SMESHGUI_MeshInfo::createField()
747 QLabel* lab = new QLabel( this );
748 lab->setFrameStyle( StyledPanel | Sunken );
749 lab->setAlignment( Qt::AlignCenter );
750 lab->setAutoFillBackground( true );
751 QPalette pal = lab->palette();
752 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
753 lab->setPalette( pal );
754 lab->setMinimumWidth( 70 );
759 \brief Create horizontal rule.
760 \return new line object
762 QWidget* SMESHGUI_MeshInfo::createLine()
764 QFrame* line = new QFrame( this );
765 line->setFrameStyle( HLine | Sunken );
770 \brief Change widget font attributes (bold, italic, ...).
772 \param attr font attributes (XORed flags)
773 \param val value to be set to attributes
775 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
779 if ( attr & Bold ) f.setBold( val );
780 if ( attr & Italic ) f.setItalic( val );
786 \brief Show/hide group(s) of fields.
787 \param start beginning of the block
788 \param end end of the block
789 \param on visibility flag
791 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
793 start = qMax( 0, start );
794 end = qMin( end, (int)iElementsEnd );
795 for ( int i = start; i < end; i++ ) {
796 wlist wl = myWidgets[i];
797 foreach ( QWidget* w, wl ) w->setVisible( on );
801 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
803 out << QString( 9, '-' ) << "\n";
804 out << tr( "BASE_INFO" ) << "\n";
805 out << QString( 9, '-' ) << "\n";
806 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
807 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
808 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
809 out << tr( "ELEMENTS_LAB" ) << "\n";
810 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
811 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
812 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
813 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
814 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
815 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
816 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
817 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
818 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
819 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
820 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
821 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
822 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
823 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
824 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
825 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
826 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
827 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
828 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
829 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
830 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
831 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
832 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
833 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
834 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
835 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
836 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
837 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
838 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
839 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
840 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
841 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
842 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
843 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
844 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
845 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
846 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
847 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
848 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
849 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
850 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
851 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
852 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
853 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
854 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
855 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
856 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
857 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
858 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
859 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
860 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
861 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
862 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
863 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
864 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
868 \class SMESHGUI_ElemInfo
869 \brief Base class for the mesh element information widget.
874 \param parent parent widget
876 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
877 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
879 myFrame = new QWidget( this );
880 myExtra = new ExtraWidget( this );
881 QVBoxLayout* vbl = new QVBoxLayout( this );
883 vbl->setSpacing( 0 );
884 vbl->addWidget( myFrame );
885 vbl->addWidget( myExtra );
886 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
887 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
894 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
899 \brief Set mesh data source (actor)
900 \param actor mesh object actor
902 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
904 if ( myActor != actor ) {
912 \brief Show mesh element information
913 \param id mesh node / element ID
914 \param isElem show mesh element information if \c true or mesh node information if \c false
916 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
920 showInfo( ids, isElem );
924 \brief Show mesh element information
925 \param ids mesh nodes / elements identifiers
926 \param isElem show mesh element information if \c true or mesh node information if \c false
928 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
930 QList<long> newIds = ids.toList();
932 if ( myIDs == newIds && myIsElement == isElem ) return;
935 myIsElement = isElem;
938 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
942 \brief Clear mesh element information widget
944 void SMESHGUI_ElemInfo::clear()
953 \brief Get central area widget
954 \return central widget
956 QWidget* SMESHGUI_ElemInfo::frame() const
963 \return actor being used
965 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
971 \brief Get current info mode.
972 \return \c true if mesh element information is shown or \c false if node information is shown
974 bool SMESHGUI_ElemInfo::isElements() const
980 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
981 \brief Show information on the specified nodes / elements
983 This function is to be redefined in sub-classes.
985 \param ids nodes / elements identifiers information is to be shown on
989 \brief Internal clean-up (reset widget)
991 void SMESHGUI_ElemInfo::clearInternal()
996 \brief Get node connectivity
997 \param node mesh node
998 \return node connectivity map
1000 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1004 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1005 while ( it && it->more() ) {
1006 const SMDS_MeshElement* ne = it->next();
1007 elmap[ ne->GetType() ] << ne->GetID();
1014 \brief Format connectivity data to string representation
1015 \param connectivity connetivity map
1016 \param type element type
1017 \return string representation of the connectivity
1019 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1022 if ( connectivity.contains( type ) ) {
1023 QList<int> elements = connectivity[ type ];
1025 foreach( int id, elements )
1026 str << QString::number( id );
1028 return str.join( " " );
1032 \brief Calculate gravity center of the mesh element
1033 \param element mesh element
1035 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1039 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1040 while ( nodeIt->more() ) {
1041 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1042 xyz.add( node->X(), node->Y(), node->Z() );
1044 xyz.divide( element->NbNodes() );
1050 \brief Calculate normal vector to the mesh face
1051 \param element mesh face
1053 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1055 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1056 return XYZ(n.X(), n.Y(), n.Z());
1060 \brief This slot is called from "Show Previous" button click.
1061 Shows information on the previous group of the items.
1063 void SMESHGUI_ElemInfo::showPrevious()
1065 myIndex = qMax( 0, myIndex-1 );
1067 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1071 \brief This slot is called from "Show Next" button click.
1072 Shows information on the next group of the items.
1074 void SMESHGUI_ElemInfo::showNext()
1076 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1078 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1082 \brief Update widgets state
1084 void SMESHGUI_ElemInfo::updateControls()
1086 myExtra->updateControls( myIDs.count(), myIndex );
1090 \class SMESHGUI_SimpleElemInfo
1091 \brief Represents mesh element information in the simple text area.
1096 \param parent parent widget
1098 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1099 : SMESHGUI_ElemInfo( parent )
1101 myInfo = new QTextBrowser( frame() );
1102 QVBoxLayout* l = new QVBoxLayout( frame() );
1104 l->addWidget( myInfo );
1108 \brief Show mesh element information
1109 \param ids mesh nodes / elements identifiers
1111 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1116 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1117 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1118 int cprecision = -1;
1119 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1120 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1121 foreach ( long id, ids ) {
1122 if ( !isElements() ) {
1126 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1127 if ( !node ) return;
1130 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1132 myInfo->append( "" );
1134 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1135 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1136 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1137 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1139 myInfo->append( "" );
1141 Connectivity connectivity = nodeConnectivity( node );
1142 if ( !connectivity.isEmpty() ) {
1143 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1144 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1145 if ( !con.isEmpty() )
1146 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1147 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1148 if ( !con.isEmpty() )
1149 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1150 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1151 if ( !con.isEmpty() )
1152 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1153 con = formatConnectivity( connectivity, SMDSAbs_Face );
1154 if ( !con.isEmpty() )
1155 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1156 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1157 if ( !con.isEmpty() )
1158 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1161 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1164 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1165 if ( !CORBA::is_nil( aMeshPtr ) ) {
1166 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1167 int shapeID = pos->shapeID;
1168 if ( shapeID > 0 ) {
1171 switch ( pos->shapeType ) {
1173 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1174 if ( pos->params.length() == 1 )
1178 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1179 if ( pos->params.length() == 2 ) {
1185 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1188 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1192 myInfo->append( "" );
1193 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1194 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1195 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1196 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1197 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1198 if ( pos->shapeType == GEOM::FACE ) {
1199 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1200 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1205 // groups node belongs to
1206 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1207 if ( !CORBA::is_nil( aMesh ) ) {
1208 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1209 myInfo->append( "" ); // separator
1210 bool top_created = false;
1211 for ( int i = 0; i < groups->length(); i++ ) {
1212 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1213 if ( CORBA::is_nil( aGrp ) ) continue;
1214 QString aName = aGrp->GetName();
1215 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1216 if ( !top_created ) {
1217 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1220 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1221 if ( grp_details ) {
1222 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1223 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1224 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1226 // type : group on geometry, standalone group, group on filter
1227 if ( !CORBA::is_nil( aStdGroup ) ) {
1228 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1229 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1231 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1232 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1233 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1234 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1235 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1237 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1238 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1241 else if ( !CORBA::is_nil( aFltGroup ) ) {
1242 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1243 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1247 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1248 arg( QString::number( aGrp->Size() ) ) );
1251 SALOMEDS::Color color = aGrp->GetColor();
1252 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1253 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1261 // show element info
1263 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1264 SMESH::Controls::NumericalFunctorPtr afunctor;
1267 // Element ID && Type
1269 switch( e->GetType() ) {
1270 case SMDSAbs_0DElement:
1271 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1273 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1275 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1277 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1278 case SMDSAbs_Volume:
1279 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1283 if ( stype.isEmpty() ) return;
1284 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1286 myInfo->append( "" );
1290 switch( e->GetEntityType() ) {
1291 case SMDSEntity_Triangle:
1292 case SMDSEntity_Quad_Triangle:
1293 case SMDSEntity_BiQuad_Triangle:
1294 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1295 case SMDSEntity_Quadrangle:
1296 case SMDSEntity_Quad_Quadrangle:
1297 case SMDSEntity_BiQuad_Quadrangle:
1298 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1299 case SMDSEntity_Polygon:
1300 case SMDSEntity_Quad_Polygon:
1301 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1302 case SMDSEntity_Tetra:
1303 case SMDSEntity_Quad_Tetra:
1304 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1305 case SMDSEntity_Pyramid:
1306 case SMDSEntity_Quad_Pyramid:
1307 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1308 case SMDSEntity_Hexa:
1309 case SMDSEntity_Quad_Hexa:
1310 case SMDSEntity_TriQuad_Hexa:
1311 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1312 case SMDSEntity_Penta:
1313 case SMDSEntity_Quad_Penta:
1314 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1315 case SMDSEntity_Hexagonal_Prism:
1316 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1317 case SMDSEntity_Polyhedra:
1318 case SMDSEntity_Quad_Polyhedra:
1319 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1323 if ( !gtype.isEmpty() )
1324 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1326 // Quadratic flag (any element except 0D)
1327 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1328 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1330 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1332 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1335 myInfo->append( "" );
1338 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1339 for ( int idx = 1; nodeIt->more(); idx++ ) {
1340 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1341 // node number and ID
1342 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1344 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1345 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1346 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1347 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1348 // node connectivity
1349 Connectivity connectivity = nodeConnectivity( node );
1350 if ( !connectivity.isEmpty() ) {
1351 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1352 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1353 if ( !con.isEmpty() )
1354 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1355 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1356 if ( !con.isEmpty() )
1357 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1358 con = formatConnectivity( connectivity, SMDSAbs_Face );
1359 if ( !con.isEmpty() )
1360 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1361 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1362 if ( !con.isEmpty() )
1363 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1366 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1370 myInfo->append( "" );
1373 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1375 if ( e->GetType() == SMDSAbs_Edge ) {
1376 afunctor.reset( new SMESH::Controls::Length() );
1377 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1378 afunctor->SetPrecision( cprecision );
1379 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1381 if( e->GetType() == SMDSAbs_Face ) {
1383 afunctor.reset( new SMESH::Controls::Area() );
1384 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1385 afunctor->SetPrecision( cprecision );
1386 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1388 afunctor.reset( new SMESH::Controls::Taper() );
1389 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1390 afunctor->SetPrecision( cprecision );
1391 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1393 afunctor.reset( new SMESH::Controls::AspectRatio() );
1394 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1395 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1397 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1398 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1399 afunctor->SetPrecision( cprecision );
1400 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1402 afunctor.reset( new SMESH::Controls::Warping() );
1403 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1404 afunctor->SetPrecision( cprecision );
1405 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1407 afunctor.reset( new SMESH::Controls::Skew() );
1408 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1409 afunctor->SetPrecision( cprecision );
1410 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1412 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1413 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1414 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1416 if( e->GetType() == SMDSAbs_Volume ) {
1418 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1419 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1420 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1422 afunctor.reset( new SMESH::Controls::Volume() );
1423 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1424 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1426 afunctor.reset( new SMESH::Controls::Volume() );
1427 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1428 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1431 myInfo->append( "" );
1434 XYZ gc = gravityCenter( e );
1435 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1438 if( e->GetType() == SMDSAbs_Face ) {
1439 XYZ gc = normal( e );
1440 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1444 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1445 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1446 if ( !CORBA::is_nil( aMesh ) ) {
1447 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1448 int shapeID = pos.shapeID;
1449 if ( shapeID > 0 ) {
1450 myInfo->append( "" ); // separator
1452 switch ( pos.shapeType ) {
1453 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1454 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1455 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1456 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1457 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1458 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1460 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1465 // Groups the element belongs to
1466 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1467 if ( !CORBA::is_nil( aMesh ) ) {
1468 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1469 myInfo->append( "" ); // separator
1470 bool top_created = false;
1471 for ( int i = 0; i < groups->length(); i++ ) {
1472 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1473 if ( CORBA::is_nil( aGrp ) ) continue;
1474 QString aName = aGrp->GetName();
1475 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1476 if ( !top_created ) {
1477 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1480 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1481 if ( grp_details ) {
1482 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1483 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1484 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1486 // type : group on geometry, standalone group, group on filter
1487 if ( !CORBA::is_nil( aStdGroup ) ) {
1488 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1489 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1491 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1492 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1493 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1494 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1495 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1497 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1498 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1501 else if ( !CORBA::is_nil( aFltGroup ) ) {
1502 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1503 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1506 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1507 arg( QString::number( aGrp->Size() ) ) );
1510 SALOMEDS::Color color = aGrp->GetColor();
1511 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1512 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1519 if ( ids.count() > 1 ) {
1520 myInfo->append( "" );
1521 myInfo->append( "------" );
1522 myInfo->append( "" );
1529 \brief Internal clean-up (reset widget)
1531 void SMESHGUI_SimpleElemInfo::clearInternal()
1536 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1538 out << QString( 12, '-' ) << "\n";
1539 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1540 out << QString( 12, '-' ) << "\n";
1541 out << myInfo->toPlainText();
1547 \class SMESHGUI_TreeElemInfo::ItemDelegate
1548 \brief Item delegate for tree mesh info widget
1551 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1554 ItemDelegate( QObject* );
1555 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1562 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1567 \brief Create item editor widget
1570 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1572 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1573 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1578 \class SMESHGUI_TreeElemInfo
1579 \brief Represents mesh element information in the tree-like form.
1584 \param parent parent widget
1586 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1587 : SMESHGUI_ElemInfo( parent )
1589 myInfo = new QTreeWidget( frame() );
1590 myInfo->setColumnCount( 2 );
1591 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1592 myInfo->header()->setStretchLastSection( true );
1593 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1594 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1595 QVBoxLayout* l = new QVBoxLayout( frame() );
1597 l->addWidget( myInfo );
1598 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1602 \brief Show mesh element information
1603 \param ids mesh nodes / elements identifiers
1605 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1610 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1611 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1612 int cprecision = -1;
1613 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1614 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1615 foreach ( long id, ids ) {
1616 if ( !isElements() ) {
1620 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1622 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1625 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1626 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1627 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1629 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1630 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1631 QTreeWidgetItem* xItem = createItem( coordItem );
1632 xItem->setText( 0, "X" );
1633 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1634 QTreeWidgetItem* yItem = createItem( coordItem );
1635 yItem->setText( 0, "Y" );
1636 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1637 QTreeWidgetItem* zItem = createItem( coordItem );
1638 zItem->setText( 0, "Z" );
1639 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1641 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1642 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1643 Connectivity connectivity = nodeConnectivity( node );
1644 if ( !connectivity.isEmpty() ) {
1645 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1646 if ( !con.isEmpty() ) {
1647 QTreeWidgetItem* i = createItem( conItem );
1648 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1649 i->setText( 1, con );
1651 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1652 if ( !con.isEmpty() ) {
1653 QTreeWidgetItem* i = createItem( conItem );
1654 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1655 i->setText( 1, con );
1656 i->setData( 1, TypeRole, NodeConnectivity );
1658 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1659 if ( !con.isEmpty() ) {
1660 QTreeWidgetItem* i = createItem( conItem );
1661 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1662 i->setText( 1, con );
1663 i->setData( 1, TypeRole, NodeConnectivity );
1665 con = formatConnectivity( connectivity, SMDSAbs_Face );
1666 if ( !con.isEmpty() ) {
1667 QTreeWidgetItem* i = createItem( conItem );
1668 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1669 i->setText( 1, con );
1670 i->setData( 1, TypeRole, NodeConnectivity );
1672 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1673 if ( !con.isEmpty() ) {
1674 QTreeWidgetItem* i = createItem( conItem );
1675 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1676 i->setText( 1, con );
1677 i->setData( 1, TypeRole, NodeConnectivity );
1681 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1684 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1685 if ( !CORBA::is_nil( aMeshPtr ) ) {
1686 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1687 int shapeID = pos->shapeID;
1688 if ( shapeID > 0 ) {
1691 switch ( pos->shapeType ) {
1693 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1694 if ( pos->params.length() == 1 )
1698 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1699 if ( pos->params.length() == 2 ) {
1705 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1708 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1711 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1712 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1713 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1714 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1715 QTreeWidgetItem* uItem = createItem( posItem );
1716 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1717 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1718 if ( pos->shapeType == GEOM::FACE ) {
1719 QTreeWidgetItem* vItem = createItem( posItem );
1720 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1721 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1726 // groups node belongs to
1727 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1728 if ( !CORBA::is_nil( aMesh ) ) {
1729 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1730 QTreeWidgetItem* groupsItem = 0;
1731 for ( int i = 0; i < groups->length(); i++ ) {
1732 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1733 if ( CORBA::is_nil( aGrp ) ) continue;
1734 QString aName = aGrp->GetName();
1735 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1736 if ( !groupsItem ) {
1737 groupsItem = createItem( nodeItem, Bold );
1738 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1740 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1741 it->setText( 0, aName.trimmed() );
1742 if ( grp_details ) {
1743 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1744 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1745 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1747 // type : group on geometry, standalone group, group on filter
1748 QTreeWidgetItem* typeItem = createItem( it );
1749 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1750 if ( !CORBA::is_nil( aStdGroup ) ) {
1751 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1753 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1754 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1755 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1756 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1758 QTreeWidgetItem* gobjItem = createItem( typeItem );
1759 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1760 gobjItem->setText( 1, sobj->GetName().c_str() );
1763 else if ( !CORBA::is_nil( aFltGroup ) ) {
1764 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1768 QTreeWidgetItem* sizeItem = createItem( it );
1769 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1770 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1773 SALOMEDS::Color color = aGrp->GetColor();
1774 QTreeWidgetItem* colorItem = createItem( it );
1775 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1776 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1784 // show element info
1786 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1787 SMESH::Controls::NumericalFunctorPtr afunctor;
1790 // element ID && type
1792 switch( e->GetType() ) {
1793 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1794 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1795 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1796 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1797 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1800 if ( stype.isEmpty() ) return;
1801 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1802 elemItem->setText( 0, stype );
1803 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1806 switch( e->GetEntityType() ) {
1807 case SMDSEntity_Triangle:
1808 case SMDSEntity_Quad_Triangle:
1809 case SMDSEntity_BiQuad_Triangle:
1810 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1811 case SMDSEntity_Quadrangle:
1812 case SMDSEntity_Quad_Quadrangle:
1813 case SMDSEntity_BiQuad_Quadrangle:
1814 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1815 case SMDSEntity_Polygon:
1816 case SMDSEntity_Quad_Polygon:
1817 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1818 case SMDSEntity_Tetra:
1819 case SMDSEntity_Quad_Tetra:
1820 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1821 case SMDSEntity_Pyramid:
1822 case SMDSEntity_Quad_Pyramid:
1823 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1824 case SMDSEntity_Hexa:
1825 case SMDSEntity_Quad_Hexa:
1826 case SMDSEntity_TriQuad_Hexa:
1827 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1828 case SMDSEntity_Penta:
1829 case SMDSEntity_Quad_Penta:
1830 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1831 case SMDSEntity_Hexagonal_Prism:
1832 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1833 case SMDSEntity_Polyhedra:
1834 case SMDSEntity_Quad_Polyhedra:
1835 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1839 if ( !gtype.isEmpty() ) {
1840 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1841 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1842 typeItem->setText( 1, gtype );
1844 // quadratic flag (for edges, faces and volumes)
1845 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1847 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1848 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1849 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1851 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1853 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1854 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1855 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1858 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1859 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1862 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1863 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1864 for ( int idx = 1; nodeIt->more(); idx++ ) {
1865 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1866 nodeInfo( node, idx, e->NbNodes(), conItem );
1870 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1871 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1872 QList<const SMDS_MeshElement*> uniqueNodes;
1873 while ( nodeIt->more() )
1874 uniqueNodes.append( nodeIt->next() );
1876 SMDS_VolumeTool vtool( e );
1877 const int nbFaces = vtool.NbFaces();
1878 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1879 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1880 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1881 faceItem->setExpanded( true );
1883 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1884 const int nbNodes = vtool.NbFaceNodes( face_id );
1885 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1886 const SMDS_MeshNode* node = aNodeIds[node_id];
1887 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1892 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1893 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1895 if( e->GetType()==SMDSAbs_Edge){
1896 afunctor.reset( new SMESH::Controls::Length() );
1897 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1898 afunctor->SetPrecision( cprecision );
1899 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1900 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1901 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1903 if( e->GetType() == SMDSAbs_Face ) {
1905 afunctor.reset( new SMESH::Controls::Area() );
1906 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1907 afunctor->SetPrecision( cprecision );
1908 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1909 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1910 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1912 afunctor.reset( new SMESH::Controls::Taper() );
1913 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1914 afunctor->SetPrecision( cprecision );
1915 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1916 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1917 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1919 afunctor.reset( new SMESH::Controls::AspectRatio() );
1920 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1921 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1922 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1923 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1925 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1926 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1927 afunctor->SetPrecision( cprecision );
1928 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
1929 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
1930 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1932 afunctor.reset( new SMESH::Controls::Warping() );
1933 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1934 afunctor->SetPrecision( cprecision );
1935 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1936 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1937 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1939 afunctor.reset( new SMESH::Controls::Skew() );
1940 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1941 afunctor->SetPrecision( cprecision );
1942 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
1943 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
1944 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1946 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1947 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1948 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
1949 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
1950 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1952 if( e->GetType() == SMDSAbs_Volume ) {
1954 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1955 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1956 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
1957 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
1958 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1960 afunctor.reset( new SMESH::Controls::Volume() );
1961 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1962 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
1963 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
1964 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1966 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
1967 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1968 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
1969 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
1970 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1974 XYZ gc = gravityCenter( e );
1975 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
1976 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
1977 QTreeWidgetItem* xItem = createItem( gcItem );
1978 xItem->setText( 0, "X" );
1979 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1980 QTreeWidgetItem* yItem = createItem( gcItem );
1981 yItem->setText( 0, "Y" );
1982 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1983 QTreeWidgetItem* zItem = createItem( gcItem );
1984 zItem->setText( 0, "Z" );
1985 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1988 if( e->GetType() == SMDSAbs_Face ) {
1989 XYZ gc = normal( e );
1990 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
1991 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
1992 QTreeWidgetItem* xItem = createItem( nItem );
1993 xItem->setText( 0, "X" );
1994 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1995 QTreeWidgetItem* yItem = createItem( nItem );
1996 yItem->setText( 0, "Y" );
1997 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1998 QTreeWidgetItem* zItem = createItem( nItem );
1999 zItem->setText( 0, "Z" );
2000 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2004 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2005 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2006 if ( !CORBA::is_nil( aMesh ) ) {
2007 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2008 int shapeID = pos.shapeID;
2009 if ( shapeID > 0 ) {
2010 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2012 switch ( pos.shapeType ) {
2013 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2014 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2015 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2016 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2017 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2018 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2020 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2021 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2025 // groups element belongs to
2026 if ( !CORBA::is_nil( aMesh ) ) {
2027 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2028 QTreeWidgetItem* groupsItem = 0;
2029 for ( int i = 0; i < groups->length(); i++ ) {
2030 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2031 if ( CORBA::is_nil( aGrp ) ) continue;
2032 QString aName = aGrp->GetName();
2033 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2034 if ( !groupsItem ) {
2035 groupsItem = createItem( elemItem, Bold );
2036 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2038 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2039 it->setText( 0, aName.trimmed() );
2040 if ( grp_details ) {
2041 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2042 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2043 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2045 // type : group on geometry, standalone group, group on filter
2046 QTreeWidgetItem* typeItem = createItem( it );
2047 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2048 if ( !CORBA::is_nil( aStdGroup ) ) {
2049 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2051 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2052 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2053 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2054 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2056 QTreeWidgetItem* gobjItem = createItem( typeItem );
2057 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2058 gobjItem->setText( 1, sobj->GetName().c_str() );
2061 else if ( !CORBA::is_nil( aFltGroup ) ) {
2062 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2066 QTreeWidgetItem* sizeItem = createItem( it );
2067 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2068 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2071 SALOMEDS::Color color = aGrp->GetColor();
2072 QTreeWidgetItem* colorItem = createItem( it );
2073 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2074 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2085 \brief Show node information
2086 \param node mesh node for showing
2087 \param index index of current node
2088 \param nbNodes number of unique nodes in element
2089 \param parentItem parent item of tree
2091 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2092 int nbNodes, QTreeWidgetItem* parentItem )
2094 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2095 // node number and ID
2096 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2097 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2098 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2099 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2100 nodeItem->setData( 1, IdRole, node->GetID() );
2101 nodeItem->setExpanded( false );
2103 QTreeWidgetItem* coordItem = createItem( nodeItem );
2104 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2105 QTreeWidgetItem* xItem = createItem( coordItem );
2106 xItem->setText( 0, "X" );
2107 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2108 QTreeWidgetItem* yItem = createItem( coordItem );
2109 yItem->setText( 0, "Y" );
2110 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2111 QTreeWidgetItem* zItem = createItem( coordItem );
2112 zItem->setText( 0, "Z" );
2113 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2114 // node connectivity
2115 QTreeWidgetItem* nconItem = createItem( nodeItem );
2116 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2117 Connectivity connectivity = nodeConnectivity( node );
2118 if ( !connectivity.isEmpty() ) {
2119 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2120 if ( !con.isEmpty() ) {
2121 QTreeWidgetItem* i = createItem( nconItem );
2122 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2123 i->setText( 1, con );
2125 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2126 if ( !con.isEmpty() ) {
2127 QTreeWidgetItem* i = createItem( nconItem );
2128 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2129 i->setText( 1, con );
2130 i->setData( 1, TypeRole, NodeConnectivity );
2132 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2133 if ( !con.isEmpty() ) {
2134 QTreeWidgetItem* i = createItem( nconItem );
2135 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2136 i->setText( 1, con );
2137 i->setData( 1, TypeRole, NodeConnectivity );
2139 con = formatConnectivity( connectivity, SMDSAbs_Face );
2140 if ( !con.isEmpty() ) {
2141 QTreeWidgetItem* i = createItem( nconItem );
2142 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2143 i->setText( 1, con );
2144 i->setData( 1, TypeRole, NodeConnectivity );
2146 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2147 if ( !con.isEmpty() ) {
2148 QTreeWidgetItem* i = createItem( nconItem );
2149 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2150 i->setText( 1, con );
2151 i->setData( 1, TypeRole, NodeConnectivity );
2156 \brief Internal clean-up (reset widget)
2158 void SMESHGUI_TreeElemInfo::clearInternal()
2165 \brief Create new tree item.
2166 \param parent parent tree widget item
2167 \param flags item flag
2168 \return new tree widget item
2170 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2172 QTreeWidgetItem* item;
2174 item = new QTreeWidgetItem( parent );
2176 item = new QTreeWidgetItem( myInfo );
2178 item->setFlags( item->flags() | Qt::ItemIsEditable );
2180 QFont f = item->font( 0 );
2182 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2183 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2184 item->setFont( i, f );
2187 item->setExpanded( true );
2191 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2193 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2194 if ( widgets.isEmpty() ) return;
2195 QTreeWidgetItem* aTreeItem = widgets.first();
2196 int type = aTreeItem->data( 1, TypeRole ).toInt();
2197 int id = aTreeItem->data( 1, IdRole ).toInt();
2199 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2200 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2201 emit( itemInfo( id ) );
2202 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2203 emit( itemInfo( aTreeItem->text( 1 ) ) );
2206 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2209 int type = theItem->data( 1, TypeRole ).toInt();
2210 int id = theItem->data( 1, IdRole ).toInt();
2211 if ( type == ElemConnectivity && id > 0 )
2212 emit( itemInfo( id ) );
2213 else if ( type == NodeConnectivity )
2214 emit( itemInfo( theItem->text( 1 ) ) );
2218 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2220 out << QString( 12, '-' ) << "\n";
2221 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2222 out << QString( 12, '-' ) << "\n";
2224 QTreeWidgetItemIterator it( myInfo );
2226 if ( !( *it )->text(0).isEmpty() ) {
2227 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2228 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2238 \brief Mesh information computer
2241 The class is created for different computation operation. Currently it is used
2242 to compute number of underlying nodes for the groups.
2248 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* item, QObject* parent )
2249 : QObject( parent ), myItem( item )
2251 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2255 \brief Compute function
2257 void GrpComputor::compute()
2259 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2260 QTreeWidgetItem* item = myItem;
2262 int nbNodes = myGroup->GetNumberOfNodes();
2263 item->treeWidget()->removeItemWidget( item, 1 );
2264 item->setText( 1, QString::number( nbNodes ));
2269 \class SMESHGUI_AddInfo
2270 \brief The wigdet shows additional information on the mesh object.
2275 \param parent parent widget
2277 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2278 : QTreeWidget( parent )
2280 setColumnCount( 2 );
2281 header()->setStretchLastSection( true );
2282 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2289 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2294 \brief Show additional information on the selected object
2295 \param obj object being processed (mesh, sub-mesh, group, ID source)
2297 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2299 setProperty( "group_index", 0 );
2300 setProperty( "submesh_index", 0 );
2301 myComputors.clear();
2304 if ( CORBA::is_nil( obj ) ) return;
2306 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2307 if ( !sobj ) return;
2310 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2311 nameItem->setText( 0, tr( "NAME" ) );
2312 nameItem->setText( 1, sobj->GetName().c_str() );
2314 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2315 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2316 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2318 if ( !aMesh->_is_nil() )
2319 meshInfo( aMesh, nameItem );
2320 else if ( !aSubMesh->_is_nil() )
2321 subMeshInfo( aSubMesh, nameItem );
2322 else if ( !aGroup->_is_nil() )
2323 groupInfo( aGroup.in(), nameItem );
2327 \brief Create new tree item.
2328 \param parent parent tree widget item
2329 \param flags item flag
2330 \return new tree widget item
2332 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2334 QTreeWidgetItem* item;
2337 item = new QTreeWidgetItem( parent );
2339 item = new QTreeWidgetItem( this );
2341 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2343 QFont f = item->font( 0 );
2345 for ( int i = 0; i < columnCount(); i++ ) {
2346 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2347 item->setFont( i, f );
2350 item->setExpanded( true );
2355 \brief Show mesh info
2356 \param mesh mesh object
2357 \param parent parent tree item
2359 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2362 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2363 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2364 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2365 typeItem->setText( 0, tr( "TYPE" ) );
2366 if ( !CORBA::is_nil( shape ) ) {
2367 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2368 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2370 QTreeWidgetItem* gobjItem = createItem( typeItem );
2371 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2372 gobjItem->setText( 1, sobj->GetName().c_str() );
2375 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2376 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2377 QTreeWidgetItem* fileItem = createItem( typeItem );
2378 fileItem->setText( 0, tr( "FILE_NAME" ) );
2379 fileItem->setText( 1, (char*)inf->fileName );
2382 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2386 myGroups = mesh->GetGroups();
2390 mySubMeshes = mesh->GetSubMeshes();
2395 \brief Show sub-mesh info
2396 \param subMesh sub-mesh object
2397 \param parent parent tree item
2399 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2401 bool isShort = parent->parent() != 0;
2405 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2407 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2408 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2409 nameItem->setText( 1, sobj->GetName().c_str() );
2414 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2415 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2417 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2418 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2419 gobjItem->setText( 1, sobj->GetName().c_str() );
2424 \brief Show group info
2425 \param grp mesh group object
2426 \param parent parent tree item
2428 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2430 bool isShort = parent->parent() != 0;
2432 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2433 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2434 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2438 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2440 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2441 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2442 nameItem->setText( 1, sobj->GetName().c_str() );
2446 // type : group on geometry, standalone group, group on filter
2447 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2448 typeItem->setText( 0, tr( "TYPE" ) );
2449 if ( !CORBA::is_nil( aStdGroup ) ) {
2450 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2452 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2453 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2454 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2455 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2457 QTreeWidgetItem* gobjItem = createItem( typeItem );
2458 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2459 gobjItem->setText( 1, sobj->GetName().c_str() );
2462 else if ( !CORBA::is_nil( aFltGroup ) ) {
2463 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2468 QString etype = tr( "UNKNOWN" );
2469 switch( grp->GetType() ) {
2471 etype = tr( "NODE" );
2474 etype = tr( "EDGE" );
2477 etype = tr( "FACE" );
2480 etype = tr( "VOLUME" );
2483 etype = tr( "0DELEM" );
2486 etype = tr( "BALL" );
2491 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2492 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2493 etypeItem->setText( 1, etype );
2497 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2498 sizeItem->setText( 0, tr( "SIZE" ) );
2499 sizeItem->setText( 1, QString::number( grp->Size() ) );
2502 SALOMEDS::Color color = grp->GetColor();
2503 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2504 colorItem->setText( 0, tr( "COLOR" ) );
2505 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2507 // nb of underlying nodes
2508 if ( grp->GetType() != SMESH::NODE) {
2509 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2510 nodesItem->setText( 0, tr( "NB_NODES" ) );
2511 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2512 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2513 bool meshLoaded = mesh->IsLoaded();
2514 bool toShowNodes = ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || grp->Size() <= nbNodesLimit );
2515 if ( toShowNodes && meshLoaded ) {
2516 // already calculated and up-to-date
2517 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2520 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2521 setItemWidget( nodesItem, 1, btn );
2522 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2523 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2524 myComputors.append( comp );
2526 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2531 void SMESHGUI_AddInfo::showGroups()
2533 myComputors.clear();
2535 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2536 if ( !parent ) return;
2538 int idx = property( "group_index" ).toInt();
2540 QTreeWidgetItem* itemGroups = 0;
2541 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2542 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2543 itemGroups = parent->child( i );
2544 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2546 extra->updateControls( myGroups->length(), idx );
2547 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2551 QMap<int, QTreeWidgetItem*> grpItems;
2552 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2553 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2554 if ( CORBA::is_nil( grp ) ) continue;
2555 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2556 if ( !grpSObj ) continue;
2558 int grpType = grp->GetType();
2560 if ( !itemGroups ) {
2561 // create top-level groups container item
2562 itemGroups = createItem( parent, Bold | All );
2563 itemGroups->setText( 0, tr( "GROUPS" ) );
2564 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2566 // total number of groups > 10, show extra widgets for info browsing
2567 if ( myGroups->length() > MAXITEMS ) {
2568 ExtraWidget* extra = new ExtraWidget( this, true );
2569 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2570 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2571 setItemWidget( itemGroups, 1, extra );
2572 extra->updateControls( myGroups->length(), idx );
2576 if ( grpItems.find( grpType ) == grpItems.end() ) {
2577 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2578 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2579 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2583 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2584 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2587 groupInfo( grp.in(), grpNameItem );
2591 void SMESHGUI_AddInfo::showSubMeshes()
2593 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2594 if ( !parent ) return;
2596 int idx = property( "submesh_index" ).toInt();
2598 QTreeWidgetItem* itemSubMeshes = 0;
2599 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2600 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2601 itemSubMeshes = parent->child( i );
2602 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2604 extra->updateControls( mySubMeshes->length(), idx );
2605 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2609 QMap<int, QTreeWidgetItem*> smItems;
2610 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2611 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2612 if ( CORBA::is_nil( sm ) ) continue;
2613 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2614 if ( !smSObj ) continue;
2616 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2617 if ( CORBA::is_nil(gobj ) ) continue;
2619 int smType = gobj->GetShapeType();
2620 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2622 if ( !itemSubMeshes ) {
2623 itemSubMeshes = createItem( parent, Bold | All );
2624 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2625 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2627 // total number of sub-meshes > 10, show extra widgets for info browsing
2628 if ( mySubMeshes->length() > MAXITEMS ) {
2629 ExtraWidget* extra = new ExtraWidget( this, true );
2630 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2631 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2632 setItemWidget( itemSubMeshes, 1, extra );
2633 extra->updateControls( mySubMeshes->length(), idx );
2637 if ( smItems.find( smType ) == smItems.end() ) {
2638 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2639 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2640 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2644 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2645 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2648 subMeshInfo( sm.in(), smNameItem );
2653 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2655 void SMESHGUI_AddInfo::changeLoadToCompute()
2657 for ( int i = 0; i < myComputors.count(); ++i )
2659 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2661 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2662 btn->setText( tr("COMPUTE") );
2667 void SMESHGUI_AddInfo::showPreviousGroups()
2669 int idx = property( "group_index" ).toInt();
2670 setProperty( "group_index", idx-1 );
2674 void SMESHGUI_AddInfo::showNextGroups()
2676 int idx = property( "group_index" ).toInt();
2677 setProperty( "group_index", idx+1 );
2681 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2683 int idx = property( "submesh_index" ).toInt();
2684 setProperty( "submesh_index", idx-1 );
2688 void SMESHGUI_AddInfo::showNextSubMeshes()
2690 int idx = property( "submesh_index" ).toInt();
2691 setProperty( "submesh_index", idx+1 );
2695 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2697 out << QString( 15, '-') << "\n";
2698 out << tr( "ADDITIONAL_INFO" ) << "\n";
2699 out << QString( 15, '-' ) << "\n";
2700 QTreeWidgetItemIterator it( this );
2702 if ( !( ( *it )->text(0) ).isEmpty() ) {
2703 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2704 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2705 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2707 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2716 \class SMESHGUI_MeshInfoDlg
2717 \brief Mesh information dialog box
2722 \param parent parent widget
2723 \param page specifies the dialog page to be shown at the start-up
2725 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2726 : QDialog( parent ), myActor( 0 )
2729 setAttribute( Qt::WA_DeleteOnClose, true );
2730 setWindowTitle( tr( "MESH_INFO" ) );
2731 setSizeGripEnabled( true );
2733 myTabWidget = new QTabWidget( this );
2737 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2738 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2742 QWidget* w = new QWidget( myTabWidget );
2744 myMode = new QButtonGroup( this );
2745 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2746 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2747 myMode->button( NodeMode )->setChecked( true );
2748 myID = new QLineEdit( w );
2749 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2751 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2752 mode = qMin( 1, qMax( 0, mode ) );
2755 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2757 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2759 QGridLayout* elemLayout = new QGridLayout( w );
2760 elemLayout->setMargin( MARGIN );
2761 elemLayout->setSpacing( SPACING );
2762 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2763 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2764 elemLayout->addWidget( myID, 0, 2 );
2765 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2767 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2771 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2772 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2776 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2777 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2781 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2782 okBtn->setAutoDefault( true );
2783 okBtn->setDefault( true );
2785 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2786 dumpBtn->setAutoDefault( true );
2787 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2788 helpBtn->setAutoDefault( true );
2790 QHBoxLayout* btnLayout = new QHBoxLayout;
2791 btnLayout->setSpacing( SPACING );
2792 btnLayout->setMargin( 0 );
2794 btnLayout->addWidget( okBtn );
2795 btnLayout->addWidget( dumpBtn );
2796 btnLayout->addStretch( 10 );
2797 btnLayout->addWidget( helpBtn );
2799 QVBoxLayout* l = new QVBoxLayout ( this );
2800 l->setMargin( MARGIN );
2801 l->setSpacing( SPACING );
2802 l->addWidget( myTabWidget );
2803 l->addLayout( btnLayout );
2805 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2807 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2808 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2809 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2810 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2811 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2812 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2813 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2814 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2815 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2816 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2824 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2829 \brief Show mesh information
2830 \param IO interactive object
2832 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2834 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2835 if ( !CORBA::is_nil( obj ) ) {
2836 myBaseInfo->showInfo( obj );
2837 myAddInfo->showInfo( obj );
2838 myCtrlInfo->showInfo( obj );
2840 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2841 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
2844 if ( myActor && selector ) {
2845 nb = myMode->checkedId() == NodeMode ?
2846 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2847 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2849 myElemInfo->setSource( myActor ) ;
2851 myID->setText( ID.trimmed() );
2853 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2854 foreach ( ID, idTxt )
2855 ids << ID.trimmed().toLong();
2856 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2860 myElemInfo->clear();
2866 \brief Perform clean-up actions on the dialog box closing.
2868 void SMESHGUI_MeshInfoDlg::reject()
2870 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2871 selMgr->clearFilters();
2872 SMESH::SetPointRepresentation( false );
2873 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2874 aViewWindow->SetSelectionMode( ActorSelection );
2879 \brief Process keyboard event
2880 \param e key press event
2882 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2884 QDialog::keyPressEvent( e );
2885 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2892 \brief Reactivate dialog box, when mouse pointer goes into it.
2894 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2900 \brief Setup selection mode depending on the current dialog box state.
2902 void SMESHGUI_MeshInfoDlg::updateSelection()
2904 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2906 disconnect( selMgr, 0, this, 0 );
2907 selMgr->clearFilters();
2909 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2910 SMESH::SetPointRepresentation( false );
2911 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2912 aViewWindow->SetSelectionMode( ActorSelection );
2915 if ( myMode->checkedId() == NodeMode ) {
2916 SMESH::SetPointRepresentation( true );
2917 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2918 aViewWindow->SetSelectionMode( NodeSelection );
2921 SMESH::SetPointRepresentation( false );
2922 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2923 aViewWindow->SetSelectionMode( CellSelection );
2927 QString oldID = myID->text().trimmed();
2928 SMESH_Actor* oldActor = myActor;
2931 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
2934 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
2935 myID->setText( oldID );
2941 \brief Show help page
2943 void SMESHGUI_MeshInfoDlg::help()
2945 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
2946 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
2947 "mesh_infos_page.html#mesh_element_info_anchor" );
2951 \brief Show mesh information
2953 void SMESHGUI_MeshInfoDlg::updateInfo()
2955 SUIT_OverrideCursor wc;
2957 SALOME_ListIO selected;
2958 SMESHGUI::selectionMgr()->selectedObjects( selected );
2960 if ( selected.Extent() == 1 ) {
2961 Handle(SALOME_InteractiveObject) IO = selected.First();
2965 // myBaseInfo->clear();
2966 // myElemInfo->clear();
2967 // myAddInfo->clear();
2972 \brief Activate dialog box
2974 void SMESHGUI_MeshInfoDlg::activate()
2976 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
2977 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
2978 myTabWidget->setEnabled( true );
2983 \brief Deactivate dialog box
2985 void SMESHGUI_MeshInfoDlg::deactivate()
2987 myTabWidget->setEnabled( false );
2988 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
2992 \brief Called when users switches between node / element modes.
2994 void SMESHGUI_MeshInfoDlg::modeChanged()
3001 \brief Caled when users prints mesh element ID in the corresponding field.
3003 void SMESHGUI_MeshInfoDlg::idChanged()
3005 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
3006 if ( myActor && selector ) {
3007 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3008 TColStd_MapOfInteger ID;
3010 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3011 foreach ( QString tid, idTxt ) {
3012 long id = tid.trimmed().toLong();
3013 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3014 myActor->GetObject()->GetMesh()->FindElement( id ) :
3015 myActor->GetObject()->GetMesh()->FindNode( id );
3021 selector->AddOrRemoveIndex( IO, ID, false );
3022 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3023 aViewWindow->highlight( IO, true, true );
3024 aViewWindow->Repaint();
3026 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3030 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3032 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3033 myMode->button( NodeMode )->click();
3034 myID->setText( QString::number( id ) );
3038 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3040 if ( !theStr.isEmpty() ) {
3041 myMode->button( ElemMode )->click();
3042 myID->setText( theStr );
3046 void SMESHGUI_MeshInfoDlg::dump()
3048 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3050 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3051 if ( !appStudy ) return;
3052 _PTR( Study ) aStudy = appStudy->studyDS();
3054 QStringList aFilters;
3055 aFilters.append( tr( "TEXT_FILES" ) );
3057 bool anIsBase = true;
3058 bool anIsElem = true;
3059 bool anIsAdd = true;
3060 bool anIsCtrl = true;
3062 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3063 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3064 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3065 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3066 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3069 DumpFileDlg fd( this );
3070 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3071 fd.setFilters( aFilters );
3072 fd.myBaseChk->setChecked( anIsBase );
3073 fd.myElemChk->setChecked( anIsElem );
3074 fd.myAddChk ->setChecked( anIsAdd );
3075 fd.myCtrlChk->setChecked( anIsCtrl );
3076 if ( fd.exec() == QDialog::Accepted )
3078 QString aFileName = fd.selectedFile();
3080 bool toBase = fd.myBaseChk->isChecked();
3081 bool toElem = fd.myElemChk->isChecked();
3082 bool toAdd = fd.myAddChk->isChecked();
3083 bool toCtrl = fd.myCtrlChk->isChecked();
3085 if ( !aFileName.isEmpty() ) {
3086 QFileInfo aFileInfo( aFileName );
3087 if ( aFileInfo.isDir() )
3090 QFile aFile( aFileName );
3091 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3094 QTextStream out( &aFile );
3096 if ( toBase ) myBaseInfo->saveInfo( out );
3097 if ( toElem ) myElemInfo->saveInfo( out );
3098 if ( toAdd ) myAddInfo ->saveInfo( out );
3099 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3105 \class SMESHGUI_CtrlInfo
3106 \brief Class for the mesh controls information widget.
3111 \param parent parent widget
3113 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3114 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3116 setFrameStyle( StyledPanel | Sunken );
3118 myMainLayout = new QGridLayout( this );
3119 myMainLayout->setMargin( MARGIN );
3120 myMainLayout->setSpacing( SPACING );
3123 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3124 QLabel* aName = createField();
3125 aName->setMinimumWidth( 150 );
3128 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3129 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3131 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3134 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3135 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3136 QLabel* aNodesFree = createField();
3137 myWidgets << aNodesFree;
3138 myPredicates << aFilterMgr->CreateFreeNodes();
3140 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3141 QLabel* aNodesDouble = createField();
3142 myWidgets << aNodesDouble;
3143 myPredicates << aFilterMgr->CreateEqualNodes();
3144 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3145 myToleranceWidget = new SMESHGUI_SpinBox( this );
3146 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3147 myToleranceWidget->setAcceptNames( false );
3148 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3151 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3152 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3153 QLabel* anEdgesDouble = createField();
3154 myWidgets << anEdgesDouble;
3155 myPredicates << aFilterMgr->CreateEqualEdges();
3158 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3159 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3160 QLabel* aFacesDouble = createField();
3161 myWidgets << aFacesDouble;
3162 myPredicates << aFilterMgr->CreateEqualFaces();
3163 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3164 QLabel* aFacesOver = createField();
3165 myWidgets << aFacesOver;
3166 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3167 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3168 myPlot = createPlot( this );
3169 myAspectRatio = aFilterMgr->CreateAspectRatio();
3172 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3173 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3174 QLabel* aVolumesDouble = createField();
3175 myWidgets << aVolumesDouble;
3176 myPredicates << aFilterMgr->CreateEqualVolumes();
3177 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3178 QLabel* aVolumesOver = createField();
3179 myWidgets << aVolumesOver;
3180 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3181 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3182 myPlot3D = createPlot( this );
3183 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3185 QToolButton* aFreeNodesBtn = new QToolButton( this );
3186 aFreeNodesBtn->setIcon(aComputeIcon);
3187 myButtons << aFreeNodesBtn; //0
3189 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3190 aDoubleNodesBtn->setIcon(aComputeIcon);
3191 myButtons << aDoubleNodesBtn; //1
3193 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3194 aDoubleEdgesBtn->setIcon(aComputeIcon);
3195 myButtons << aDoubleEdgesBtn; //2
3197 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3198 aDoubleFacesBtn->setIcon(aComputeIcon);
3199 myButtons << aDoubleFacesBtn; //3
3201 QToolButton* aOverContFacesBtn = new QToolButton( this );
3202 aOverContFacesBtn->setIcon(aComputeIcon);
3203 myButtons << aOverContFacesBtn; //4
3205 QToolButton* aComputeFaceBtn = new QToolButton( this );
3206 aComputeFaceBtn->setIcon(aComputeIcon);
3207 myButtons << aComputeFaceBtn; //5
3209 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3210 aDoubleVolumesBtn->setIcon(aComputeIcon);
3211 myButtons << aDoubleVolumesBtn; //6
3213 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3214 aOverContVolumesBtn->setIcon(aComputeIcon);
3215 myButtons << aOverContVolumesBtn; //7
3217 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3218 aComputeVolumeBtn->setIcon(aComputeIcon);
3219 myButtons << aComputeVolumeBtn; //8
3221 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3222 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3223 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3224 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3225 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3226 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3227 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3228 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3229 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3230 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3232 setFontAttributes( aNameLab );
3233 setFontAttributes( aNodesLab );
3234 setFontAttributes( anEdgesLab );
3235 setFontAttributes( aFacesLab );
3236 setFontAttributes( aVolumesLab );
3238 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3239 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3240 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3241 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3242 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3243 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3244 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3245 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3246 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3247 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3248 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3249 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3250 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3251 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3252 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3253 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3254 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3255 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3256 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3257 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3258 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3259 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3260 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3261 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3262 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3263 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3264 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3265 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3266 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3267 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3268 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3269 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3270 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3271 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3272 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3274 myMainLayout->setColumnStretch( 0, 0 );
3275 myMainLayout->setColumnStretch( 1, 5 );
3276 myMainLayout->setRowStretch ( 11, 5 );
3277 myMainLayout->setRowStretch ( 16, 5 );
3278 myMainLayout->setRowStretch ( 17, 1 );
3286 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3290 \brief Change widget font attributes (bold, ...).
3292 \param attr font attributes (XORed flags)
3294 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3297 QFont f = w->font();
3304 \brief Create info field
3305 \return new info field
3307 QLabel* SMESHGUI_CtrlInfo::createField()
3309 QLabel* lab = new QLabel( this );
3310 lab->setFrameStyle( StyledPanel | Sunken );
3311 lab->setAlignment( Qt::AlignCenter );
3312 lab->setAutoFillBackground( true );
3313 QPalette pal = lab->palette();
3314 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3315 lab->setPalette( pal );
3316 lab->setMinimumWidth( 60 );
3321 \brief Create QwtPlot
3324 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3326 QwtPlot* aPlot = new QwtPlot( parent );
3327 aPlot->setMinimumSize( 100, 100 );
3328 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3329 xFont.setPointSize( 5 );
3330 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3331 yFont.setPointSize( 5 );
3332 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3333 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3339 \brief Show controls information on the selected object
3341 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3345 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3346 if ( myObject->_is_nil() ) return;
3348 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3349 myWidgets[0]->setText( aSO->GetName().c_str() );
3351 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3352 if ( mesh->_is_nil() ) return;
3354 const bool meshLoaded = mesh->IsLoaded();
3355 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3356 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3357 for ( int i = 0; i < myButtons.count(); ++i )
3358 myButtons[i]->setEnabled( true );
3360 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3361 if ( ! &nbElemsByType.in() ) return;
3363 const CORBA::Long ctrlLimit =
3364 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3367 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3368 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3369 nbElemsByType[ SMESH::FACE ] +
3370 nbElemsByType[ SMESH::VOLUME ] );
3371 if ( nbNodes + nbElems > 0 ) {
3372 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3374 computeFreeNodesInfo();
3376 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3377 computeDoubleNodesInfo();
3380 myButtons[0]->setEnabled( true );
3381 myButtons[1]->setEnabled( true );
3385 for( int i=2; i<=10; i++)
3386 myMainLayout->itemAt(i)->widget()->setVisible( false );
3390 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3392 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3393 computeDoubleEdgesInfo();
3395 myButtons[2]->setEnabled( true );
3398 for( int i=11; i<=14; i++)
3399 myMainLayout->itemAt(i)->widget()->setVisible( false );
3403 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3404 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3406 computeDoubleFacesInfo();
3407 // over constrained faces
3408 computeOverConstrainedFacesInfo();
3409 // aspect Ratio histogram
3410 computeAspectRatio();
3413 myButtons[3]->setEnabled( true );
3414 myButtons[4]->setEnabled( true );
3415 myButtons[5]->setEnabled( true );
3419 myMainLayout->setRowStretch(11,0);
3420 for( int i=15; i<=24; i++)
3421 myMainLayout->itemAt(i)->widget()->setVisible( false );
3425 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3426 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3428 computeDoubleVolumesInfo();
3429 // over constrained volumes
3430 computeOverConstrainedVolumesInfo();
3431 // aspect Ratio 3D histogram
3432 computeAspectRatio3D();
3435 myButtons[6]->setEnabled( true );
3436 myButtons[7]->setEnabled( true );
3437 myButtons[8]->setEnabled( true );
3441 myMainLayout->setRowStretch(16,0);
3442 for( int i=25; i<=34; i++)
3443 myMainLayout->itemAt(i)->widget()->setVisible( false );
3447 //================================================================================
3449 * \brief Computes and shows nb of elements satisfying a given predicate
3450 * \param [in] ft - a predicate type (SMESH::FunctorType)
3451 * \param [in] iBut - index of one of myButtons to disable
3452 * \param [in] iWdg - index of one of myWidgets to show the computed number
3454 //================================================================================
3456 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3458 myButtons[ iBut ]->setEnabled( false );
3459 myWidgets[ iWdg ]->setText( "" );
3460 if ( myObject->_is_nil() ) return;
3462 SUIT_OverrideCursor wc;
3464 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3465 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3468 this->showInfo( myObject ); // try to show all values
3469 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3470 return; // <ft> predicate already computed
3472 // look for a predicate of type <ft>
3473 for ( int i = 0; i < myPredicates.count(); ++i )
3474 if ( myPredicates[i]->GetFunctorType() == ft )
3476 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3477 myWidgets[ iWdg ]->setText( QString::number( nb ));
3481 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3483 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3486 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3488 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3491 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3493 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3496 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3498 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3501 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3503 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3506 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3508 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3511 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3513 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3516 void SMESHGUI_CtrlInfo::computeAspectRatio()
3518 myButtons[5]->setEnabled( false );
3520 if ( myObject->_is_nil() ) return;
3522 SUIT_OverrideCursor wc;
3524 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3525 if ( aHistogram && !aHistogram->isEmpty() ) {
3526 QwtPlotItem* anItem = aHistogram->createPlotItem();
3527 anItem->attach( myPlot );
3533 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3535 myButtons[8]->setEnabled( false );
3537 if ( myObject->_is_nil() ) return;
3539 SUIT_OverrideCursor wc;
3541 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3542 if ( aHistogram && !aHistogram->isEmpty() ) {
3543 QwtPlotItem* anItem = aHistogram->createPlotItem();
3544 anItem->attach( myPlot3D );
3551 \brief Internal clean-up (reset widget)
3553 void SMESHGUI_CtrlInfo::clearInternal()
3555 for( int i=0; i<=34; i++)
3556 myMainLayout->itemAt(i)->widget()->setVisible( true );
3557 for( int i=0; i<=8; i++)
3558 myButtons[i]->setEnabled( false );
3559 myPlot->detachItems();
3560 myPlot3D->detachItems();
3563 myWidgets[0]->setText( QString() );
3564 for ( int i = 1; i < myWidgets.count(); i++ )
3565 myWidgets[i]->setText( "" );
3566 myMainLayout->setRowStretch(11,5);
3567 myMainLayout->setRowStretch(16,5);
3570 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3572 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3573 myButtons[1]->setEnabled( true );
3574 myWidgets[2]->setText("");
3577 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3579 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3580 if ( mesh->_is_nil() ) return 0;
3581 if ( !mesh->IsLoaded() )
3583 aNumFun->SetMesh( mesh );
3585 CORBA::Long cprecision = 6;
3586 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3587 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3588 aNumFun->SetPrecision( cprecision );
3590 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3592 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3593 /*isLogarithmic=*/false,
3595 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3596 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3597 if ( &histogramVar.in() )
3599 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3600 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3601 if ( histogramVar->length() >= 2 )
3602 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3607 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3608 out << QString( 20, '-' ) << "\n";
3609 out << tr( "CTRL_INFO" ) << "\n";
3610 out << QString( 20, '-' ) << "\n";
3611 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3612 out << tr( "NODES_INFO" ) << "\n";
3613 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3614 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3615 out << tr( "EDGES_INFO" ) << "\n";
3616 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3617 out << tr( "FACES_INFO" ) << "\n";
3618 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3619 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3620 out << tr( "VOLUMES_INFO" ) << "\n";
3621 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3622 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3626 \class SMESHGUI_CtrlInfoDlg
3627 \brief Controls information dialog box
3632 \param parent parent widget
3633 \param page specifies the dialog page to be shown at the start-up
3635 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3638 setAttribute( Qt::WA_DeleteOnClose, true );
3639 setWindowTitle( tr( "CTRL_INFO" ) );
3640 setMinimumSize( 400, 600 );
3642 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3645 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3646 okBtn->setAutoDefault( true );
3647 okBtn->setDefault( true );
3649 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3650 dumpBtn->setAutoDefault( true );
3651 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3652 helpBtn->setAutoDefault( true );
3654 QHBoxLayout* btnLayout = new QHBoxLayout;
3655 btnLayout->setSpacing( SPACING );
3656 btnLayout->setMargin( 0 );
3658 btnLayout->addWidget( okBtn );
3659 btnLayout->addWidget( dumpBtn );
3660 btnLayout->addStretch( 10 );
3661 btnLayout->addWidget( helpBtn );
3663 QVBoxLayout* l = new QVBoxLayout ( this );
3664 l->setMargin( MARGIN );
3665 l->setSpacing( SPACING );
3666 l->addWidget( myCtrlInfo );
3667 l->addLayout( btnLayout );
3669 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3670 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3671 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3672 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3673 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3681 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3686 \brief Show controls information
3687 \param IO interactive object
3689 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3691 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3692 myCtrlInfo->showInfo( obj );
3696 \brief Perform clean-up actions on the dialog box closing.
3698 void SMESHGUI_CtrlInfoDlg::reject()
3700 SMESH::SetPointRepresentation( false );
3705 \brief Setup selection mode depending on the current dialog box state.
3707 void SMESHGUI_CtrlInfoDlg::updateSelection()
3709 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3710 disconnect( selMgr, 0, this, 0 );
3711 SMESH::SetPointRepresentation( false );
3712 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3717 \brief Show mesh information
3719 void SMESHGUI_CtrlInfoDlg::updateInfo()
3721 SUIT_OverrideCursor wc;
3723 SALOME_ListIO selected;
3724 SMESHGUI::selectionMgr()->selectedObjects( selected );
3726 if ( selected.Extent() == 1 ) {
3727 Handle(SALOME_InteractiveObject) IO = selected.First();
3733 \brief Activate dialog box
3735 void SMESHGUI_CtrlInfoDlg::activate()
3737 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3738 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3743 \brief Deactivate dialog box
3745 void SMESHGUI_CtrlInfoDlg::deactivate()
3747 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3751 * \brief Dump contents into a file
3753 void SMESHGUI_CtrlInfoDlg::dump()
3755 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3757 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3758 if ( !appStudy ) return;
3759 _PTR( Study ) aStudy = appStudy->studyDS();
3761 QStringList aFilters;
3762 aFilters.append( tr( "TEXT_FILES" ) );
3764 DumpFileDlg fd( this );
3765 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3766 fd.setFilters( aFilters );
3767 fd.myBaseChk->hide();
3768 fd.myElemChk->hide();
3769 fd.myAddChk ->hide();
3770 fd.myCtrlChk->hide();
3771 if ( fd.exec() == QDialog::Accepted )
3773 QString aFileName = fd.selectedFile();
3774 if ( !aFileName.isEmpty() ) {
3775 QFileInfo aFileInfo( aFileName );
3776 if ( aFileInfo.isDir() )
3779 QFile aFile( aFileName );
3780 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3783 QTextStream out( &aFile );
3784 myCtrlInfo->saveInfo( out );
3792 void SMESHGUI_CtrlInfoDlg::help()
3794 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");