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 QLabel* a2DPolLin = createField();
310 QLabel* a2DPolQuad = createField();
311 myWidgets[ index++ ] << a2DLine;
312 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
313 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
314 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
315 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
318 QWidget* a3DLine = createLine();
319 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
320 QLabel* a3DTotal = createField();
321 QLabel* a3DLin = createField();
322 QLabel* a3DQuad = createField();
323 QLabel* a3DBiQuad = createField();
324 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
325 QLabel* a3DTetTotal = createField();
326 QLabel* a3DTetLin = createField();
327 QLabel* a3DTetQuad = createField();
328 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
329 QLabel* a3DHexTotal = createField();
330 QLabel* a3DHexLin = createField();
331 QLabel* a3DHexQuad = createField();
332 QLabel* a3DHexBiQuad = createField();
333 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
334 QLabel* a3DPyrTotal = createField();
335 QLabel* a3DPyrLin = createField();
336 QLabel* a3DPyrQuad = createField();
337 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
338 QLabel* a3DPriTotal = createField();
339 QLabel* a3DPriLin = createField();
340 QLabel* a3DPriQuad = createField();
341 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
342 QLabel* a3DHexPriTotal = createField();
343 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
344 QLabel* a3DPolTotal = createField();
345 myWidgets[ index++ ] << a3DLine;
346 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
347 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
348 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
349 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
350 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
351 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
352 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
354 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
355 myLoadBtn->setAutoDefault( true );
356 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
358 setFontAttributes( aNameLab, Bold );
359 setFontAttributes( aObjLab, Bold );
360 setFontAttributes( aNodesLab, Bold );
361 setFontAttributes( aElemLab, Bold );
362 setFontAttributes( aElemTotal, Italic );
363 setFontAttributes( aElemLin, Italic );
364 setFontAttributes( aElemQuad, Italic );
365 setFontAttributes( aElemBiQuad, Italic );
366 setFontAttributes( a0DLab, Bold );
367 setFontAttributes( aBallLab, Bold );
368 setFontAttributes( a1DLab, Bold );
369 setFontAttributes( a2DLab, Bold );
370 setFontAttributes( a3DLab, Bold );
372 l->addWidget( aNameLab, 0, 0 );
373 l->addWidget( aName, 0, 1, 1, 4 );
374 l->addWidget( aObjLab, 1, 0 );
375 l->addWidget( aObj, 1, 1, 1, 4 );
376 l->addWidget( aNodesLine, 2, 0, 1, 5 );
377 l->addWidget( aNodesLab, 3, 0 );
378 l->addWidget( aNodes, 3, 1 );
379 l->addWidget( aElemLine, 4, 0, 1, 5 );
380 l->addWidget( aElemLab, 5, 0 );
381 l->addWidget( aElemTotal, 5, 1 );
382 l->addWidget( aElemLin, 5, 2 );
383 l->addWidget( aElemQuad, 5, 3 );
384 l->addWidget( aElemBiQuad, 5, 4 );
385 l->addWidget( aNbLine, 6, 1, 1, 4 );
386 l->addWidget( aNbTotal, 7, 1 );
387 l->addWidget( aNbLin, 7, 2 );
388 l->addWidget( aNbQuad, 7, 3 );
389 l->addWidget( aNbBiQuad, 7, 4 );
390 l->addWidget( a0DLine, 8, 1, 1, 4 );
391 l->addWidget( a0DLab, 9, 0 );
392 l->addWidget( a0DTotal, 9, 1 );
393 l->addWidget( aBallLine, 10, 1, 1, 4 );
394 l->addWidget( aBallLab, 11, 0 );
395 l->addWidget( aBallTotal, 11, 1 );
396 l->addWidget( a1DLine, 12, 1, 1, 4 );
397 l->addWidget( a1DLab, 13, 0 );
398 l->addWidget( a1DTotal, 13, 1 );
399 l->addWidget( a1DLin, 13, 2 );
400 l->addWidget( a1DQuad, 13, 3 );
401 l->addWidget( a2DLine, 14, 1, 1, 4 );
402 l->addWidget( a2DLab, 15, 0 );
403 l->addWidget( a2DTotal, 15, 1 );
404 l->addWidget( a2DLin, 15, 2 );
405 l->addWidget( a2DQuad, 15, 3 );
406 l->addWidget( a2DBiQuad, 15, 4 );
407 l->addWidget( a2DTriLab, 16, 0 );
408 l->addWidget( a2DTriTotal, 16, 1 );
409 l->addWidget( a2DTriLin, 16, 2 );
410 l->addWidget( a2DTriQuad, 16, 3 );
411 l->addWidget( a2DTriBiQuad, 16, 4 );
412 l->addWidget( a2DQuaLab, 17, 0 );
413 l->addWidget( a2DQuaTotal, 17, 1 );
414 l->addWidget( a2DQuaLin, 17, 2 );
415 l->addWidget( a2DQuaQuad, 17, 3 );
416 l->addWidget( a2DQuaBiQuad, 17, 4 );
417 l->addWidget( a2DPolLab, 18, 0 );
418 l->addWidget( a2DPolTotal, 18, 1 );
419 l->addWidget( a2DPolLin, 18, 2 );
420 l->addWidget( a2DPolQuad, 18, 3 );
421 l->addWidget( a3DLine, 19, 1, 1, 4 );
422 l->addWidget( a3DLab, 20, 0 );
423 l->addWidget( a3DTotal, 20, 1 );
424 l->addWidget( a3DLin, 20, 2 );
425 l->addWidget( a3DQuad, 20, 3 );
426 l->addWidget( a3DBiQuad, 20, 4 );
427 l->addWidget( a3DTetLab, 21, 0 );
428 l->addWidget( a3DTetTotal, 21, 1 );
429 l->addWidget( a3DTetLin, 21, 2 );
430 l->addWidget( a3DTetQuad, 21, 3 );
431 l->addWidget( a3DHexLab, 22, 0 );
432 l->addWidget( a3DHexTotal, 22, 1 );
433 l->addWidget( a3DHexLin, 22, 2 );
434 l->addWidget( a3DHexQuad, 22, 3 );
435 l->addWidget( a3DHexBiQuad, 22, 4 );
436 l->addWidget( a3DPyrLab, 23, 0 );
437 l->addWidget( a3DPyrTotal, 23, 1 );
438 l->addWidget( a3DPyrLin, 23, 2 );
439 l->addWidget( a3DPyrQuad, 23, 3 );
440 l->addWidget( a3DPriLab, 24, 0 );
441 l->addWidget( a3DPriTotal, 24, 1 );
442 l->addWidget( a3DPriLin, 24, 2 );
443 l->addWidget( a3DPriQuad, 24, 3 );
444 l->addWidget( a3DHexPriLab, 25, 0 );
445 l->addWidget( a3DHexPriTotal, 25, 1 );
446 l->addWidget( a3DPolLab, 26, 0 );
447 l->addWidget( a3DPolTotal, 26, 1 );
448 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
450 l->setColumnStretch( 0, 0 );
451 l->setColumnStretch( 1, 5 );
452 l->setColumnStretch( 2, 5 );
453 l->setColumnStretch( 3, 5 );
454 l->setColumnStretch( 4, 5 );
455 l->setRowStretch( 27, 5 );
463 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
468 \brief Show information on the mesh object.
469 \param obj object being processed (mesh, sub-mesh, group, ID source)
471 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
474 if ( !CORBA::is_nil( obj ) ) {
475 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
477 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
478 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
479 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
480 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
481 if ( !aMesh->_is_nil() ) {
482 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
484 else if ( !aSubMesh->_is_nil() ) {
485 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
487 else if ( !aGroup->_is_nil() ) {
489 switch( aGroup->GetType() ) {
490 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
491 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
492 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
493 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
494 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
495 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
496 default: objType = tr( "OBJECT_GROUP" );break;
498 myWidgets[iObject][iSingle]->setProperty( "text", objType );
500 SMESH::long_array_var info = obj->GetMeshInfo();
501 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
502 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
503 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
504 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
505 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
506 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
507 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
508 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
509 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
510 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
511 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
512 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
513 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
514 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
516 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
517 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
518 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
519 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
520 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
521 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
522 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
523 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
524 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
525 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
526 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
527 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
528 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
529 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
530 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
531 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
532 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
533 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
534 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
535 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
536 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
537 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
538 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
539 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
540 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
541 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
542 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
543 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
544 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
545 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
546 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
547 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
548 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
549 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
550 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
551 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
552 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
553 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
554 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
555 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
556 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
557 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
558 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
559 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
560 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
561 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
562 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
563 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
564 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
565 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
566 // before full loading from study file, type of elements in a sub-mesh can't be defined
568 bool infoOK = obj->IsMeshInfoCorrect();
569 myLoadBtn->setVisible( !infoOK );
573 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
574 // 2. No info at all (for a group on geom or filter)
575 bool hasAnyInfo = false;
576 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
577 hasAnyInfo = info[i];
578 if ( hasAnyInfo ) // believe it is a sub-mesh
580 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
582 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
583 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
584 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
585 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
586 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
587 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
588 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
589 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
590 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
591 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
592 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
593 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
594 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
595 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
596 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
597 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
598 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
599 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
601 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
603 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
604 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
605 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
606 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
607 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
608 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
609 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
610 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
611 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
612 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
613 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
614 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
615 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
616 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
617 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
618 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
619 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
620 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
621 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
622 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
623 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
624 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
629 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
630 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
631 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
632 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
633 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
634 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
635 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
636 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
637 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
638 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
640 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
643 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
644 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
645 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
647 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
648 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
649 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
650 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
651 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
652 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
653 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
654 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
655 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
656 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
657 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
658 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
659 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
660 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
661 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
662 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
663 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
664 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
665 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
666 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
667 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
668 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
669 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
676 \brief Load mesh from a study file
678 void SMESHGUI_MeshInfo::loadMesh()
680 SUIT_OverrideCursor wc;
682 SALOME_ListIO selected;
683 SMESHGUI::selectionMgr()->selectedObjects( selected );
685 if ( selected.Extent() == 1 ) {
686 Handle(SALOME_InteractiveObject) IO = selected.First();
687 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
688 if ( !CORBA::is_nil( obj ) ) {
689 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
690 if ( !mesh->_is_nil() )
700 \brief Reset the widget to the initial state (nullify all fields).
702 void SMESHGUI_MeshInfo::clear()
704 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
705 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
706 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
707 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
708 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
709 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
710 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
711 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
712 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
713 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
714 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
715 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
716 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
717 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
718 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
719 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
720 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
721 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
722 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
723 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
724 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ) );
725 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
726 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
727 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
728 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
729 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
730 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
731 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
732 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
733 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
734 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
735 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
736 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
737 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
738 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
739 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
740 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
741 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
742 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
743 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
744 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
745 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
746 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
747 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
748 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
749 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
753 \brief Create info field
754 \return new info field
756 QLabel* SMESHGUI_MeshInfo::createField()
758 QLabel* lab = new QLabel( this );
759 lab->setFrameStyle( StyledPanel | Sunken );
760 lab->setAlignment( Qt::AlignCenter );
761 lab->setAutoFillBackground( true );
762 QPalette pal = lab->palette();
763 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
764 lab->setPalette( pal );
765 lab->setMinimumWidth( 70 );
770 \brief Create horizontal rule.
771 \return new line object
773 QWidget* SMESHGUI_MeshInfo::createLine()
775 QFrame* line = new QFrame( this );
776 line->setFrameStyle( HLine | Sunken );
781 \brief Change widget font attributes (bold, italic, ...).
783 \param attr font attributes (XORed flags)
784 \param val value to be set to attributes
786 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
790 if ( attr & Bold ) f.setBold( val );
791 if ( attr & Italic ) f.setItalic( val );
797 \brief Show/hide group(s) of fields.
798 \param start beginning of the block
799 \param end end of the block
800 \param on visibility flag
802 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
804 start = qMax( 0, start );
805 end = qMin( end, (int)iElementsEnd );
806 for ( int i = start; i < end; i++ ) {
807 wlist wl = myWidgets[i];
808 foreach ( QWidget* w, wl ) w->setVisible( on );
812 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
814 out << QString( 9, '-' ) << "\n";
815 out << tr( "BASE_INFO" ) << "\n";
816 out << QString( 9, '-' ) << "\n";
817 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
818 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
819 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
820 out << tr( "ELEMENTS_LAB" ) << "\n";
821 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
822 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
823 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
824 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
825 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
826 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
827 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
828 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
829 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
830 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
831 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
832 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
833 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
834 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
835 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
836 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
837 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
838 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
839 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
840 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
841 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
842 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
843 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
844 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
845 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
846 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
847 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
848 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
849 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
850 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
851 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
852 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
853 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
854 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
855 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
856 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
857 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
858 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
859 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
860 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
861 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
862 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
863 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
864 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
865 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
866 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
867 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
868 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
869 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
870 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
871 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
872 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
873 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
874 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
875 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
876 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
877 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
881 \class SMESHGUI_ElemInfo
882 \brief Base class for the mesh element information widget.
887 \param parent parent widget
889 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
890 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
892 myFrame = new QWidget( this );
893 myExtra = new ExtraWidget( this );
894 QVBoxLayout* vbl = new QVBoxLayout( this );
896 vbl->setSpacing( 0 );
897 vbl->addWidget( myFrame );
898 vbl->addWidget( myExtra );
899 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
900 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
907 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
912 \brief Set mesh data source (actor)
913 \param actor mesh object actor
915 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
917 if ( myActor != actor ) {
925 \brief Show mesh element information
926 \param id mesh node / element ID
927 \param isElem show mesh element information if \c true or mesh node information if \c false
929 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
933 showInfo( ids, isElem );
937 \brief Show mesh element information
938 \param ids mesh nodes / elements identifiers
939 \param isElem show mesh element information if \c true or mesh node information if \c false
941 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
943 QList<long> newIds = ids.toList();
945 if ( myIDs == newIds && myIsElement == isElem ) return;
948 myIsElement = isElem;
951 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
955 \brief Clear mesh element information widget
957 void SMESHGUI_ElemInfo::clear()
966 \brief Get central area widget
967 \return central widget
969 QWidget* SMESHGUI_ElemInfo::frame() const
976 \return actor being used
978 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
984 \brief Get current info mode.
985 \return \c true if mesh element information is shown or \c false if node information is shown
987 bool SMESHGUI_ElemInfo::isElements() const
993 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
994 \brief Show information on the specified nodes / elements
996 This function is to be redefined in sub-classes.
998 \param ids nodes / elements identifiers information is to be shown on
1002 \brief Internal clean-up (reset widget)
1004 void SMESHGUI_ElemInfo::clearInternal()
1009 \brief Get node connectivity
1010 \param node mesh node
1011 \return node connectivity map
1013 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1017 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1018 while ( it && it->more() ) {
1019 const SMDS_MeshElement* ne = it->next();
1020 elmap[ ne->GetType() ] << ne->GetID();
1027 \brief Format connectivity data to string representation
1028 \param connectivity connetivity map
1029 \param type element type
1030 \return string representation of the connectivity
1032 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1035 if ( connectivity.contains( type ) ) {
1036 QList<int> elements = connectivity[ type ];
1038 foreach( int id, elements )
1039 str << QString::number( id );
1041 return str.join( " " );
1045 \brief Calculate gravity center of the mesh element
1046 \param element mesh element
1048 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1052 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1053 while ( nodeIt->more() ) {
1054 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1055 xyz.add( node->X(), node->Y(), node->Z() );
1057 xyz.divide( element->NbNodes() );
1063 \brief Calculate normal vector to the mesh face
1064 \param element mesh face
1066 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1068 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1069 return XYZ(n.X(), n.Y(), n.Z());
1073 \brief This slot is called from "Show Previous" button click.
1074 Shows information on the previous group of the items.
1076 void SMESHGUI_ElemInfo::showPrevious()
1078 myIndex = qMax( 0, myIndex-1 );
1080 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1084 \brief This slot is called from "Show Next" button click.
1085 Shows information on the next group of the items.
1087 void SMESHGUI_ElemInfo::showNext()
1089 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1091 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1095 \brief Update widgets state
1097 void SMESHGUI_ElemInfo::updateControls()
1099 myExtra->updateControls( myIDs.count(), myIndex );
1103 \class SMESHGUI_SimpleElemInfo
1104 \brief Represents mesh element information in the simple text area.
1109 \param parent parent widget
1111 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1112 : SMESHGUI_ElemInfo( parent )
1114 myInfo = new QTextBrowser( frame() );
1115 QVBoxLayout* l = new QVBoxLayout( frame() );
1117 l->addWidget( myInfo );
1121 \brief Show mesh element information
1122 \param ids mesh nodes / elements identifiers
1124 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1129 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1130 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1131 int cprecision = -1;
1132 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1133 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1134 foreach ( long id, ids ) {
1135 if ( !isElements() ) {
1139 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1140 if ( !node ) return;
1143 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1145 myInfo->append( "" );
1147 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1148 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1149 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1150 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1152 myInfo->append( "" );
1154 Connectivity connectivity = nodeConnectivity( node );
1155 if ( !connectivity.isEmpty() ) {
1156 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1157 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1158 if ( !con.isEmpty() )
1159 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1160 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1161 if ( !con.isEmpty() )
1162 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1163 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1164 if ( !con.isEmpty() )
1165 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1166 con = formatConnectivity( connectivity, SMDSAbs_Face );
1167 if ( !con.isEmpty() )
1168 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1169 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1170 if ( !con.isEmpty() )
1171 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1174 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1177 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1178 if ( !CORBA::is_nil( aMeshPtr ) ) {
1179 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1180 int shapeID = pos->shapeID;
1181 if ( shapeID > 0 ) {
1184 switch ( pos->shapeType ) {
1186 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1187 if ( pos->params.length() == 1 )
1191 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1192 if ( pos->params.length() == 2 ) {
1198 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1201 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1205 myInfo->append( "" );
1206 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1207 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1208 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1209 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1210 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1211 if ( pos->shapeType == GEOM::FACE ) {
1212 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1213 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1218 // groups node belongs to
1219 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1220 if ( !CORBA::is_nil( aMesh ) ) {
1221 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1222 myInfo->append( "" ); // separator
1223 bool top_created = false;
1224 for ( int i = 0; i < groups->length(); i++ ) {
1225 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1226 if ( CORBA::is_nil( aGrp ) ) continue;
1227 QString aName = aGrp->GetName();
1228 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1229 if ( !top_created ) {
1230 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1233 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1234 if ( grp_details ) {
1235 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1236 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1237 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1239 // type : group on geometry, standalone group, group on filter
1240 if ( !CORBA::is_nil( aStdGroup ) ) {
1241 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1242 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1244 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1245 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1246 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1247 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1248 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1250 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1251 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1254 else if ( !CORBA::is_nil( aFltGroup ) ) {
1255 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1256 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1260 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1261 arg( QString::number( aGrp->Size() ) ) );
1264 SALOMEDS::Color color = aGrp->GetColor();
1265 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1266 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1274 // show element info
1276 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1277 SMESH::Controls::NumericalFunctorPtr afunctor;
1280 // Element ID && Type
1282 switch( e->GetType() ) {
1283 case SMDSAbs_0DElement:
1284 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1286 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1288 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1290 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1291 case SMDSAbs_Volume:
1292 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1296 if ( stype.isEmpty() ) return;
1297 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1299 myInfo->append( "" );
1303 switch( e->GetEntityType() ) {
1304 case SMDSEntity_Triangle:
1305 case SMDSEntity_Quad_Triangle:
1306 case SMDSEntity_BiQuad_Triangle:
1307 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1308 case SMDSEntity_Quadrangle:
1309 case SMDSEntity_Quad_Quadrangle:
1310 case SMDSEntity_BiQuad_Quadrangle:
1311 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1312 case SMDSEntity_Polygon:
1313 case SMDSEntity_Quad_Polygon:
1314 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1315 case SMDSEntity_Tetra:
1316 case SMDSEntity_Quad_Tetra:
1317 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1318 case SMDSEntity_Pyramid:
1319 case SMDSEntity_Quad_Pyramid:
1320 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1321 case SMDSEntity_Hexa:
1322 case SMDSEntity_Quad_Hexa:
1323 case SMDSEntity_TriQuad_Hexa:
1324 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1325 case SMDSEntity_Penta:
1326 case SMDSEntity_Quad_Penta:
1327 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1328 case SMDSEntity_Hexagonal_Prism:
1329 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1330 case SMDSEntity_Polyhedra:
1331 case SMDSEntity_Quad_Polyhedra:
1332 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1336 if ( !gtype.isEmpty() )
1337 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1339 // Quadratic flag (any element except 0D)
1340 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1341 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1343 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1345 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1348 myInfo->append( "" );
1351 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1352 for ( int idx = 1; nodeIt->more(); idx++ ) {
1353 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1354 // node number and ID
1355 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1357 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1358 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1359 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1360 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1361 // node connectivity
1362 Connectivity connectivity = nodeConnectivity( node );
1363 if ( !connectivity.isEmpty() ) {
1364 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1365 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1366 if ( !con.isEmpty() )
1367 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1368 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1369 if ( !con.isEmpty() )
1370 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1371 con = formatConnectivity( connectivity, SMDSAbs_Face );
1372 if ( !con.isEmpty() )
1373 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1374 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1375 if ( !con.isEmpty() )
1376 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1379 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1383 myInfo->append( "" );
1386 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1388 if ( e->GetType() == SMDSAbs_Edge ) {
1389 afunctor.reset( new SMESH::Controls::Length() );
1390 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1391 afunctor->SetPrecision( cprecision );
1392 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1394 if( e->GetType() == SMDSAbs_Face ) {
1396 afunctor.reset( new SMESH::Controls::Area() );
1397 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1398 afunctor->SetPrecision( cprecision );
1399 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1401 afunctor.reset( new SMESH::Controls::Taper() );
1402 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1403 afunctor->SetPrecision( cprecision );
1404 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1406 afunctor.reset( new SMESH::Controls::AspectRatio() );
1407 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1408 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1410 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1411 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1412 afunctor->SetPrecision( cprecision );
1413 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1415 afunctor.reset( new SMESH::Controls::Warping() );
1416 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1417 afunctor->SetPrecision( cprecision );
1418 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1420 afunctor.reset( new SMESH::Controls::Skew() );
1421 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1422 afunctor->SetPrecision( cprecision );
1423 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1425 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1426 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1427 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1429 if( e->GetType() == SMDSAbs_Volume ) {
1431 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1432 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1433 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1435 afunctor.reset( new SMESH::Controls::Volume() );
1436 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1437 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1439 afunctor.reset( new SMESH::Controls::Volume() );
1440 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1441 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1444 myInfo->append( "" );
1447 XYZ gc = gravityCenter( e );
1448 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1451 if( e->GetType() == SMDSAbs_Face ) {
1452 XYZ gc = normal( e );
1453 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1457 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1458 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1459 if ( !CORBA::is_nil( aMesh ) ) {
1460 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1461 int shapeID = pos.shapeID;
1462 if ( shapeID > 0 ) {
1463 myInfo->append( "" ); // separator
1465 switch ( pos.shapeType ) {
1466 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1467 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1468 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1469 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1470 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1471 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1473 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1478 // Groups the element belongs to
1479 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1480 if ( !CORBA::is_nil( aMesh ) ) {
1481 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1482 myInfo->append( "" ); // separator
1483 bool top_created = false;
1484 for ( int i = 0; i < groups->length(); i++ ) {
1485 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1486 if ( CORBA::is_nil( aGrp ) ) continue;
1487 QString aName = aGrp->GetName();
1488 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1489 if ( !top_created ) {
1490 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1493 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1494 if ( grp_details ) {
1495 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1496 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1497 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1499 // type : group on geometry, standalone group, group on filter
1500 if ( !CORBA::is_nil( aStdGroup ) ) {
1501 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1502 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1504 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1505 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1506 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1507 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1508 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1510 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1511 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1514 else if ( !CORBA::is_nil( aFltGroup ) ) {
1515 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1516 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1519 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1520 arg( QString::number( aGrp->Size() ) ) );
1523 SALOMEDS::Color color = aGrp->GetColor();
1524 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1525 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1532 if ( ids.count() > 1 ) {
1533 myInfo->append( "" );
1534 myInfo->append( "------" );
1535 myInfo->append( "" );
1542 \brief Internal clean-up (reset widget)
1544 void SMESHGUI_SimpleElemInfo::clearInternal()
1549 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1551 out << QString( 12, '-' ) << "\n";
1552 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1553 out << QString( 12, '-' ) << "\n";
1554 out << myInfo->toPlainText();
1560 \class SMESHGUI_TreeElemInfo::ItemDelegate
1561 \brief Item delegate for tree mesh info widget
1564 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1567 ItemDelegate( QObject* );
1568 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1575 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1580 \brief Create item editor widget
1583 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1585 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1586 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1591 \class SMESHGUI_TreeElemInfo
1592 \brief Represents mesh element information in the tree-like form.
1597 \param parent parent widget
1599 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1600 : SMESHGUI_ElemInfo( parent )
1602 myInfo = new QTreeWidget( frame() );
1603 myInfo->setColumnCount( 2 );
1604 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1605 myInfo->header()->setStretchLastSection( true );
1606 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1607 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1608 QVBoxLayout* l = new QVBoxLayout( frame() );
1610 l->addWidget( myInfo );
1611 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1615 \brief Show mesh element information
1616 \param ids mesh nodes / elements identifiers
1618 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1623 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1624 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1625 int cprecision = -1;
1626 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1627 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1628 foreach ( long id, ids ) {
1629 if ( !isElements() ) {
1633 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1635 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1638 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1639 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1640 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1642 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1643 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1644 QTreeWidgetItem* xItem = createItem( coordItem );
1645 xItem->setText( 0, "X" );
1646 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1647 QTreeWidgetItem* yItem = createItem( coordItem );
1648 yItem->setText( 0, "Y" );
1649 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1650 QTreeWidgetItem* zItem = createItem( coordItem );
1651 zItem->setText( 0, "Z" );
1652 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1654 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1655 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1656 Connectivity connectivity = nodeConnectivity( node );
1657 if ( !connectivity.isEmpty() ) {
1658 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1659 if ( !con.isEmpty() ) {
1660 QTreeWidgetItem* i = createItem( conItem );
1661 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1662 i->setText( 1, con );
1664 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1665 if ( !con.isEmpty() ) {
1666 QTreeWidgetItem* i = createItem( conItem );
1667 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1668 i->setText( 1, con );
1669 i->setData( 1, TypeRole, NodeConnectivity );
1671 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1672 if ( !con.isEmpty() ) {
1673 QTreeWidgetItem* i = createItem( conItem );
1674 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1675 i->setText( 1, con );
1676 i->setData( 1, TypeRole, NodeConnectivity );
1678 con = formatConnectivity( connectivity, SMDSAbs_Face );
1679 if ( !con.isEmpty() ) {
1680 QTreeWidgetItem* i = createItem( conItem );
1681 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1682 i->setText( 1, con );
1683 i->setData( 1, TypeRole, NodeConnectivity );
1685 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1686 if ( !con.isEmpty() ) {
1687 QTreeWidgetItem* i = createItem( conItem );
1688 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1689 i->setText( 1, con );
1690 i->setData( 1, TypeRole, NodeConnectivity );
1694 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1697 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1698 if ( !CORBA::is_nil( aMeshPtr ) ) {
1699 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1700 int shapeID = pos->shapeID;
1701 if ( shapeID > 0 ) {
1704 switch ( pos->shapeType ) {
1706 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1707 if ( pos->params.length() == 1 )
1711 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1712 if ( pos->params.length() == 2 ) {
1718 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1721 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1724 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1725 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1726 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1727 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1728 QTreeWidgetItem* uItem = createItem( posItem );
1729 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1730 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1731 if ( pos->shapeType == GEOM::FACE ) {
1732 QTreeWidgetItem* vItem = createItem( posItem );
1733 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1734 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1739 // groups node belongs to
1740 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1741 if ( !CORBA::is_nil( aMesh ) ) {
1742 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1743 QTreeWidgetItem* groupsItem = 0;
1744 for ( int i = 0; i < groups->length(); i++ ) {
1745 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1746 if ( CORBA::is_nil( aGrp ) ) continue;
1747 QString aName = aGrp->GetName();
1748 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1749 if ( !groupsItem ) {
1750 groupsItem = createItem( nodeItem, Bold );
1751 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1753 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1754 it->setText( 0, aName.trimmed() );
1755 if ( grp_details ) {
1756 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1757 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1758 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1760 // type : group on geometry, standalone group, group on filter
1761 QTreeWidgetItem* typeItem = createItem( it );
1762 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1763 if ( !CORBA::is_nil( aStdGroup ) ) {
1764 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1766 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1767 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1768 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1769 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1771 QTreeWidgetItem* gobjItem = createItem( typeItem );
1772 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1773 gobjItem->setText( 1, sobj->GetName().c_str() );
1776 else if ( !CORBA::is_nil( aFltGroup ) ) {
1777 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1781 QTreeWidgetItem* sizeItem = createItem( it );
1782 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1783 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1786 SALOMEDS::Color color = aGrp->GetColor();
1787 QTreeWidgetItem* colorItem = createItem( it );
1788 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1789 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1797 // show element info
1799 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1800 SMESH::Controls::NumericalFunctorPtr afunctor;
1803 // element ID && type
1805 switch( e->GetType() ) {
1806 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1807 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1808 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1809 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1810 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1813 if ( stype.isEmpty() ) return;
1814 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1815 elemItem->setText( 0, stype );
1816 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1819 switch( e->GetEntityType() ) {
1820 case SMDSEntity_Triangle:
1821 case SMDSEntity_Quad_Triangle:
1822 case SMDSEntity_BiQuad_Triangle:
1823 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1824 case SMDSEntity_Quadrangle:
1825 case SMDSEntity_Quad_Quadrangle:
1826 case SMDSEntity_BiQuad_Quadrangle:
1827 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1828 case SMDSEntity_Polygon:
1829 case SMDSEntity_Quad_Polygon:
1830 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1831 case SMDSEntity_Tetra:
1832 case SMDSEntity_Quad_Tetra:
1833 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1834 case SMDSEntity_Pyramid:
1835 case SMDSEntity_Quad_Pyramid:
1836 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1837 case SMDSEntity_Hexa:
1838 case SMDSEntity_Quad_Hexa:
1839 case SMDSEntity_TriQuad_Hexa:
1840 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1841 case SMDSEntity_Penta:
1842 case SMDSEntity_Quad_Penta:
1843 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1844 case SMDSEntity_Hexagonal_Prism:
1845 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1846 case SMDSEntity_Polyhedra:
1847 case SMDSEntity_Quad_Polyhedra:
1848 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1852 if ( !gtype.isEmpty() ) {
1853 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1854 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1855 typeItem->setText( 1, gtype );
1857 // quadratic flag (for edges, faces and volumes)
1858 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1860 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1861 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1862 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1864 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1866 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1867 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1868 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1871 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1872 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1875 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1876 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1877 for ( int idx = 1; nodeIt->more(); idx++ ) {
1878 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1879 nodeInfo( node, idx, e->NbNodes(), conItem );
1883 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1884 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1885 QList<const SMDS_MeshElement*> uniqueNodes;
1886 while ( nodeIt->more() )
1887 uniqueNodes.append( nodeIt->next() );
1889 SMDS_VolumeTool vtool( e );
1890 const int nbFaces = vtool.NbFaces();
1891 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1892 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1893 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1894 faceItem->setExpanded( true );
1896 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1897 const int nbNodes = vtool.NbFaceNodes( face_id );
1898 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1899 const SMDS_MeshNode* node = aNodeIds[node_id];
1900 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1905 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1906 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1908 if( e->GetType()==SMDSAbs_Edge){
1909 afunctor.reset( new SMESH::Controls::Length() );
1910 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1911 afunctor->SetPrecision( cprecision );
1912 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1913 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1914 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1916 if( e->GetType() == SMDSAbs_Face ) {
1918 afunctor.reset( new SMESH::Controls::Area() );
1919 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1920 afunctor->SetPrecision( cprecision );
1921 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1922 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1923 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1925 afunctor.reset( new SMESH::Controls::Taper() );
1926 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1927 afunctor->SetPrecision( cprecision );
1928 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1929 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1930 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1932 afunctor.reset( new SMESH::Controls::AspectRatio() );
1933 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1934 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1935 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1936 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1938 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1939 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1940 afunctor->SetPrecision( cprecision );
1941 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
1942 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
1943 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1945 afunctor.reset( new SMESH::Controls::Warping() );
1946 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1947 afunctor->SetPrecision( cprecision );
1948 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1949 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1950 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1952 afunctor.reset( new SMESH::Controls::Skew() );
1953 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1954 afunctor->SetPrecision( cprecision );
1955 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
1956 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
1957 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1959 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1960 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1961 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
1962 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
1963 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1965 if( e->GetType() == SMDSAbs_Volume ) {
1967 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1968 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1969 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
1970 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
1971 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1973 afunctor.reset( new SMESH::Controls::Volume() );
1974 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1975 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
1976 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
1977 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1979 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
1980 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1981 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
1982 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
1983 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1987 XYZ gc = gravityCenter( e );
1988 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
1989 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
1990 QTreeWidgetItem* xItem = createItem( gcItem );
1991 xItem->setText( 0, "X" );
1992 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1993 QTreeWidgetItem* yItem = createItem( gcItem );
1994 yItem->setText( 0, "Y" );
1995 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1996 QTreeWidgetItem* zItem = createItem( gcItem );
1997 zItem->setText( 0, "Z" );
1998 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2001 if( e->GetType() == SMDSAbs_Face ) {
2002 XYZ gc = normal( e );
2003 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2004 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2005 QTreeWidgetItem* xItem = createItem( nItem );
2006 xItem->setText( 0, "X" );
2007 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2008 QTreeWidgetItem* yItem = createItem( nItem );
2009 yItem->setText( 0, "Y" );
2010 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2011 QTreeWidgetItem* zItem = createItem( nItem );
2012 zItem->setText( 0, "Z" );
2013 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2017 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2018 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2019 if ( !CORBA::is_nil( aMesh ) ) {
2020 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2021 int shapeID = pos.shapeID;
2022 if ( shapeID > 0 ) {
2023 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2025 switch ( pos.shapeType ) {
2026 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2027 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2028 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2029 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2030 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2031 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2033 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2034 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2038 // groups element belongs to
2039 if ( !CORBA::is_nil( aMesh ) ) {
2040 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2041 QTreeWidgetItem* groupsItem = 0;
2042 for ( int i = 0; i < groups->length(); i++ ) {
2043 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2044 if ( CORBA::is_nil( aGrp ) ) continue;
2045 QString aName = aGrp->GetName();
2046 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2047 if ( !groupsItem ) {
2048 groupsItem = createItem( elemItem, Bold );
2049 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2051 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2052 it->setText( 0, aName.trimmed() );
2053 if ( grp_details ) {
2054 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2055 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2056 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2058 // type : group on geometry, standalone group, group on filter
2059 QTreeWidgetItem* typeItem = createItem( it );
2060 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2061 if ( !CORBA::is_nil( aStdGroup ) ) {
2062 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2064 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2065 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2066 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2067 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2069 QTreeWidgetItem* gobjItem = createItem( typeItem );
2070 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2071 gobjItem->setText( 1, sobj->GetName().c_str() );
2074 else if ( !CORBA::is_nil( aFltGroup ) ) {
2075 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2079 QTreeWidgetItem* sizeItem = createItem( it );
2080 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2081 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2084 SALOMEDS::Color color = aGrp->GetColor();
2085 QTreeWidgetItem* colorItem = createItem( it );
2086 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2087 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2098 \brief Show node information
2099 \param node mesh node for showing
2100 \param index index of current node
2101 \param nbNodes number of unique nodes in element
2102 \param parentItem parent item of tree
2104 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2105 int nbNodes, QTreeWidgetItem* parentItem )
2107 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2108 // node number and ID
2109 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2110 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2111 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2112 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2113 nodeItem->setData( 1, IdRole, node->GetID() );
2114 nodeItem->setExpanded( false );
2116 QTreeWidgetItem* coordItem = createItem( nodeItem );
2117 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2118 QTreeWidgetItem* xItem = createItem( coordItem );
2119 xItem->setText( 0, "X" );
2120 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2121 QTreeWidgetItem* yItem = createItem( coordItem );
2122 yItem->setText( 0, "Y" );
2123 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2124 QTreeWidgetItem* zItem = createItem( coordItem );
2125 zItem->setText( 0, "Z" );
2126 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2127 // node connectivity
2128 QTreeWidgetItem* nconItem = createItem( nodeItem );
2129 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2130 Connectivity connectivity = nodeConnectivity( node );
2131 if ( !connectivity.isEmpty() ) {
2132 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2133 if ( !con.isEmpty() ) {
2134 QTreeWidgetItem* i = createItem( nconItem );
2135 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2136 i->setText( 1, con );
2138 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2139 if ( !con.isEmpty() ) {
2140 QTreeWidgetItem* i = createItem( nconItem );
2141 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2142 i->setText( 1, con );
2143 i->setData( 1, TypeRole, NodeConnectivity );
2145 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2146 if ( !con.isEmpty() ) {
2147 QTreeWidgetItem* i = createItem( nconItem );
2148 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2149 i->setText( 1, con );
2150 i->setData( 1, TypeRole, NodeConnectivity );
2152 con = formatConnectivity( connectivity, SMDSAbs_Face );
2153 if ( !con.isEmpty() ) {
2154 QTreeWidgetItem* i = createItem( nconItem );
2155 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2156 i->setText( 1, con );
2157 i->setData( 1, TypeRole, NodeConnectivity );
2159 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2160 if ( !con.isEmpty() ) {
2161 QTreeWidgetItem* i = createItem( nconItem );
2162 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2163 i->setText( 1, con );
2164 i->setData( 1, TypeRole, NodeConnectivity );
2169 \brief Internal clean-up (reset widget)
2171 void SMESHGUI_TreeElemInfo::clearInternal()
2178 \brief Create new tree item.
2179 \param parent parent tree widget item
2180 \param flags item flag
2181 \return new tree widget item
2183 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2185 QTreeWidgetItem* item;
2187 item = new QTreeWidgetItem( parent );
2189 item = new QTreeWidgetItem( myInfo );
2191 item->setFlags( item->flags() | Qt::ItemIsEditable );
2193 QFont f = item->font( 0 );
2195 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2196 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2197 item->setFont( i, f );
2200 item->setExpanded( true );
2204 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2206 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2207 if ( widgets.isEmpty() ) return;
2208 QTreeWidgetItem* aTreeItem = widgets.first();
2209 int type = aTreeItem->data( 1, TypeRole ).toInt();
2210 int id = aTreeItem->data( 1, IdRole ).toInt();
2212 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2213 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2214 emit( itemInfo( id ) );
2215 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2216 emit( itemInfo( aTreeItem->text( 1 ) ) );
2219 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2222 int type = theItem->data( 1, TypeRole ).toInt();
2223 int id = theItem->data( 1, IdRole ).toInt();
2224 if ( type == ElemConnectivity && id > 0 )
2225 emit( itemInfo( id ) );
2226 else if ( type == NodeConnectivity )
2227 emit( itemInfo( theItem->text( 1 ) ) );
2231 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2233 out << QString( 12, '-' ) << "\n";
2234 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2235 out << QString( 12, '-' ) << "\n";
2237 QTreeWidgetItemIterator it( myInfo );
2239 if ( !( *it )->text(0).isEmpty() ) {
2240 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2241 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2251 \brief Mesh information computer
2254 The class is created for different computation operation. Currently it is used
2255 to compute number of underlying nodes for the groups.
2261 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2262 QTreeWidgetItem* item,
2265 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2267 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2271 \brief Compute function
2273 void GrpComputor::compute()
2275 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2276 QTreeWidgetItem* item = myItem;
2278 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2279 item->treeWidget()->removeItemWidget( item, 1 );
2280 item->setText( 1, QString::number( nb ));
2285 \class SMESHGUI_AddInfo
2286 \brief The wigdet shows additional information on the mesh object.
2291 \param parent parent widget
2293 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2294 : QTreeWidget( parent )
2296 setColumnCount( 2 );
2297 header()->setStretchLastSection( true );
2298 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2305 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2310 \brief Show additional information on the selected object
2311 \param obj object being processed (mesh, sub-mesh, group, ID source)
2313 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2315 setProperty( "group_index", 0 );
2316 setProperty( "submesh_index", 0 );
2317 myComputors.clear();
2320 if ( CORBA::is_nil( obj ) ) return;
2322 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2323 if ( !sobj ) return;
2326 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2327 nameItem->setText( 0, tr( "NAME" ) );
2328 nameItem->setText( 1, sobj->GetName().c_str() );
2330 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2331 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2332 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2334 if ( !aMesh->_is_nil() )
2335 meshInfo( aMesh, nameItem );
2336 else if ( !aSubMesh->_is_nil() )
2337 subMeshInfo( aSubMesh, nameItem );
2338 else if ( !aGroup->_is_nil() )
2339 groupInfo( aGroup.in(), nameItem );
2343 \brief Create new tree item.
2344 \param parent parent tree widget item
2345 \param flags item flag
2346 \return new tree widget item
2348 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2350 QTreeWidgetItem* item;
2353 item = new QTreeWidgetItem( parent );
2355 item = new QTreeWidgetItem( this );
2357 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2359 QFont f = item->font( 0 );
2361 for ( int i = 0; i < columnCount(); i++ ) {
2362 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2363 item->setFont( i, f );
2366 item->setExpanded( true );
2371 \brief Show mesh info
2372 \param mesh mesh object
2373 \param parent parent tree item
2375 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2378 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2379 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2380 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2381 typeItem->setText( 0, tr( "TYPE" ) );
2382 if ( !CORBA::is_nil( shape ) ) {
2383 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2384 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2386 QTreeWidgetItem* gobjItem = createItem( typeItem );
2387 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2388 gobjItem->setText( 1, sobj->GetName().c_str() );
2391 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2392 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2393 QTreeWidgetItem* fileItem = createItem( typeItem );
2394 fileItem->setText( 0, tr( "FILE_NAME" ) );
2395 fileItem->setText( 1, (char*)inf->fileName );
2398 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2402 myGroups = mesh->GetGroups();
2406 mySubMeshes = mesh->GetSubMeshes();
2411 \brief Show sub-mesh info
2412 \param subMesh sub-mesh object
2413 \param parent parent tree item
2415 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2417 bool isShort = parent->parent() != 0;
2421 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2423 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2424 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2425 nameItem->setText( 1, sobj->GetName().c_str() );
2430 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2431 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2433 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2434 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2435 gobjItem->setText( 1, sobj->GetName().c_str() );
2440 \brief Show group info
2441 \param grp mesh group object
2442 \param parent parent tree item
2444 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2446 bool isShort = parent->parent() != 0;
2448 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2449 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2450 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2454 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2456 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2457 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2458 nameItem->setText( 1, sobj->GetName().c_str() );
2462 // type : group on geometry, standalone group, group on filter
2463 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2464 typeItem->setText( 0, tr( "TYPE" ) );
2465 if ( !CORBA::is_nil( aStdGroup ) ) {
2466 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2468 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2469 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2470 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2471 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2473 QTreeWidgetItem* gobjItem = createItem( typeItem );
2474 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2475 gobjItem->setText( 1, sobj->GetName().c_str() );
2478 else if ( !CORBA::is_nil( aFltGroup ) ) {
2479 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2484 QString etype = tr( "UNKNOWN" );
2485 switch( grp->GetType() ) {
2487 etype = tr( "NODE" );
2490 etype = tr( "EDGE" );
2493 etype = tr( "FACE" );
2496 etype = tr( "VOLUME" );
2499 etype = tr( "0DELEM" );
2502 etype = tr( "BALL" );
2507 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2508 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2509 etypeItem->setText( 1, etype );
2512 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2513 bool meshLoaded = mesh->IsLoaded();
2515 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2517 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2518 groupSize = grp->Size();
2520 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2521 sizeItem->setText( 0, tr( "SIZE" ) );
2522 if ( groupSize > -1 ) {
2523 sizeItem->setText( 1, QString::number( groupSize ) );
2526 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2527 setItemWidget( sizeItem, 1, btn );
2528 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2529 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2530 myComputors.append( comp );
2532 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2536 SALOMEDS::Color color = grp->GetColor();
2537 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2538 colorItem->setText( 0, tr( "COLOR" ) );
2539 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2541 // nb of underlying nodes
2542 if ( grp->GetType() != SMESH::NODE) {
2543 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2544 nodesItem->setText( 0, tr( "NB_NODES" ) );
2545 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2546 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2547 if ( toShowNodes && meshLoaded ) {
2548 // already calculated and up-to-date
2549 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2552 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2553 setItemWidget( nodesItem, 1, btn );
2554 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2555 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2556 myComputors.append( comp );
2558 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2563 void SMESHGUI_AddInfo::showGroups()
2565 myComputors.clear();
2567 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2568 if ( !parent ) return;
2570 int idx = property( "group_index" ).toInt();
2572 QTreeWidgetItem* itemGroups = 0;
2573 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2574 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2575 itemGroups = parent->child( i );
2576 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2578 extra->updateControls( myGroups->length(), idx );
2579 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2583 QMap<int, QTreeWidgetItem*> grpItems;
2584 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2585 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2586 if ( CORBA::is_nil( grp ) ) continue;
2587 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2588 if ( !grpSObj ) continue;
2590 int grpType = grp->GetType();
2592 if ( !itemGroups ) {
2593 // create top-level groups container item
2594 itemGroups = createItem( parent, Bold | All );
2595 itemGroups->setText( 0, tr( "GROUPS" ) );
2596 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2598 // total number of groups > 10, show extra widgets for info browsing
2599 if ( myGroups->length() > MAXITEMS ) {
2600 ExtraWidget* extra = new ExtraWidget( this, true );
2601 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2602 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2603 setItemWidget( itemGroups, 1, extra );
2604 extra->updateControls( myGroups->length(), idx );
2608 if ( grpItems.find( grpType ) == grpItems.end() ) {
2609 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2610 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2611 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2615 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2616 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2619 groupInfo( grp.in(), grpNameItem );
2623 void SMESHGUI_AddInfo::showSubMeshes()
2625 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2626 if ( !parent ) return;
2628 int idx = property( "submesh_index" ).toInt();
2630 QTreeWidgetItem* itemSubMeshes = 0;
2631 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2632 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2633 itemSubMeshes = parent->child( i );
2634 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2636 extra->updateControls( mySubMeshes->length(), idx );
2637 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2641 QMap<int, QTreeWidgetItem*> smItems;
2642 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2643 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2644 if ( CORBA::is_nil( sm ) ) continue;
2645 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2646 if ( !smSObj ) continue;
2648 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2649 if ( CORBA::is_nil(gobj ) ) continue;
2651 int smType = gobj->GetShapeType();
2652 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2654 if ( !itemSubMeshes ) {
2655 itemSubMeshes = createItem( parent, Bold | All );
2656 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2657 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2659 // total number of sub-meshes > 10, show extra widgets for info browsing
2660 if ( mySubMeshes->length() > MAXITEMS ) {
2661 ExtraWidget* extra = new ExtraWidget( this, true );
2662 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2663 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2664 setItemWidget( itemSubMeshes, 1, extra );
2665 extra->updateControls( mySubMeshes->length(), idx );
2669 if ( smItems.find( smType ) == smItems.end() ) {
2670 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2671 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2672 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2676 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2677 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2680 subMeshInfo( sm.in(), smNameItem );
2685 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2687 void SMESHGUI_AddInfo::changeLoadToCompute()
2689 for ( int i = 0; i < myComputors.count(); ++i )
2691 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2693 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2694 btn->setText( tr("COMPUTE") );
2699 void SMESHGUI_AddInfo::showPreviousGroups()
2701 int idx = property( "group_index" ).toInt();
2702 setProperty( "group_index", idx-1 );
2706 void SMESHGUI_AddInfo::showNextGroups()
2708 int idx = property( "group_index" ).toInt();
2709 setProperty( "group_index", idx+1 );
2713 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2715 int idx = property( "submesh_index" ).toInt();
2716 setProperty( "submesh_index", idx-1 );
2720 void SMESHGUI_AddInfo::showNextSubMeshes()
2722 int idx = property( "submesh_index" ).toInt();
2723 setProperty( "submesh_index", idx+1 );
2727 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2729 out << QString( 15, '-') << "\n";
2730 out << tr( "ADDITIONAL_INFO" ) << "\n";
2731 out << QString( 15, '-' ) << "\n";
2732 QTreeWidgetItemIterator it( this );
2734 if ( !( ( *it )->text(0) ).isEmpty() ) {
2735 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2736 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2737 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2739 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2748 \class SMESHGUI_MeshInfoDlg
2749 \brief Mesh information dialog box
2754 \param parent parent widget
2755 \param page specifies the dialog page to be shown at the start-up
2757 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2758 : QDialog( parent ), myActor( 0 )
2761 setAttribute( Qt::WA_DeleteOnClose, true );
2762 setWindowTitle( tr( "MESH_INFO" ) );
2763 setSizeGripEnabled( true );
2765 myTabWidget = new QTabWidget( this );
2769 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2770 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2774 QWidget* w = new QWidget( myTabWidget );
2776 myMode = new QButtonGroup( this );
2777 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2778 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2779 myMode->button( NodeMode )->setChecked( true );
2780 myID = new QLineEdit( w );
2781 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2783 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2784 mode = qMin( 1, qMax( 0, mode ) );
2787 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2789 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2791 QGridLayout* elemLayout = new QGridLayout( w );
2792 elemLayout->setMargin( MARGIN );
2793 elemLayout->setSpacing( SPACING );
2794 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2795 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2796 elemLayout->addWidget( myID, 0, 2 );
2797 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2799 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2803 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2804 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2808 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2809 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2813 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2814 okBtn->setAutoDefault( true );
2815 okBtn->setDefault( true );
2817 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2818 dumpBtn->setAutoDefault( true );
2819 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2820 helpBtn->setAutoDefault( true );
2822 QHBoxLayout* btnLayout = new QHBoxLayout;
2823 btnLayout->setSpacing( SPACING );
2824 btnLayout->setMargin( 0 );
2826 btnLayout->addWidget( okBtn );
2827 btnLayout->addWidget( dumpBtn );
2828 btnLayout->addStretch( 10 );
2829 btnLayout->addWidget( helpBtn );
2831 QVBoxLayout* l = new QVBoxLayout ( this );
2832 l->setMargin( MARGIN );
2833 l->setSpacing( SPACING );
2834 l->addWidget( myTabWidget );
2835 l->addLayout( btnLayout );
2837 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2839 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2840 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2841 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2842 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2843 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2844 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2845 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2846 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2847 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2848 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2856 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2861 \brief Show mesh information
2862 \param IO interactive object
2864 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2866 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2867 if ( !CORBA::is_nil( obj ) ) {
2868 myBaseInfo->showInfo( obj );
2869 myAddInfo->showInfo( obj );
2870 myCtrlInfo->showInfo( obj );
2872 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2873 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
2876 if ( myActor && selector ) {
2877 nb = myMode->checkedId() == NodeMode ?
2878 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2879 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2881 myElemInfo->setSource( myActor ) ;
2883 myID->setText( ID.trimmed() );
2885 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2886 foreach ( ID, idTxt )
2887 ids << ID.trimmed().toLong();
2888 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2892 myElemInfo->clear();
2898 \brief Perform clean-up actions on the dialog box closing.
2900 void SMESHGUI_MeshInfoDlg::reject()
2902 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2903 selMgr->clearFilters();
2904 SMESH::SetPointRepresentation( false );
2905 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2906 aViewWindow->SetSelectionMode( ActorSelection );
2911 \brief Process keyboard event
2912 \param e key press event
2914 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2916 QDialog::keyPressEvent( e );
2917 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2924 \brief Reactivate dialog box, when mouse pointer goes into it.
2926 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2932 \brief Setup selection mode depending on the current dialog box state.
2934 void SMESHGUI_MeshInfoDlg::updateSelection()
2936 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2938 disconnect( selMgr, 0, this, 0 );
2939 selMgr->clearFilters();
2941 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2942 SMESH::SetPointRepresentation( false );
2943 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2944 aViewWindow->SetSelectionMode( ActorSelection );
2947 if ( myMode->checkedId() == NodeMode ) {
2948 SMESH::SetPointRepresentation( true );
2949 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2950 aViewWindow->SetSelectionMode( NodeSelection );
2953 SMESH::SetPointRepresentation( false );
2954 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2955 aViewWindow->SetSelectionMode( CellSelection );
2959 QString oldID = myID->text().trimmed();
2960 SMESH_Actor* oldActor = myActor;
2963 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
2966 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
2967 myID->setText( oldID );
2973 \brief Show help page
2975 void SMESHGUI_MeshInfoDlg::help()
2977 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
2978 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
2979 "mesh_infos_page.html#mesh_element_info_anchor" );
2983 \brief Show mesh information
2985 void SMESHGUI_MeshInfoDlg::updateInfo()
2987 SUIT_OverrideCursor wc;
2989 SALOME_ListIO selected;
2990 SMESHGUI::selectionMgr()->selectedObjects( selected );
2992 if ( selected.Extent() == 1 ) {
2993 Handle(SALOME_InteractiveObject) IO = selected.First();
2997 // myBaseInfo->clear();
2998 // myElemInfo->clear();
2999 // myAddInfo->clear();
3004 \brief Activate dialog box
3006 void SMESHGUI_MeshInfoDlg::activate()
3008 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3009 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3010 myTabWidget->setEnabled( true );
3015 \brief Deactivate dialog box
3017 void SMESHGUI_MeshInfoDlg::deactivate()
3019 myTabWidget->setEnabled( false );
3020 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3024 \brief Called when users switches between node / element modes.
3026 void SMESHGUI_MeshInfoDlg::modeChanged()
3033 \brief Caled when users prints mesh element ID in the corresponding field.
3035 void SMESHGUI_MeshInfoDlg::idChanged()
3037 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
3038 if ( myActor && selector ) {
3039 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3040 TColStd_MapOfInteger ID;
3042 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3043 foreach ( QString tid, idTxt ) {
3044 long id = tid.trimmed().toLong();
3045 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3046 myActor->GetObject()->GetMesh()->FindElement( id ) :
3047 myActor->GetObject()->GetMesh()->FindNode( id );
3053 selector->AddOrRemoveIndex( IO, ID, false );
3054 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3055 aViewWindow->highlight( IO, true, true );
3056 aViewWindow->Repaint();
3058 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3062 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3064 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3065 myMode->button( NodeMode )->click();
3066 myID->setText( QString::number( id ) );
3070 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3072 if ( !theStr.isEmpty() ) {
3073 myMode->button( ElemMode )->click();
3074 myID->setText( theStr );
3078 void SMESHGUI_MeshInfoDlg::dump()
3080 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3082 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3083 if ( !appStudy ) return;
3084 _PTR( Study ) aStudy = appStudy->studyDS();
3086 QStringList aFilters;
3087 aFilters.append( tr( "TEXT_FILES" ) );
3089 bool anIsBase = true;
3090 bool anIsElem = true;
3091 bool anIsAdd = true;
3092 bool anIsCtrl = true;
3094 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3095 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3096 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3097 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3098 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3101 DumpFileDlg fd( this );
3102 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3103 fd.setFilters( aFilters );
3104 fd.myBaseChk->setChecked( anIsBase );
3105 fd.myElemChk->setChecked( anIsElem );
3106 fd.myAddChk ->setChecked( anIsAdd );
3107 fd.myCtrlChk->setChecked( anIsCtrl );
3108 if ( fd.exec() == QDialog::Accepted )
3110 QString aFileName = fd.selectedFile();
3112 bool toBase = fd.myBaseChk->isChecked();
3113 bool toElem = fd.myElemChk->isChecked();
3114 bool toAdd = fd.myAddChk->isChecked();
3115 bool toCtrl = fd.myCtrlChk->isChecked();
3117 if ( !aFileName.isEmpty() ) {
3118 QFileInfo aFileInfo( aFileName );
3119 if ( aFileInfo.isDir() )
3122 QFile aFile( aFileName );
3123 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3126 QTextStream out( &aFile );
3128 if ( toBase ) myBaseInfo->saveInfo( out );
3129 if ( toElem ) myElemInfo->saveInfo( out );
3130 if ( toAdd ) myAddInfo ->saveInfo( out );
3131 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3137 \class SMESHGUI_CtrlInfo
3138 \brief Class for the mesh controls information widget.
3143 \param parent parent widget
3145 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3146 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3148 setFrameStyle( StyledPanel | Sunken );
3150 myMainLayout = new QGridLayout( this );
3151 myMainLayout->setMargin( MARGIN );
3152 myMainLayout->setSpacing( SPACING );
3155 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3156 QLabel* aName = createField();
3157 aName->setMinimumWidth( 150 );
3160 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3161 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3163 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3166 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3167 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3168 QLabel* aNodesFree = createField();
3169 myWidgets << aNodesFree;
3170 myPredicates << aFilterMgr->CreateFreeNodes();
3172 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3173 QLabel* aNodesDouble = createField();
3174 myWidgets << aNodesDouble;
3175 myPredicates << aFilterMgr->CreateEqualNodes();
3176 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3177 myToleranceWidget = new SMESHGUI_SpinBox( this );
3178 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3179 myToleranceWidget->setAcceptNames( false );
3180 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3183 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3184 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3185 QLabel* anEdgesDouble = createField();
3186 myWidgets << anEdgesDouble;
3187 myPredicates << aFilterMgr->CreateEqualEdges();
3190 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3191 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3192 QLabel* aFacesDouble = createField();
3193 myWidgets << aFacesDouble;
3194 myPredicates << aFilterMgr->CreateEqualFaces();
3195 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3196 QLabel* aFacesOver = createField();
3197 myWidgets << aFacesOver;
3198 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3199 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3200 myPlot = createPlot( this );
3201 myAspectRatio = aFilterMgr->CreateAspectRatio();
3204 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3205 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3206 QLabel* aVolumesDouble = createField();
3207 myWidgets << aVolumesDouble;
3208 myPredicates << aFilterMgr->CreateEqualVolumes();
3209 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3210 QLabel* aVolumesOver = createField();
3211 myWidgets << aVolumesOver;
3212 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3213 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3214 myPlot3D = createPlot( this );
3215 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3217 QToolButton* aFreeNodesBtn = new QToolButton( this );
3218 aFreeNodesBtn->setIcon(aComputeIcon);
3219 myButtons << aFreeNodesBtn; //0
3221 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3222 aDoubleNodesBtn->setIcon(aComputeIcon);
3223 myButtons << aDoubleNodesBtn; //1
3225 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3226 aDoubleEdgesBtn->setIcon(aComputeIcon);
3227 myButtons << aDoubleEdgesBtn; //2
3229 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3230 aDoubleFacesBtn->setIcon(aComputeIcon);
3231 myButtons << aDoubleFacesBtn; //3
3233 QToolButton* aOverContFacesBtn = new QToolButton( this );
3234 aOverContFacesBtn->setIcon(aComputeIcon);
3235 myButtons << aOverContFacesBtn; //4
3237 QToolButton* aComputeFaceBtn = new QToolButton( this );
3238 aComputeFaceBtn->setIcon(aComputeIcon);
3239 myButtons << aComputeFaceBtn; //5
3241 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3242 aDoubleVolumesBtn->setIcon(aComputeIcon);
3243 myButtons << aDoubleVolumesBtn; //6
3245 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3246 aOverContVolumesBtn->setIcon(aComputeIcon);
3247 myButtons << aOverContVolumesBtn; //7
3249 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3250 aComputeVolumeBtn->setIcon(aComputeIcon);
3251 myButtons << aComputeVolumeBtn; //8
3253 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3254 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3255 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3256 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3257 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3258 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3259 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3260 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3261 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3262 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3264 setFontAttributes( aNameLab );
3265 setFontAttributes( aNodesLab );
3266 setFontAttributes( anEdgesLab );
3267 setFontAttributes( aFacesLab );
3268 setFontAttributes( aVolumesLab );
3270 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3271 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3272 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3273 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3274 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3275 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3276 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3277 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3278 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3279 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3280 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3281 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3282 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3283 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3284 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3285 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3286 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3287 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3288 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3289 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3290 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3291 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3292 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3293 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3294 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3295 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3296 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3297 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3298 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3299 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3300 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3301 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3302 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3303 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3304 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3306 myMainLayout->setColumnStretch( 0, 0 );
3307 myMainLayout->setColumnStretch( 1, 5 );
3308 myMainLayout->setRowStretch ( 11, 5 );
3309 myMainLayout->setRowStretch ( 16, 5 );
3310 myMainLayout->setRowStretch ( 17, 1 );
3318 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3322 \brief Change widget font attributes (bold, ...).
3324 \param attr font attributes (XORed flags)
3326 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3329 QFont f = w->font();
3336 \brief Create info field
3337 \return new info field
3339 QLabel* SMESHGUI_CtrlInfo::createField()
3341 QLabel* lab = new QLabel( this );
3342 lab->setFrameStyle( StyledPanel | Sunken );
3343 lab->setAlignment( Qt::AlignCenter );
3344 lab->setAutoFillBackground( true );
3345 QPalette pal = lab->palette();
3346 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3347 lab->setPalette( pal );
3348 lab->setMinimumWidth( 60 );
3353 \brief Create QwtPlot
3356 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3358 QwtPlot* aPlot = new QwtPlot( parent );
3359 aPlot->setMinimumSize( 100, 100 );
3360 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3361 xFont.setPointSize( 5 );
3362 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3363 yFont.setPointSize( 5 );
3364 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3365 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3371 \brief Show controls information on the selected object
3373 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3377 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3378 if ( myObject->_is_nil() ) return;
3380 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3381 myWidgets[0]->setText( aSO->GetName().c_str() );
3383 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3384 if ( mesh->_is_nil() ) return;
3386 const bool meshLoaded = mesh->IsLoaded();
3387 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3388 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3389 for ( int i = 0; i < myButtons.count(); ++i )
3390 myButtons[i]->setEnabled( true );
3392 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3393 if ( ! &nbElemsByType.in() ) return;
3395 const CORBA::Long ctrlLimit =
3396 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3399 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3400 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3401 nbElemsByType[ SMESH::FACE ] +
3402 nbElemsByType[ SMESH::VOLUME ] );
3403 if ( nbNodes + nbElems > 0 ) {
3404 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3406 computeFreeNodesInfo();
3408 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3409 computeDoubleNodesInfo();
3412 myButtons[0]->setEnabled( true );
3413 myButtons[1]->setEnabled( true );
3417 for( int i=2; i<=10; i++)
3418 myMainLayout->itemAt(i)->widget()->setVisible( false );
3422 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3424 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3425 computeDoubleEdgesInfo();
3427 myButtons[2]->setEnabled( true );
3430 for( int i=11; i<=14; i++)
3431 myMainLayout->itemAt(i)->widget()->setVisible( false );
3435 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3436 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3438 computeDoubleFacesInfo();
3439 // over constrained faces
3440 computeOverConstrainedFacesInfo();
3441 // aspect Ratio histogram
3442 computeAspectRatio();
3445 myButtons[3]->setEnabled( true );
3446 myButtons[4]->setEnabled( true );
3447 myButtons[5]->setEnabled( true );
3449 #ifdef DISABLE_PLOT2DVIEWER
3450 myMainLayout->setRowStretch(11,0);
3451 for( int i=22; i<=24; i++)
3452 myMainLayout->itemAt(i)->widget()->setVisible( false );
3456 myMainLayout->setRowStretch(11,0);
3457 for( int i=15; i<=24; i++)
3458 myMainLayout->itemAt(i)->widget()->setVisible( false );
3462 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3463 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3465 computeDoubleVolumesInfo();
3466 // over constrained volumes
3467 computeOverConstrainedVolumesInfo();
3468 // aspect Ratio 3D histogram
3469 computeAspectRatio3D();
3472 myButtons[6]->setEnabled( true );
3473 myButtons[7]->setEnabled( true );
3474 myButtons[8]->setEnabled( true );
3476 #ifdef DISABLE_PLOT2DVIEWER
3477 myMainLayout->setRowStretch(16,0);
3478 for( int i=32; i<=34; i++)
3479 myMainLayout->itemAt(i)->widget()->setVisible( false );
3483 myMainLayout->setRowStretch(16,0);
3484 for( int i=25; i<=34; i++)
3485 myMainLayout->itemAt(i)->widget()->setVisible( false );
3489 //================================================================================
3491 * \brief Computes and shows nb of elements satisfying a given predicate
3492 * \param [in] ft - a predicate type (SMESH::FunctorType)
3493 * \param [in] iBut - index of one of myButtons to disable
3494 * \param [in] iWdg - index of one of myWidgets to show the computed number
3496 //================================================================================
3498 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3500 myButtons[ iBut ]->setEnabled( false );
3501 myWidgets[ iWdg ]->setText( "" );
3502 if ( myObject->_is_nil() ) return;
3504 SUIT_OverrideCursor wc;
3506 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3507 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3510 this->showInfo( myObject ); // try to show all values
3511 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3512 return; // <ft> predicate already computed
3514 // look for a predicate of type <ft>
3515 for ( int i = 0; i < myPredicates.count(); ++i )
3516 if ( myPredicates[i]->GetFunctorType() == ft )
3518 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3519 myWidgets[ iWdg ]->setText( QString::number( nb ));
3523 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3525 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3528 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3530 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3533 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3535 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3538 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3540 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3543 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3545 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3548 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3550 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3553 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3555 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3558 void SMESHGUI_CtrlInfo::computeAspectRatio()
3560 #ifndef DISABLE_PLOT2DVIEWER
3561 myButtons[5]->setEnabled( false );
3563 if ( myObject->_is_nil() ) return;
3565 SUIT_OverrideCursor wc;
3567 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3568 if ( aHistogram && !aHistogram->isEmpty() ) {
3569 QwtPlotItem* anItem = aHistogram->createPlotItem();
3570 anItem->attach( myPlot );
3577 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3579 #ifndef DISABLE_PLOT2DVIEWER
3580 myButtons[8]->setEnabled( false );
3582 if ( myObject->_is_nil() ) return;
3584 SUIT_OverrideCursor wc;
3586 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3587 if ( aHistogram && !aHistogram->isEmpty() ) {
3588 QwtPlotItem* anItem = aHistogram->createPlotItem();
3589 anItem->attach( myPlot3D );
3597 \brief Internal clean-up (reset widget)
3599 void SMESHGUI_CtrlInfo::clearInternal()
3601 for( int i=0; i<=34; i++)
3602 myMainLayout->itemAt(i)->widget()->setVisible( true );
3603 for( int i=0; i<=8; i++)
3604 myButtons[i]->setEnabled( false );
3605 myPlot->detachItems();
3606 myPlot3D->detachItems();
3609 myWidgets[0]->setText( QString() );
3610 for ( int i = 1; i < myWidgets.count(); i++ )
3611 myWidgets[i]->setText( "" );
3612 myMainLayout->setRowStretch(11,5);
3613 myMainLayout->setRowStretch(16,5);
3616 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3618 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3619 myButtons[1]->setEnabled( true );
3620 myWidgets[2]->setText("");
3623 #ifndef DISABLE_PLOT2DVIEWER
3624 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3626 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3627 if ( mesh->_is_nil() ) return 0;
3628 if ( !mesh->IsLoaded() )
3630 aNumFun->SetMesh( mesh );
3632 CORBA::Long cprecision = 6;
3633 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3634 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3635 aNumFun->SetPrecision( cprecision );
3637 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3639 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3640 /*isLogarithmic=*/false,
3642 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3643 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3644 if ( &histogramVar.in() )
3646 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3647 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3648 if ( histogramVar->length() >= 2 )
3649 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3655 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3656 out << QString( 20, '-' ) << "\n";
3657 out << tr( "CTRL_INFO" ) << "\n";
3658 out << QString( 20, '-' ) << "\n";
3659 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3660 out << tr( "NODES_INFO" ) << "\n";
3661 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3662 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3663 out << tr( "EDGES_INFO" ) << "\n";
3664 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3665 out << tr( "FACES_INFO" ) << "\n";
3666 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3667 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3668 out << tr( "VOLUMES_INFO" ) << "\n";
3669 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3670 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3674 \class SMESHGUI_CtrlInfoDlg
3675 \brief Controls information dialog box
3680 \param parent parent widget
3681 \param page specifies the dialog page to be shown at the start-up
3683 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3686 setAttribute( Qt::WA_DeleteOnClose, true );
3687 setWindowTitle( tr( "CTRL_INFO" ) );
3688 setMinimumSize( 400, 600 );
3690 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3693 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3694 okBtn->setAutoDefault( true );
3695 okBtn->setDefault( true );
3697 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3698 dumpBtn->setAutoDefault( true );
3699 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3700 helpBtn->setAutoDefault( true );
3702 QHBoxLayout* btnLayout = new QHBoxLayout;
3703 btnLayout->setSpacing( SPACING );
3704 btnLayout->setMargin( 0 );
3706 btnLayout->addWidget( okBtn );
3707 btnLayout->addWidget( dumpBtn );
3708 btnLayout->addStretch( 10 );
3709 btnLayout->addWidget( helpBtn );
3711 QVBoxLayout* l = new QVBoxLayout ( this );
3712 l->setMargin( MARGIN );
3713 l->setSpacing( SPACING );
3714 l->addWidget( myCtrlInfo );
3715 l->addLayout( btnLayout );
3717 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3718 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3719 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3720 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3721 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3729 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3734 \brief Show controls information
3735 \param IO interactive object
3737 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3739 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3740 myCtrlInfo->showInfo( obj );
3744 \brief Perform clean-up actions on the dialog box closing.
3746 void SMESHGUI_CtrlInfoDlg::reject()
3748 SMESH::SetPointRepresentation( false );
3753 \brief Setup selection mode depending on the current dialog box state.
3755 void SMESHGUI_CtrlInfoDlg::updateSelection()
3757 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3758 disconnect( selMgr, 0, this, 0 );
3759 SMESH::SetPointRepresentation( false );
3760 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3765 \brief Show mesh information
3767 void SMESHGUI_CtrlInfoDlg::updateInfo()
3769 SUIT_OverrideCursor wc;
3771 SALOME_ListIO selected;
3772 SMESHGUI::selectionMgr()->selectedObjects( selected );
3774 if ( selected.Extent() == 1 ) {
3775 Handle(SALOME_InteractiveObject) IO = selected.First();
3781 \brief Activate dialog box
3783 void SMESHGUI_CtrlInfoDlg::activate()
3785 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3786 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3791 \brief Deactivate dialog box
3793 void SMESHGUI_CtrlInfoDlg::deactivate()
3795 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3799 * \brief Dump contents into a file
3801 void SMESHGUI_CtrlInfoDlg::dump()
3803 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3805 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3806 if ( !appStudy ) return;
3807 _PTR( Study ) aStudy = appStudy->studyDS();
3809 QStringList aFilters;
3810 aFilters.append( tr( "TEXT_FILES" ) );
3812 DumpFileDlg fd( this );
3813 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3814 fd.setFilters( aFilters );
3815 fd.myBaseChk->hide();
3816 fd.myElemChk->hide();
3817 fd.myAddChk ->hide();
3818 fd.myCtrlChk->hide();
3819 if ( fd.exec() == QDialog::Accepted )
3821 QString aFileName = fd.selectedFile();
3822 if ( !aFileName.isEmpty() ) {
3823 QFileInfo aFileInfo( aFileName );
3824 if ( aFileInfo.isDir() )
3827 QFile aFile( aFileName );
3828 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3831 QTextStream out( &aFile );
3832 myCtrlInfo->saveInfo( out );
3840 void SMESHGUI_CtrlInfoDlg::help()
3842 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");