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->setObjectName("meshName");
235 aName->setMinimumWidth( 150 );
236 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
237 QLabel* aObj = createField();
238 aObj->setObjectName("meshType");
239 aObj->setMinimumWidth( 150 );
240 myWidgets[ index++ ] << aNameLab << aName;
241 myWidgets[ index++ ] << aObjLab << aObj;
244 QWidget* aNodesLine = createLine();
245 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
246 QLabel* aNodes = createField();
247 aNodes->setObjectName("nbNodes");
248 myWidgets[ index++ ] << aNodesLine;
249 myWidgets[ index++ ] << aNodesLab << aNodes;
252 QWidget* aElemLine = createLine();
253 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
254 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
255 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
256 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
257 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
258 myWidgets[ index++ ] << aElemLine;
259 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
261 // ... Number elements
262 QWidget* aNbLine = createLine();
263 QLabel* aNbTotal = createField();
264 aNbTotal->setObjectName("totalNbElems");
265 QLabel* aNbLin = createField();
266 aNbLin->setObjectName("totalNbLinearElems");
267 QLabel* aNbQuad = createField();
268 aNbQuad->setObjectName("totalNbQuadraticElems");
269 QLabel* aNbBiQuad = createField();
270 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
271 myWidgets[ index++ ] << aNbLine;
272 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
275 QWidget* a0DLine = createLine();
276 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
277 QLabel* a0DTotal = createField();
278 a0DTotal->setObjectName("nb0D");
280 myWidgets[ index++ ] << a0DLine;
281 myWidgets[ index++ ] << a0DLab << a0DTotal;
284 QWidget* aBallLine = createLine();
285 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
286 QLabel* aBallTotal = createField();
287 aBallTotal->setObjectName("nbBall");
288 myWidgets[ index++ ] << aBallLine;
289 myWidgets[ index++ ] << aBallLab << aBallTotal;
292 QWidget* a1DLine = createLine();
293 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
294 QLabel* a1DTotal = createField();
295 a1DTotal->setObjectName("nb1D");
296 QLabel* a1DLin = createField();
297 a1DLin->setObjectName("nbLinear1D");
298 QLabel* a1DQuad = createField();
299 a1DQuad->setObjectName("nbQuadratic1D");
300 myWidgets[ index++ ] << a1DLine;
301 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
304 QWidget* a2DLine = createLine();
305 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
306 QLabel* a2DTotal = createField();
307 a2DTotal->setObjectName("nb2D");
308 QLabel* a2DLin = createField();
309 a2DLin->setObjectName("nbLinear2D");
310 QLabel* a2DQuad = createField();
311 a2DQuad->setObjectName("nbQuadratic2D");
312 QLabel* a2DBiQuad = createField();
313 a2DBiQuad->setObjectName("nbBiQuadratic2D");
314 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
315 QLabel* a2DTriTotal = createField();
316 a2DTriTotal->setObjectName("nbTriangle");
317 QLabel* a2DTriLin = createField();
318 a2DTriLin->setObjectName("nbLinearTriangle");
319 QLabel* a2DTriQuad = createField();
320 a2DTriQuad->setObjectName("nbQuadraticTriangle");
321 QLabel* a2DTriBiQuad = createField();
322 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
323 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
324 QLabel* a2DQuaTotal = createField();
325 a2DQuaTotal->setObjectName("nbQuadrangle");
326 QLabel* a2DQuaLin = createField();
327 a2DQuaLin->setObjectName("nbLinearQuadrangle");
328 QLabel* a2DQuaQuad = createField();
329 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
330 QLabel* a2DQuaBiQuad = createField();
331 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
332 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
333 QLabel* a2DPolTotal = createField();
334 a2DPolTotal->setObjectName("nbPolygon");
335 QLabel* a2DPolLin = createField();
336 a2DPolLin->setObjectName("nbLinearPolygon");
337 QLabel* a2DPolQuad = createField();
338 a2DPolQuad->setObjectName("nbQuadraticPolygon");
339 myWidgets[ index++ ] << a2DLine;
340 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
341 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
342 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
343 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
346 QWidget* a3DLine = createLine();
347 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
348 QLabel* a3DTotal = createField();
349 a3DTotal->setObjectName("nb3D");
350 QLabel* a3DLin = createField();
351 a3DLin->setObjectName("nbLinear3D");
352 QLabel* a3DQuad = createField();
353 a3DQuad->setObjectName("nbQuadratic3D");
354 QLabel* a3DBiQuad = createField();
355 a3DBiQuad->setObjectName("nbBiQuadratic3D");
356 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
357 QLabel* a3DTetTotal = createField();
358 a3DTetTotal->setObjectName("nbTetrahedron");
359 QLabel* a3DTetLin = createField();
360 a3DTetLin->setObjectName("nbLinearTetrahedron");
361 QLabel* a3DTetQuad = createField();
362 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
363 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
364 QLabel* a3DHexTotal = createField();
365 a3DHexTotal->setObjectName("nbHexahedron");
366 QLabel* a3DHexLin = createField();
367 a3DHexLin->setObjectName("nbLinearHexahedron");
368 QLabel* a3DHexQuad = createField();
369 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
370 QLabel* a3DHexBiQuad = createField();
371 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
372 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
373 QLabel* a3DPyrTotal = createField();
374 a3DPyrTotal->setObjectName("nbPyramid");
375 QLabel* a3DPyrLin = createField();
376 a3DPyrLin->setObjectName("nbLinearPyramid");
377 QLabel* a3DPyrQuad = createField();
378 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
379 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
380 QLabel* a3DPriTotal = createField();
381 a3DPriTotal->setObjectName("nbPrism");
382 QLabel* a3DPriLin = createField();
383 a3DPriLin->setObjectName("nbLinearPrism");
384 QLabel* a3DPriQuad = createField();
385 a3DPriQuad->setObjectName("nbQuadraticPrism");
386 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
387 QLabel* a3DHexPriTotal = createField();
388 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
389 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
390 QLabel* a3DPolTotal = createField();
391 a3DPolTotal->setObjectName("nbPolyhedron");
392 myWidgets[ index++ ] << a3DLine;
393 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
394 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
395 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
396 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
397 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
398 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
399 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
401 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
402 myLoadBtn->setAutoDefault( true );
403 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
405 setFontAttributes( aNameLab, Bold );
406 setFontAttributes( aObjLab, Bold );
407 setFontAttributes( aNodesLab, Bold );
408 setFontAttributes( aElemLab, Bold );
409 setFontAttributes( aElemTotal, Italic );
410 setFontAttributes( aElemLin, Italic );
411 setFontAttributes( aElemQuad, Italic );
412 setFontAttributes( aElemBiQuad, Italic );
413 setFontAttributes( a0DLab, Bold );
414 setFontAttributes( aBallLab, Bold );
415 setFontAttributes( a1DLab, Bold );
416 setFontAttributes( a2DLab, Bold );
417 setFontAttributes( a3DLab, Bold );
419 l->addWidget( aNameLab, 0, 0 );
420 l->addWidget( aName, 0, 1, 1, 4 );
421 l->addWidget( aObjLab, 1, 0 );
422 l->addWidget( aObj, 1, 1, 1, 4 );
423 l->addWidget( aNodesLine, 2, 0, 1, 5 );
424 l->addWidget( aNodesLab, 3, 0 );
425 l->addWidget( aNodes, 3, 1 );
426 l->addWidget( aElemLine, 4, 0, 1, 5 );
427 l->addWidget( aElemLab, 5, 0 );
428 l->addWidget( aElemTotal, 5, 1 );
429 l->addWidget( aElemLin, 5, 2 );
430 l->addWidget( aElemQuad, 5, 3 );
431 l->addWidget( aElemBiQuad, 5, 4 );
432 l->addWidget( aNbLine, 6, 1, 1, 4 );
433 l->addWidget( aNbTotal, 7, 1 );
434 l->addWidget( aNbLin, 7, 2 );
435 l->addWidget( aNbQuad, 7, 3 );
436 l->addWidget( aNbBiQuad, 7, 4 );
437 l->addWidget( a0DLine, 8, 1, 1, 4 );
438 l->addWidget( a0DLab, 9, 0 );
439 l->addWidget( a0DTotal, 9, 1 );
440 l->addWidget( aBallLine, 10, 1, 1, 4 );
441 l->addWidget( aBallLab, 11, 0 );
442 l->addWidget( aBallTotal, 11, 1 );
443 l->addWidget( a1DLine, 12, 1, 1, 4 );
444 l->addWidget( a1DLab, 13, 0 );
445 l->addWidget( a1DTotal, 13, 1 );
446 l->addWidget( a1DLin, 13, 2 );
447 l->addWidget( a1DQuad, 13, 3 );
448 l->addWidget( a2DLine, 14, 1, 1, 4 );
449 l->addWidget( a2DLab, 15, 0 );
450 l->addWidget( a2DTotal, 15, 1 );
451 l->addWidget( a2DLin, 15, 2 );
452 l->addWidget( a2DQuad, 15, 3 );
453 l->addWidget( a2DBiQuad, 15, 4 );
454 l->addWidget( a2DTriLab, 16, 0 );
455 l->addWidget( a2DTriTotal, 16, 1 );
456 l->addWidget( a2DTriLin, 16, 2 );
457 l->addWidget( a2DTriQuad, 16, 3 );
458 l->addWidget( a2DTriBiQuad, 16, 4 );
459 l->addWidget( a2DQuaLab, 17, 0 );
460 l->addWidget( a2DQuaTotal, 17, 1 );
461 l->addWidget( a2DQuaLin, 17, 2 );
462 l->addWidget( a2DQuaQuad, 17, 3 );
463 l->addWidget( a2DQuaBiQuad, 17, 4 );
464 l->addWidget( a2DPolLab, 18, 0 );
465 l->addWidget( a2DPolTotal, 18, 1 );
466 l->addWidget( a2DPolLin, 18, 2 );
467 l->addWidget( a2DPolQuad, 18, 3 );
468 l->addWidget( a3DLine, 19, 1, 1, 4 );
469 l->addWidget( a3DLab, 20, 0 );
470 l->addWidget( a3DTotal, 20, 1 );
471 l->addWidget( a3DLin, 20, 2 );
472 l->addWidget( a3DQuad, 20, 3 );
473 l->addWidget( a3DBiQuad, 20, 4 );
474 l->addWidget( a3DTetLab, 21, 0 );
475 l->addWidget( a3DTetTotal, 21, 1 );
476 l->addWidget( a3DTetLin, 21, 2 );
477 l->addWidget( a3DTetQuad, 21, 3 );
478 l->addWidget( a3DHexLab, 22, 0 );
479 l->addWidget( a3DHexTotal, 22, 1 );
480 l->addWidget( a3DHexLin, 22, 2 );
481 l->addWidget( a3DHexQuad, 22, 3 );
482 l->addWidget( a3DHexBiQuad, 22, 4 );
483 l->addWidget( a3DPyrLab, 23, 0 );
484 l->addWidget( a3DPyrTotal, 23, 1 );
485 l->addWidget( a3DPyrLin, 23, 2 );
486 l->addWidget( a3DPyrQuad, 23, 3 );
487 l->addWidget( a3DPriLab, 24, 0 );
488 l->addWidget( a3DPriTotal, 24, 1 );
489 l->addWidget( a3DPriLin, 24, 2 );
490 l->addWidget( a3DPriQuad, 24, 3 );
491 l->addWidget( a3DHexPriLab, 25, 0 );
492 l->addWidget( a3DHexPriTotal, 25, 1 );
493 l->addWidget( a3DPolLab, 26, 0 );
494 l->addWidget( a3DPolTotal, 26, 1 );
495 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
497 l->setColumnStretch( 0, 0 );
498 l->setColumnStretch( 1, 5 );
499 l->setColumnStretch( 2, 5 );
500 l->setColumnStretch( 3, 5 );
501 l->setColumnStretch( 4, 5 );
502 l->setRowStretch( 27, 5 );
510 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
515 \brief Show information on the mesh object.
516 \param obj object being processed (mesh, sub-mesh, group, ID source)
518 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
521 if ( !CORBA::is_nil( obj ) ) {
522 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
524 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
525 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
526 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
527 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
528 if ( !aMesh->_is_nil() ) {
529 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
531 else if ( !aSubMesh->_is_nil() ) {
532 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
534 else if ( !aGroup->_is_nil() ) {
536 switch( aGroup->GetType() ) {
537 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
538 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
539 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
540 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
541 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
542 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
543 default: objType = tr( "OBJECT_GROUP" );break;
545 myWidgets[iObject][iSingle]->setProperty( "text", objType );
547 SMESH::long_array_var info = obj->GetMeshInfo();
548 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
549 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
550 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
551 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
552 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
553 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
554 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
555 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
556 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
557 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
558 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
559 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
560 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
561 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
563 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
564 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
565 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
566 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
567 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
568 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
569 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
570 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
571 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
572 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
573 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
574 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
575 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
576 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
577 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
578 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
579 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
580 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
581 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
582 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
583 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
584 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
585 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
586 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
587 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
588 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
589 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
590 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
591 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
592 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
593 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
594 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
595 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
596 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
597 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
598 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
599 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
600 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
601 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
602 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
603 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
604 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
605 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
606 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
607 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
608 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
609 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
610 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
611 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
612 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
613 // before full loading from study file, type of elements in a sub-mesh can't be defined
615 bool infoOK = obj->IsMeshInfoCorrect();
616 myLoadBtn->setVisible( !infoOK );
620 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
621 // 2. No info at all (for a group on geom or filter)
622 bool hasAnyInfo = false;
623 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
624 hasAnyInfo = info[i];
625 if ( hasAnyInfo ) // believe it is a sub-mesh
627 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
629 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
630 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
631 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
632 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
633 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
634 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
635 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
636 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
637 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
638 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
640 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
643 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
644 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
645 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
648 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
650 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
651 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
652 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
653 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
654 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
655 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
656 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
661 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
662 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
667 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
668 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
669 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
670 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
671 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
676 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
677 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
678 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
679 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
681 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
682 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
683 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
684 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
685 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
686 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
687 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
688 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
690 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
691 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
692 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
694 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
695 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
696 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
697 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
698 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
699 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
700 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
703 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
704 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
706 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
707 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
712 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
713 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
714 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
715 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
716 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
723 \brief Load mesh from a study file
725 void SMESHGUI_MeshInfo::loadMesh()
727 SUIT_OverrideCursor wc;
729 SALOME_ListIO selected;
730 SMESHGUI::selectionMgr()->selectedObjects( selected );
732 if ( selected.Extent() == 1 ) {
733 Handle(SALOME_InteractiveObject) IO = selected.First();
734 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
735 if ( !CORBA::is_nil( obj ) ) {
736 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
737 if ( !mesh->_is_nil() )
747 \brief Reset the widget to the initial state (nullify all fields).
749 void SMESHGUI_MeshInfo::clear()
751 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
752 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
753 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
754 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
755 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
756 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
757 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
758 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
759 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
760 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
761 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
762 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
763 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
764 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
765 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
766 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
767 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
768 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
769 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
770 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
771 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ) );
772 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
773 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
774 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
775 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
776 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
777 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
778 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
779 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
780 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
781 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
782 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
783 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
784 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
785 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
786 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
787 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
788 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
789 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
790 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
791 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
792 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
793 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
794 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
795 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
796 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
800 \brief Create info field
801 \return new info field
803 QLabel* SMESHGUI_MeshInfo::createField()
805 QLabel* lab = new QLabel( this );
806 lab->setFrameStyle( StyledPanel | Sunken );
807 lab->setAlignment( Qt::AlignCenter );
808 lab->setAutoFillBackground( true );
809 QPalette pal = lab->palette();
810 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
811 lab->setPalette( pal );
812 lab->setMinimumWidth( 70 );
817 \brief Create horizontal rule.
818 \return new line object
820 QWidget* SMESHGUI_MeshInfo::createLine()
822 QFrame* line = new QFrame( this );
823 line->setFrameStyle( HLine | Sunken );
828 \brief Change widget font attributes (bold, italic, ...).
830 \param attr font attributes (XORed flags)
831 \param val value to be set to attributes
833 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
837 if ( attr & Bold ) f.setBold( val );
838 if ( attr & Italic ) f.setItalic( val );
844 \brief Show/hide group(s) of fields.
845 \param start beginning of the block
846 \param end end of the block
847 \param on visibility flag
849 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
851 start = qMax( 0, start );
852 end = qMin( end, (int)iElementsEnd );
853 for ( int i = start; i < end; i++ ) {
854 wlist wl = myWidgets[i];
855 foreach ( QWidget* w, wl ) w->setVisible( on );
859 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
861 out << QString( 9, '-' ) << "\n";
862 out << tr( "BASE_INFO" ) << "\n";
863 out << QString( 9, '-' ) << "\n";
864 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
865 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
866 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
867 out << tr( "ELEMENTS_LAB" ) << "\n";
868 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
869 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
870 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
871 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
872 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
873 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
874 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
875 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
876 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
877 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
878 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
879 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
880 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
881 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
883 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
886 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
887 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
888 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
889 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
890 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
891 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
895 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
899 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
900 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
901 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
903 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
904 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
906 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
907 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
909 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
910 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
911 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
913 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
915 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
917 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
920 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
921 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
923 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
924 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
928 \class SMESHGUI_ElemInfo
929 \brief Base class for the mesh element information widget.
934 \param parent parent widget
936 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
937 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
939 myFrame = new QWidget( this );
940 myExtra = new ExtraWidget( this );
941 QVBoxLayout* vbl = new QVBoxLayout( this );
943 vbl->setSpacing( 0 );
944 vbl->addWidget( myFrame );
945 vbl->addWidget( myExtra );
946 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
947 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
954 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
959 \brief Set mesh data source (actor)
960 \param actor mesh object actor
962 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
964 if ( myActor != actor ) {
972 \brief Show mesh element information
973 \param id mesh node / element ID
974 \param isElem show mesh element information if \c true or mesh node information if \c false
976 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
980 showInfo( ids, isElem );
984 \brief Show mesh element information
985 \param ids mesh nodes / elements identifiers
986 \param isElem show mesh element information if \c true or mesh node information if \c false
988 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
990 QList<long> newIds = ids.toList();
992 if ( myIDs == newIds && myIsElement == isElem ) return;
995 myIsElement = isElem;
998 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1002 \brief Clear mesh element information widget
1004 void SMESHGUI_ElemInfo::clear()
1013 \brief Get central area widget
1014 \return central widget
1016 QWidget* SMESHGUI_ElemInfo::frame() const
1023 \return actor being used
1025 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1031 \brief Get current info mode.
1032 \return \c true if mesh element information is shown or \c false if node information is shown
1034 bool SMESHGUI_ElemInfo::isElements() const
1040 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1041 \brief Show information on the specified nodes / elements
1043 This function is to be redefined in sub-classes.
1045 \param ids nodes / elements identifiers information is to be shown on
1049 \brief Internal clean-up (reset widget)
1051 void SMESHGUI_ElemInfo::clearInternal()
1056 \brief Get node connectivity
1057 \param node mesh node
1058 \return node connectivity map
1060 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1064 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1065 while ( it && it->more() ) {
1066 const SMDS_MeshElement* ne = it->next();
1067 elmap[ ne->GetType() ] << ne->GetID();
1074 \brief Format connectivity data to string representation
1075 \param connectivity connetivity map
1076 \param type element type
1077 \return string representation of the connectivity
1079 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1082 if ( connectivity.contains( type ) ) {
1083 QList<int> elements = connectivity[ type ];
1085 foreach( int id, elements )
1086 str << QString::number( id );
1088 return str.join( " " );
1092 \brief Calculate gravity center of the mesh element
1093 \param element mesh element
1095 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1099 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1100 while ( nodeIt->more() ) {
1101 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1102 xyz.add( node->X(), node->Y(), node->Z() );
1104 xyz.divide( element->NbNodes() );
1110 \brief Calculate normal vector to the mesh face
1111 \param element mesh face
1113 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1115 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1116 return XYZ(n.X(), n.Y(), n.Z());
1120 \brief This slot is called from "Show Previous" button click.
1121 Shows information on the previous group of the items.
1123 void SMESHGUI_ElemInfo::showPrevious()
1125 myIndex = qMax( 0, myIndex-1 );
1127 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1131 \brief This slot is called from "Show Next" button click.
1132 Shows information on the next group of the items.
1134 void SMESHGUI_ElemInfo::showNext()
1136 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1138 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1142 \brief Update widgets state
1144 void SMESHGUI_ElemInfo::updateControls()
1146 myExtra->updateControls( myIDs.count(), myIndex );
1150 \class SMESHGUI_SimpleElemInfo
1151 \brief Represents mesh element information in the simple text area.
1156 \param parent parent widget
1158 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1159 : SMESHGUI_ElemInfo( parent )
1161 myInfo = new QTextBrowser( frame() );
1162 QVBoxLayout* l = new QVBoxLayout( frame() );
1164 l->addWidget( myInfo );
1168 \brief Show mesh element information
1169 \param ids mesh nodes / elements identifiers
1171 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1176 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1177 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1178 int cprecision = -1;
1179 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1180 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1181 foreach ( long id, ids ) {
1182 if ( !isElements() ) {
1186 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1187 if ( !node ) return;
1190 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1192 myInfo->append( "" );
1194 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1195 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1196 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1197 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1199 myInfo->append( "" );
1201 Connectivity connectivity = nodeConnectivity( node );
1202 if ( !connectivity.isEmpty() ) {
1203 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1204 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1205 if ( !con.isEmpty() )
1206 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1207 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1208 if ( !con.isEmpty() )
1209 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1210 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1211 if ( !con.isEmpty() )
1212 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1213 con = formatConnectivity( connectivity, SMDSAbs_Face );
1214 if ( !con.isEmpty() )
1215 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1216 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1217 if ( !con.isEmpty() )
1218 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1221 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1224 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1225 if ( !CORBA::is_nil( aMeshPtr ) ) {
1226 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1227 int shapeID = pos->shapeID;
1228 if ( shapeID > 0 ) {
1231 switch ( pos->shapeType ) {
1233 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1234 if ( pos->params.length() == 1 )
1238 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1239 if ( pos->params.length() == 2 ) {
1245 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1248 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1252 myInfo->append( "" );
1253 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1254 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1255 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1256 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1257 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1258 if ( pos->shapeType == GEOM::FACE ) {
1259 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1260 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1265 // groups node belongs to
1266 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1267 if ( !CORBA::is_nil( aMesh ) ) {
1268 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1269 myInfo->append( "" ); // separator
1270 bool top_created = false;
1271 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1272 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1273 if ( CORBA::is_nil( aGrp ) ) continue;
1274 QString aName = aGrp->GetName();
1275 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1276 if ( !top_created ) {
1277 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1280 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1281 if ( grp_details ) {
1282 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1283 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1284 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1286 // type : group on geometry, standalone group, group on filter
1287 if ( !CORBA::is_nil( aStdGroup ) ) {
1288 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1289 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1291 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1292 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1293 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1294 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1295 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1297 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1298 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1301 else if ( !CORBA::is_nil( aFltGroup ) ) {
1302 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1303 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1307 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1308 arg( QString::number( aGrp->Size() ) ) );
1311 SALOMEDS::Color color = aGrp->GetColor();
1312 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1313 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1321 // show element info
1323 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1324 SMESH::Controls::NumericalFunctorPtr afunctor;
1327 // Element ID && Type
1329 switch( e->GetType() ) {
1330 case SMDSAbs_0DElement:
1331 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1333 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1335 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1337 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1338 case SMDSAbs_Volume:
1339 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1343 if ( stype.isEmpty() ) return;
1344 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1346 myInfo->append( "" );
1350 switch( e->GetEntityType() ) {
1351 case SMDSEntity_Triangle:
1352 case SMDSEntity_Quad_Triangle:
1353 case SMDSEntity_BiQuad_Triangle:
1354 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1355 case SMDSEntity_Quadrangle:
1356 case SMDSEntity_Quad_Quadrangle:
1357 case SMDSEntity_BiQuad_Quadrangle:
1358 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1359 case SMDSEntity_Polygon:
1360 case SMDSEntity_Quad_Polygon:
1361 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1362 case SMDSEntity_Tetra:
1363 case SMDSEntity_Quad_Tetra:
1364 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1365 case SMDSEntity_Pyramid:
1366 case SMDSEntity_Quad_Pyramid:
1367 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1368 case SMDSEntity_Hexa:
1369 case SMDSEntity_Quad_Hexa:
1370 case SMDSEntity_TriQuad_Hexa:
1371 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1372 case SMDSEntity_Penta:
1373 case SMDSEntity_Quad_Penta:
1374 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1375 case SMDSEntity_Hexagonal_Prism:
1376 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1377 case SMDSEntity_Polyhedra:
1378 case SMDSEntity_Quad_Polyhedra:
1379 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1383 if ( !gtype.isEmpty() )
1384 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1386 // Quadratic flag (any element except 0D)
1387 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1388 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1390 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1392 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1395 myInfo->append( "" );
1398 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1399 for ( int idx = 1; nodeIt->more(); idx++ ) {
1400 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1401 // node number and ID
1402 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1404 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1405 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1406 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1407 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1408 // node connectivity
1409 Connectivity connectivity = nodeConnectivity( node );
1410 if ( !connectivity.isEmpty() ) {
1411 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1412 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1413 if ( !con.isEmpty() )
1414 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1415 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1416 if ( !con.isEmpty() )
1417 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1418 con = formatConnectivity( connectivity, SMDSAbs_Face );
1419 if ( !con.isEmpty() )
1420 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1421 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1422 if ( !con.isEmpty() )
1423 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1426 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1430 myInfo->append( "" );
1433 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1435 if ( e->GetType() == SMDSAbs_Edge ) {
1436 afunctor.reset( new SMESH::Controls::Length() );
1437 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1438 afunctor->SetPrecision( cprecision );
1439 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1441 if( e->GetType() == SMDSAbs_Face ) {
1443 afunctor.reset( new SMESH::Controls::Area() );
1444 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1445 afunctor->SetPrecision( cprecision );
1446 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1448 afunctor.reset( new SMESH::Controls::Taper() );
1449 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1450 afunctor->SetPrecision( cprecision );
1451 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1453 afunctor.reset( new SMESH::Controls::AspectRatio() );
1454 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1455 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1457 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1458 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1459 afunctor->SetPrecision( cprecision );
1460 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1462 afunctor.reset( new SMESH::Controls::Warping() );
1463 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1464 afunctor->SetPrecision( cprecision );
1465 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1467 afunctor.reset( new SMESH::Controls::Skew() );
1468 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1469 afunctor->SetPrecision( cprecision );
1470 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1472 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1473 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1474 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1476 if( e->GetType() == SMDSAbs_Volume ) {
1478 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1479 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1480 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1482 afunctor.reset( new SMESH::Controls::Volume() );
1483 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1484 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1486 afunctor.reset( new SMESH::Controls::Volume() );
1487 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1488 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1491 myInfo->append( "" );
1494 XYZ gc = gravityCenter( e );
1495 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1498 if( e->GetType() == SMDSAbs_Face ) {
1499 XYZ gc = normal( e );
1500 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1504 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1505 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1506 if ( !CORBA::is_nil( aMesh ) ) {
1507 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1508 int shapeID = pos.shapeID;
1509 if ( shapeID > 0 ) {
1510 myInfo->append( "" ); // separator
1512 switch ( pos.shapeType ) {
1513 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1514 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1515 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1516 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1517 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1518 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1520 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1525 // Groups the element belongs to
1526 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1527 if ( !CORBA::is_nil( aMesh ) ) {
1528 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1529 myInfo->append( "" ); // separator
1530 bool top_created = false;
1531 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1532 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1533 if ( CORBA::is_nil( aGrp ) ) continue;
1534 QString aName = aGrp->GetName();
1535 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1536 if ( !top_created ) {
1537 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1540 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1541 if ( grp_details ) {
1542 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1543 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1544 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1546 // type : group on geometry, standalone group, group on filter
1547 if ( !CORBA::is_nil( aStdGroup ) ) {
1548 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1549 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1551 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1552 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1553 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1554 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1555 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1557 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1558 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1561 else if ( !CORBA::is_nil( aFltGroup ) ) {
1562 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1563 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1566 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1567 arg( QString::number( aGrp->Size() ) ) );
1570 SALOMEDS::Color color = aGrp->GetColor();
1571 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1572 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1579 if ( ids.count() > 1 ) {
1580 myInfo->append( "" );
1581 myInfo->append( "------" );
1582 myInfo->append( "" );
1589 \brief Internal clean-up (reset widget)
1591 void SMESHGUI_SimpleElemInfo::clearInternal()
1596 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1598 out << QString( 12, '-' ) << "\n";
1599 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1600 out << QString( 12, '-' ) << "\n";
1601 out << myInfo->toPlainText();
1607 \class SMESHGUI_TreeElemInfo::ItemDelegate
1608 \brief Item delegate for tree mesh info widget
1611 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1614 ItemDelegate( QObject* );
1615 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1622 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1627 \brief Create item editor widget
1630 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1632 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1633 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1638 \class SMESHGUI_TreeElemInfo
1639 \brief Represents mesh element information in the tree-like form.
1644 \param parent parent widget
1646 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1647 : SMESHGUI_ElemInfo( parent )
1649 myInfo = new QTreeWidget( frame() );
1650 myInfo->setColumnCount( 2 );
1651 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1652 myInfo->header()->setStretchLastSection( true );
1653 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1654 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1656 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1658 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1659 QVBoxLayout* l = new QVBoxLayout( frame() );
1661 l->addWidget( myInfo );
1662 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1666 \brief Show mesh element information
1667 \param ids mesh nodes / elements identifiers
1669 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1674 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1675 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1676 int cprecision = -1;
1677 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1678 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1679 foreach ( long id, ids ) {
1680 if ( !isElements() ) {
1684 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1686 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1689 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1690 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1691 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1693 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1694 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1695 QTreeWidgetItem* xItem = createItem( coordItem );
1696 xItem->setText( 0, "X" );
1697 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1698 QTreeWidgetItem* yItem = createItem( coordItem );
1699 yItem->setText( 0, "Y" );
1700 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1701 QTreeWidgetItem* zItem = createItem( coordItem );
1702 zItem->setText( 0, "Z" );
1703 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1705 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1706 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1707 Connectivity connectivity = nodeConnectivity( node );
1708 if ( !connectivity.isEmpty() ) {
1709 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1710 if ( !con.isEmpty() ) {
1711 QTreeWidgetItem* i = createItem( conItem );
1712 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1713 i->setText( 1, con );
1715 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1716 if ( !con.isEmpty() ) {
1717 QTreeWidgetItem* i = createItem( conItem );
1718 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1719 i->setText( 1, con );
1720 i->setData( 1, TypeRole, NodeConnectivity );
1722 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1723 if ( !con.isEmpty() ) {
1724 QTreeWidgetItem* i = createItem( conItem );
1725 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1726 i->setText( 1, con );
1727 i->setData( 1, TypeRole, NodeConnectivity );
1729 con = formatConnectivity( connectivity, SMDSAbs_Face );
1730 if ( !con.isEmpty() ) {
1731 QTreeWidgetItem* i = createItem( conItem );
1732 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1733 i->setText( 1, con );
1734 i->setData( 1, TypeRole, NodeConnectivity );
1736 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1737 if ( !con.isEmpty() ) {
1738 QTreeWidgetItem* i = createItem( conItem );
1739 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1740 i->setText( 1, con );
1741 i->setData( 1, TypeRole, NodeConnectivity );
1745 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1748 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1749 if ( !CORBA::is_nil( aMeshPtr ) ) {
1750 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1751 int shapeID = pos->shapeID;
1752 if ( shapeID > 0 ) {
1755 switch ( pos->shapeType ) {
1757 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1758 if ( pos->params.length() == 1 )
1762 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1763 if ( pos->params.length() == 2 ) {
1769 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1772 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1775 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1776 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1777 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1778 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1779 QTreeWidgetItem* uItem = createItem( posItem );
1780 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1781 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1782 if ( pos->shapeType == GEOM::FACE ) {
1783 QTreeWidgetItem* vItem = createItem( posItem );
1784 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1785 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1790 // groups node belongs to
1791 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1792 if ( !CORBA::is_nil( aMesh ) ) {
1793 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1794 QTreeWidgetItem* groupsItem = 0;
1795 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1796 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1797 if ( CORBA::is_nil( aGrp ) ) continue;
1798 QString aName = aGrp->GetName();
1799 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1800 if ( !groupsItem ) {
1801 groupsItem = createItem( nodeItem, Bold );
1802 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1804 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1805 it->setText( 0, aName.trimmed() );
1806 if ( grp_details ) {
1807 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1808 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1809 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1811 // type : group on geometry, standalone group, group on filter
1812 QTreeWidgetItem* typeItem = createItem( it );
1813 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1814 if ( !CORBA::is_nil( aStdGroup ) ) {
1815 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1817 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1818 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1819 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1820 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1822 QTreeWidgetItem* gobjItem = createItem( typeItem );
1823 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1824 gobjItem->setText( 1, sobj->GetName().c_str() );
1827 else if ( !CORBA::is_nil( aFltGroup ) ) {
1828 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1832 QTreeWidgetItem* sizeItem = createItem( it );
1833 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1834 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1837 SALOMEDS::Color color = aGrp->GetColor();
1838 QTreeWidgetItem* colorItem = createItem( it );
1839 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1840 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1848 // show element info
1850 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1851 SMESH::Controls::NumericalFunctorPtr afunctor;
1854 // element ID && type
1856 switch( e->GetType() ) {
1857 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1858 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1859 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1860 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1861 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1864 if ( stype.isEmpty() ) return;
1865 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1866 elemItem->setText( 0, stype );
1867 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1870 switch( e->GetEntityType() ) {
1871 case SMDSEntity_Triangle:
1872 case SMDSEntity_Quad_Triangle:
1873 case SMDSEntity_BiQuad_Triangle:
1874 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1875 case SMDSEntity_Quadrangle:
1876 case SMDSEntity_Quad_Quadrangle:
1877 case SMDSEntity_BiQuad_Quadrangle:
1878 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1879 case SMDSEntity_Polygon:
1880 case SMDSEntity_Quad_Polygon:
1881 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1882 case SMDSEntity_Tetra:
1883 case SMDSEntity_Quad_Tetra:
1884 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1885 case SMDSEntity_Pyramid:
1886 case SMDSEntity_Quad_Pyramid:
1887 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1888 case SMDSEntity_Hexa:
1889 case SMDSEntity_Quad_Hexa:
1890 case SMDSEntity_TriQuad_Hexa:
1891 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1892 case SMDSEntity_Penta:
1893 case SMDSEntity_Quad_Penta:
1894 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1895 case SMDSEntity_Hexagonal_Prism:
1896 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1897 case SMDSEntity_Polyhedra:
1898 case SMDSEntity_Quad_Polyhedra:
1899 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1903 if ( !gtype.isEmpty() ) {
1904 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1905 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1906 typeItem->setText( 1, gtype );
1908 // quadratic flag (for edges, faces and volumes)
1909 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1911 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1912 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1913 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1915 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1917 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1918 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1919 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1922 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1923 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1926 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1927 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1928 for ( int idx = 1; nodeIt->more(); idx++ ) {
1929 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1930 nodeInfo( node, idx, e->NbNodes(), conItem );
1934 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1935 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1936 QList<const SMDS_MeshElement*> uniqueNodes;
1937 while ( nodeIt->more() )
1938 uniqueNodes.append( nodeIt->next() );
1940 SMDS_VolumeTool vtool( e );
1941 const int nbFaces = vtool.NbFaces();
1942 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1943 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1944 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1945 faceItem->setExpanded( true );
1947 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1948 const int nbNodes = vtool.NbFaceNodes( face_id );
1949 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1950 const SMDS_MeshNode* node = aNodeIds[node_id];
1951 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1956 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1957 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1959 if( e->GetType()==SMDSAbs_Edge){
1960 afunctor.reset( new SMESH::Controls::Length() );
1961 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1962 afunctor->SetPrecision( cprecision );
1963 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1964 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1965 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1967 if( e->GetType() == SMDSAbs_Face ) {
1969 afunctor.reset( new SMESH::Controls::Area() );
1970 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1971 afunctor->SetPrecision( cprecision );
1972 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1973 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1974 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1976 afunctor.reset( new SMESH::Controls::Taper() );
1977 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1978 afunctor->SetPrecision( cprecision );
1979 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1980 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1981 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1983 afunctor.reset( new SMESH::Controls::AspectRatio() );
1984 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1985 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1986 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1987 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1989 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1990 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1991 afunctor->SetPrecision( cprecision );
1992 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
1993 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
1994 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1996 afunctor.reset( new SMESH::Controls::Warping() );
1997 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1998 afunctor->SetPrecision( cprecision );
1999 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
2000 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
2001 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2003 afunctor.reset( new SMESH::Controls::Skew() );
2004 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2005 afunctor->SetPrecision( cprecision );
2006 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2007 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
2008 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2010 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2011 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2012 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2013 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2014 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2016 if( e->GetType() == SMDSAbs_Volume ) {
2018 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2019 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2020 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2021 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
2022 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2024 afunctor.reset( new SMESH::Controls::Volume() );
2025 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2026 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2027 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
2028 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2030 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2031 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2032 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2033 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
2034 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2038 XYZ gc = gravityCenter( e );
2039 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2040 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
2041 QTreeWidgetItem* xItem = createItem( gcItem );
2042 xItem->setText( 0, "X" );
2043 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2044 QTreeWidgetItem* yItem = createItem( gcItem );
2045 yItem->setText( 0, "Y" );
2046 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2047 QTreeWidgetItem* zItem = createItem( gcItem );
2048 zItem->setText( 0, "Z" );
2049 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2052 if( e->GetType() == SMDSAbs_Face ) {
2053 XYZ gc = normal( e );
2054 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2055 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2056 QTreeWidgetItem* xItem = createItem( nItem );
2057 xItem->setText( 0, "X" );
2058 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2059 QTreeWidgetItem* yItem = createItem( nItem );
2060 yItem->setText( 0, "Y" );
2061 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2062 QTreeWidgetItem* zItem = createItem( nItem );
2063 zItem->setText( 0, "Z" );
2064 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2068 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2069 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2070 if ( !CORBA::is_nil( aMesh ) ) {
2071 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2072 int shapeID = pos.shapeID;
2073 if ( shapeID > 0 ) {
2074 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2076 switch ( pos.shapeType ) {
2077 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2078 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2079 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2080 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2081 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2082 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2084 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2085 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2089 // groups element belongs to
2090 if ( !CORBA::is_nil( aMesh ) ) {
2091 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2092 QTreeWidgetItem* groupsItem = 0;
2093 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2094 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2095 if ( CORBA::is_nil( aGrp ) ) continue;
2096 QString aName = aGrp->GetName();
2097 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2098 if ( !groupsItem ) {
2099 groupsItem = createItem( elemItem, Bold );
2100 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2102 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2103 it->setText( 0, aName.trimmed() );
2104 if ( grp_details ) {
2105 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2106 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2107 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2109 // type : group on geometry, standalone group, group on filter
2110 QTreeWidgetItem* typeItem = createItem( it );
2111 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2112 if ( !CORBA::is_nil( aStdGroup ) ) {
2113 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2115 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2116 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2117 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2118 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2120 QTreeWidgetItem* gobjItem = createItem( typeItem );
2121 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2122 gobjItem->setText( 1, sobj->GetName().c_str() );
2125 else if ( !CORBA::is_nil( aFltGroup ) ) {
2126 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2130 QTreeWidgetItem* sizeItem = createItem( it );
2131 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2132 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2135 SALOMEDS::Color color = aGrp->GetColor();
2136 QTreeWidgetItem* colorItem = createItem( it );
2137 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2138 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2149 \brief Show node information
2150 \param node mesh node for showing
2151 \param index index of current node
2152 \param nbNodes number of unique nodes in element
2153 \param parentItem parent item of tree
2155 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2156 int nbNodes, QTreeWidgetItem* parentItem )
2158 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2159 // node number and ID
2160 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2161 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2162 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2163 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2164 nodeItem->setData( 1, IdRole, node->GetID() );
2165 nodeItem->setExpanded( false );
2167 QTreeWidgetItem* coordItem = createItem( nodeItem );
2168 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2169 QTreeWidgetItem* xItem = createItem( coordItem );
2170 xItem->setText( 0, "X" );
2171 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2172 QTreeWidgetItem* yItem = createItem( coordItem );
2173 yItem->setText( 0, "Y" );
2174 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2175 QTreeWidgetItem* zItem = createItem( coordItem );
2176 zItem->setText( 0, "Z" );
2177 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2178 // node connectivity
2179 QTreeWidgetItem* nconItem = createItem( nodeItem );
2180 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2181 Connectivity connectivity = nodeConnectivity( node );
2182 if ( !connectivity.isEmpty() ) {
2183 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2184 if ( !con.isEmpty() ) {
2185 QTreeWidgetItem* i = createItem( nconItem );
2186 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2187 i->setText( 1, con );
2189 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2190 if ( !con.isEmpty() ) {
2191 QTreeWidgetItem* i = createItem( nconItem );
2192 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2193 i->setText( 1, con );
2194 i->setData( 1, TypeRole, NodeConnectivity );
2196 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2197 if ( !con.isEmpty() ) {
2198 QTreeWidgetItem* i = createItem( nconItem );
2199 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2200 i->setText( 1, con );
2201 i->setData( 1, TypeRole, NodeConnectivity );
2203 con = formatConnectivity( connectivity, SMDSAbs_Face );
2204 if ( !con.isEmpty() ) {
2205 QTreeWidgetItem* i = createItem( nconItem );
2206 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2207 i->setText( 1, con );
2208 i->setData( 1, TypeRole, NodeConnectivity );
2210 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2211 if ( !con.isEmpty() ) {
2212 QTreeWidgetItem* i = createItem( nconItem );
2213 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2214 i->setText( 1, con );
2215 i->setData( 1, TypeRole, NodeConnectivity );
2220 \brief Internal clean-up (reset widget)
2222 void SMESHGUI_TreeElemInfo::clearInternal()
2229 \brief Create new tree item.
2230 \param parent parent tree widget item
2231 \param flags item flag
2232 \return new tree widget item
2234 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2236 QTreeWidgetItem* item;
2238 item = new QTreeWidgetItem( parent );
2240 item = new QTreeWidgetItem( myInfo );
2242 item->setFlags( item->flags() | Qt::ItemIsEditable );
2244 QFont f = item->font( 0 );
2246 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2247 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2248 item->setFont( i, f );
2251 item->setExpanded( true );
2255 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2257 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2258 if ( widgets.isEmpty() ) return;
2259 QTreeWidgetItem* aTreeItem = widgets.first();
2260 int type = aTreeItem->data( 1, TypeRole ).toInt();
2261 int id = aTreeItem->data( 1, IdRole ).toInt();
2263 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2264 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2265 emit( itemInfo( id ) );
2266 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2267 emit( itemInfo( aTreeItem->text( 1 ) ) );
2270 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2273 int type = theItem->data( 1, TypeRole ).toInt();
2274 int id = theItem->data( 1, IdRole ).toInt();
2275 if ( type == ElemConnectivity && id > 0 )
2276 emit( itemInfo( id ) );
2277 else if ( type == NodeConnectivity )
2278 emit( itemInfo( theItem->text( 1 ) ) );
2282 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2284 out << QString( 12, '-' ) << "\n";
2285 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2286 out << QString( 12, '-' ) << "\n";
2288 QTreeWidgetItemIterator it( myInfo );
2290 if ( !( *it )->text(0).isEmpty() ) {
2291 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2292 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2302 \brief Mesh information computer
2305 The class is created for different computation operation. Currently it is used
2306 to compute number of underlying nodes for the groups.
2312 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2313 QTreeWidgetItem* item,
2316 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2318 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2322 \brief Compute function
2324 void GrpComputor::compute()
2326 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2327 QTreeWidgetItem* item = myItem;
2329 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2330 item->treeWidget()->removeItemWidget( item, 1 );
2331 item->setText( 1, QString::number( nb ));
2336 \class SMESHGUI_AddInfo
2337 \brief The wigdet shows additional information on the mesh object.
2342 \param parent parent widget
2344 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2345 : QTreeWidget( parent )
2347 setColumnCount( 2 );
2348 header()->setStretchLastSection( true );
2349 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2350 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2352 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2360 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2365 \brief Show additional information on the selected object
2366 \param obj object being processed (mesh, sub-mesh, group, ID source)
2368 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2370 setProperty( "group_index", 0 );
2371 setProperty( "submesh_index", 0 );
2372 myComputors.clear();
2375 if ( CORBA::is_nil( obj ) ) return;
2377 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2378 if ( !sobj ) return;
2381 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2382 nameItem->setText( 0, tr( "NAME" ) );
2383 nameItem->setText( 1, sobj->GetName().c_str() );
2385 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2386 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2387 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2389 if ( !aMesh->_is_nil() )
2390 meshInfo( aMesh, nameItem );
2391 else if ( !aSubMesh->_is_nil() )
2392 subMeshInfo( aSubMesh, nameItem );
2393 else if ( !aGroup->_is_nil() )
2394 groupInfo( aGroup.in(), nameItem );
2398 \brief Create new tree item.
2399 \param parent parent tree widget item
2400 \param flags item flag
2401 \return new tree widget item
2403 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2405 QTreeWidgetItem* item;
2408 item = new QTreeWidgetItem( parent );
2410 item = new QTreeWidgetItem( this );
2412 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2414 QFont f = item->font( 0 );
2416 for ( int i = 0; i < columnCount(); i++ ) {
2417 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2418 item->setFont( i, f );
2421 item->setExpanded( true );
2426 \brief Show mesh info
2427 \param mesh mesh object
2428 \param parent parent tree item
2430 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2433 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2434 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2435 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2436 typeItem->setText( 0, tr( "TYPE" ) );
2437 if ( !CORBA::is_nil( shape ) ) {
2438 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2439 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2441 QTreeWidgetItem* gobjItem = createItem( typeItem );
2442 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2443 gobjItem->setText( 1, sobj->GetName().c_str() );
2446 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2447 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2448 QTreeWidgetItem* fileItem = createItem( typeItem );
2449 fileItem->setText( 0, tr( "FILE_NAME" ) );
2450 fileItem->setText( 1, (char*)inf->fileName );
2453 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2457 myGroups = mesh->GetGroups();
2461 mySubMeshes = mesh->GetSubMeshes();
2466 \brief Show sub-mesh info
2467 \param subMesh sub-mesh object
2468 \param parent parent tree item
2470 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2472 bool isShort = parent->parent() != 0;
2476 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2478 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2479 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2480 nameItem->setText( 1, sobj->GetName().c_str() );
2485 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2486 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2488 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2489 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2490 gobjItem->setText( 1, sobj->GetName().c_str() );
2495 \brief Show group info
2496 \param grp mesh group object
2497 \param parent parent tree item
2499 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2501 bool isShort = parent->parent() != 0;
2503 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2504 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2505 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2509 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2511 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2512 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2513 nameItem->setText( 1, sobj->GetName().c_str() );
2517 // type : group on geometry, standalone group, group on filter
2518 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2519 typeItem->setText( 0, tr( "TYPE" ) );
2520 if ( !CORBA::is_nil( aStdGroup ) ) {
2521 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2523 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2524 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2525 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2526 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2528 QTreeWidgetItem* gobjItem = createItem( typeItem );
2529 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2530 gobjItem->setText( 1, sobj->GetName().c_str() );
2533 else if ( !CORBA::is_nil( aFltGroup ) ) {
2534 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2539 QString etype = tr( "UNKNOWN" );
2540 switch( grp->GetType() ) {
2542 etype = tr( "NODE" );
2545 etype = tr( "EDGE" );
2548 etype = tr( "FACE" );
2551 etype = tr( "VOLUME" );
2554 etype = tr( "0DELEM" );
2557 etype = tr( "BALL" );
2562 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2563 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2564 etypeItem->setText( 1, etype );
2567 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2568 bool meshLoaded = mesh->IsLoaded();
2570 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2572 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2573 groupSize = grp->Size();
2575 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2576 sizeItem->setText( 0, tr( "SIZE" ) );
2577 if ( groupSize > -1 ) {
2578 sizeItem->setText( 1, QString::number( groupSize ) );
2581 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2582 setItemWidget( sizeItem, 1, btn );
2583 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2584 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2585 myComputors.append( comp );
2587 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2591 SALOMEDS::Color color = grp->GetColor();
2592 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2593 colorItem->setText( 0, tr( "COLOR" ) );
2594 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2596 // nb of underlying nodes
2597 if ( grp->GetType() != SMESH::NODE) {
2598 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2599 nodesItem->setText( 0, tr( "NB_NODES" ) );
2600 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2601 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2602 if ( toShowNodes && meshLoaded ) {
2603 // already calculated and up-to-date
2604 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2607 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2608 setItemWidget( nodesItem, 1, btn );
2609 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2610 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2611 myComputors.append( comp );
2613 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2618 void SMESHGUI_AddInfo::showGroups()
2620 myComputors.clear();
2622 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2623 if ( !parent ) return;
2625 int idx = property( "group_index" ).toInt();
2627 QTreeWidgetItem* itemGroups = 0;
2628 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2629 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2630 itemGroups = parent->child( i );
2631 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2633 extra->updateControls( myGroups->length(), idx );
2634 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2638 QMap<int, QTreeWidgetItem*> grpItems;
2639 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2640 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2641 if ( CORBA::is_nil( grp ) ) continue;
2642 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2643 if ( !grpSObj ) continue;
2645 int grpType = grp->GetType();
2647 if ( !itemGroups ) {
2648 // create top-level groups container item
2649 itemGroups = createItem( parent, Bold | All );
2650 itemGroups->setText( 0, tr( "GROUPS" ) );
2651 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2653 // total number of groups > 10, show extra widgets for info browsing
2654 if ((int) myGroups->length() > MAXITEMS ) {
2655 ExtraWidget* extra = new ExtraWidget( this, true );
2656 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2657 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2658 setItemWidget( itemGroups, 1, extra );
2659 extra->updateControls( myGroups->length(), idx );
2663 if ( grpItems.find( grpType ) == grpItems.end() ) {
2664 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2665 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2666 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2670 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2671 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2674 groupInfo( grp.in(), grpNameItem );
2678 void SMESHGUI_AddInfo::showSubMeshes()
2680 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2681 if ( !parent ) return;
2683 int idx = property( "submesh_index" ).toInt();
2685 QTreeWidgetItem* itemSubMeshes = 0;
2686 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2687 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2688 itemSubMeshes = parent->child( i );
2689 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2691 extra->updateControls( mySubMeshes->length(), idx );
2692 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2696 QMap<int, QTreeWidgetItem*> smItems;
2697 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2698 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2699 if ( CORBA::is_nil( sm ) ) continue;
2700 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2701 if ( !smSObj ) continue;
2703 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2704 if ( CORBA::is_nil(gobj ) ) continue;
2706 int smType = gobj->GetShapeType();
2707 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2709 if ( !itemSubMeshes ) {
2710 itemSubMeshes = createItem( parent, Bold | All );
2711 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2712 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2714 // total number of sub-meshes > 10, show extra widgets for info browsing
2715 if ((int) mySubMeshes->length() > MAXITEMS ) {
2716 ExtraWidget* extra = new ExtraWidget( this, true );
2717 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2718 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2719 setItemWidget( itemSubMeshes, 1, extra );
2720 extra->updateControls( mySubMeshes->length(), idx );
2724 if ( smItems.find( smType ) == smItems.end() ) {
2725 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2726 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2727 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2731 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2732 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2735 subMeshInfo( sm.in(), smNameItem );
2740 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2742 void SMESHGUI_AddInfo::changeLoadToCompute()
2744 for ( int i = 0; i < myComputors.count(); ++i )
2746 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2748 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2749 btn->setText( tr("COMPUTE") );
2754 void SMESHGUI_AddInfo::showPreviousGroups()
2756 int idx = property( "group_index" ).toInt();
2757 setProperty( "group_index", idx-1 );
2761 void SMESHGUI_AddInfo::showNextGroups()
2763 int idx = property( "group_index" ).toInt();
2764 setProperty( "group_index", idx+1 );
2768 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2770 int idx = property( "submesh_index" ).toInt();
2771 setProperty( "submesh_index", idx-1 );
2775 void SMESHGUI_AddInfo::showNextSubMeshes()
2777 int idx = property( "submesh_index" ).toInt();
2778 setProperty( "submesh_index", idx+1 );
2782 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2784 out << QString( 15, '-') << "\n";
2785 out << tr( "ADDITIONAL_INFO" ) << "\n";
2786 out << QString( 15, '-' ) << "\n";
2787 QTreeWidgetItemIterator it( this );
2789 if ( !( ( *it )->text(0) ).isEmpty() ) {
2790 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2791 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2792 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2794 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2803 \class SMESHGUI_MeshInfoDlg
2804 \brief Mesh information dialog box
2809 \param parent parent widget
2810 \param page specifies the dialog page to be shown at the start-up
2812 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2813 : QDialog( parent ), myActor( 0 )
2816 setAttribute( Qt::WA_DeleteOnClose, true );
2817 setWindowTitle( tr( "MESH_INFO" ) );
2818 setSizeGripEnabled( true );
2820 myTabWidget = new QTabWidget( this );
2824 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2825 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2829 QWidget* w = new QWidget( myTabWidget );
2831 myMode = new QButtonGroup( this );
2832 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2833 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2834 myMode->button( NodeMode )->setChecked( true );
2835 myID = new QLineEdit( w );
2836 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2838 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2839 mode = qMin( 1, qMax( 0, mode ) );
2842 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2844 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2846 QGridLayout* elemLayout = new QGridLayout( w );
2847 elemLayout->setMargin( MARGIN );
2848 elemLayout->setSpacing( SPACING );
2849 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2850 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2851 elemLayout->addWidget( myID, 0, 2 );
2852 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2854 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2858 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2859 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2863 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2864 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2868 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2869 okBtn->setAutoDefault( true );
2870 okBtn->setDefault( true );
2872 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2873 dumpBtn->setAutoDefault( true );
2874 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2875 helpBtn->setAutoDefault( true );
2877 QHBoxLayout* btnLayout = new QHBoxLayout;
2878 btnLayout->setSpacing( SPACING );
2879 btnLayout->setMargin( 0 );
2881 btnLayout->addWidget( okBtn );
2882 btnLayout->addWidget( dumpBtn );
2883 btnLayout->addStretch( 10 );
2884 btnLayout->addWidget( helpBtn );
2886 QVBoxLayout* l = new QVBoxLayout ( this );
2887 l->setMargin( MARGIN );
2888 l->setSpacing( SPACING );
2889 l->addWidget( myTabWidget );
2890 l->addLayout( btnLayout );
2892 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2894 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2895 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2896 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2897 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2898 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2899 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2900 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2901 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2902 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2903 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2911 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2916 \brief Show mesh information
2917 \param IO interactive object
2919 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2921 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2922 if ( !CORBA::is_nil( obj ) ) {
2923 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2924 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2925 myCtrlInfo->showInfo( obj );
2927 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2928 SVTK_Selector* selector = SMESH::GetSelector();
2931 if ( myActor && selector ) {
2932 nb = myMode->checkedId() == NodeMode ?
2933 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2934 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2936 myElemInfo->setSource( myActor ) ;
2938 myID->setText( ID.trimmed() );
2940 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2941 foreach ( ID, idTxt )
2942 ids << ID.trimmed().toLong();
2943 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2947 myElemInfo->clear();
2953 \brief Perform clean-up actions on the dialog box closing.
2955 void SMESHGUI_MeshInfoDlg::reject()
2957 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2958 selMgr->clearFilters();
2959 SMESH::SetPointRepresentation( false );
2960 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2961 aViewWindow->SetSelectionMode( ActorSelection );
2966 \brief Process keyboard event
2967 \param e key press event
2969 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2971 QDialog::keyPressEvent( e );
2972 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2979 \brief Reactivate dialog box, when mouse pointer goes into it.
2981 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2987 \brief Setup selection mode depending on the current dialog box state.
2989 void SMESHGUI_MeshInfoDlg::updateSelection()
2991 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2993 disconnect( selMgr, 0, this, 0 );
2994 selMgr->clearFilters();
2996 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2997 SMESH::SetPointRepresentation( false );
2998 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2999 aViewWindow->SetSelectionMode( ActorSelection );
3002 if ( myMode->checkedId() == NodeMode ) {
3003 SMESH::SetPointRepresentation( true );
3004 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3005 aViewWindow->SetSelectionMode( NodeSelection );
3008 SMESH::SetPointRepresentation( false );
3009 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3010 aViewWindow->SetSelectionMode( CellSelection );
3014 QString oldID = myID->text().trimmed();
3015 SMESH_Actor* oldActor = myActor;
3018 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3021 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3022 myID->setText( oldID );
3028 \brief Show help page
3030 void SMESHGUI_MeshInfoDlg::help()
3032 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3033 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3034 "mesh_infos_page.html#mesh_element_info_anchor" );
3038 \brief Show mesh information
3040 void SMESHGUI_MeshInfoDlg::updateInfo()
3042 SUIT_OverrideCursor wc;
3044 SALOME_ListIO selected;
3045 SMESHGUI::selectionMgr()->selectedObjects( selected );
3047 if ( selected.Extent() == 1 ) {
3048 Handle(SALOME_InteractiveObject) IO = selected.First();
3052 // myBaseInfo->clear();
3053 // myElemInfo->clear();
3054 // myAddInfo->clear();
3059 \brief Activate dialog box
3061 void SMESHGUI_MeshInfoDlg::activate()
3063 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3064 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3065 myTabWidget->setEnabled( true );
3070 \brief Deactivate dialog box
3072 void SMESHGUI_MeshInfoDlg::deactivate()
3074 myTabWidget->setEnabled( false );
3075 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3079 \brief Called when users switches between node / element modes.
3081 void SMESHGUI_MeshInfoDlg::modeChanged()
3088 \brief Caled when users prints mesh element ID in the corresponding field.
3090 void SMESHGUI_MeshInfoDlg::idChanged()
3092 SVTK_Selector* selector = SMESH::GetSelector();
3093 if ( myActor && selector ) {
3094 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3095 TColStd_MapOfInteger ID;
3097 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3098 foreach ( QString tid, idTxt ) {
3099 long id = tid.trimmed().toLong();
3100 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3101 myActor->GetObject()->GetMesh()->FindElement( id ) :
3102 myActor->GetObject()->GetMesh()->FindNode( id );
3108 selector->AddOrRemoveIndex( IO, ID, false );
3109 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3110 aViewWindow->highlight( IO, true, true );
3111 aViewWindow->Repaint();
3113 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3117 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3119 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3120 myMode->button( NodeMode )->click();
3121 myID->setText( QString::number( id ) );
3125 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3127 if ( !theStr.isEmpty() ) {
3128 myMode->button( ElemMode )->click();
3129 myID->setText( theStr );
3133 void SMESHGUI_MeshInfoDlg::dump()
3135 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3137 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3138 if ( !appStudy ) return;
3139 _PTR( Study ) aStudy = appStudy->studyDS();
3141 QStringList aFilters;
3142 aFilters.append( tr( "TEXT_FILES" ) );
3144 bool anIsBase = true;
3145 bool anIsElem = true;
3146 bool anIsAdd = true;
3147 bool anIsCtrl = true;
3149 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3150 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3151 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3152 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3153 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3156 DumpFileDlg fd( this );
3157 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3158 fd.setNameFilters( aFilters );
3159 fd.myBaseChk->setChecked( anIsBase );
3160 fd.myElemChk->setChecked( anIsElem );
3161 fd.myAddChk ->setChecked( anIsAdd );
3162 fd.myCtrlChk->setChecked( anIsCtrl );
3163 if ( fd.exec() == QDialog::Accepted )
3165 QString aFileName = fd.selectedFile();
3167 bool toBase = fd.myBaseChk->isChecked();
3168 bool toElem = fd.myElemChk->isChecked();
3169 bool toAdd = fd.myAddChk->isChecked();
3170 bool toCtrl = fd.myCtrlChk->isChecked();
3172 if ( !aFileName.isEmpty() ) {
3173 QFileInfo aFileInfo( aFileName );
3174 if ( aFileInfo.isDir() )
3177 QFile aFile( aFileName );
3178 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3181 QTextStream out( &aFile );
3183 if ( toBase ) myBaseInfo->saveInfo( out );
3184 if ( toElem ) myElemInfo->saveInfo( out );
3185 if ( toAdd ) myAddInfo ->saveInfo( out );
3186 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3192 \class SMESHGUI_CtrlInfo
3193 \brief Class for the mesh controls information widget.
3198 \param parent parent widget
3200 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3201 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3203 setFrameStyle( StyledPanel | Sunken );
3205 myMainLayout = new QGridLayout( this );
3206 myMainLayout->setMargin( MARGIN );
3207 myMainLayout->setSpacing( SPACING );
3210 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3211 QLabel* aName = createField();
3212 aName->setMinimumWidth( 150 );
3215 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3216 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3218 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3221 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3222 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3223 QLabel* aNodesFree = createField();
3224 myWidgets << aNodesFree;
3225 myPredicates << aFilterMgr->CreateFreeNodes();
3227 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3228 QLabel* aNodesDouble = createField();
3229 myWidgets << aNodesDouble;
3230 myPredicates << aFilterMgr->CreateEqualNodes();
3231 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3232 myToleranceWidget = new SMESHGUI_SpinBox( this );
3233 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3234 myToleranceWidget->setAcceptNames( false );
3235 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3238 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3239 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3240 QLabel* anEdgesDouble = createField();
3241 myWidgets << anEdgesDouble;
3242 myPredicates << aFilterMgr->CreateEqualEdges();
3245 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3246 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3247 QLabel* aFacesDouble = createField();
3248 myWidgets << aFacesDouble;
3249 myPredicates << aFilterMgr->CreateEqualFaces();
3250 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3251 QLabel* aFacesOver = createField();
3252 myWidgets << aFacesOver;
3253 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3254 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3255 myPlot = createPlot( this );
3256 myAspectRatio = aFilterMgr->CreateAspectRatio();
3259 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3260 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3261 QLabel* aVolumesDouble = createField();
3262 myWidgets << aVolumesDouble;
3263 myPredicates << aFilterMgr->CreateEqualVolumes();
3264 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3265 QLabel* aVolumesOver = createField();
3266 myWidgets << aVolumesOver;
3267 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3268 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3269 myPlot3D = createPlot( this );
3270 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3272 QToolButton* aFreeNodesBtn = new QToolButton( this );
3273 aFreeNodesBtn->setIcon(aComputeIcon);
3274 myButtons << aFreeNodesBtn; //0
3276 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3277 aDoubleNodesBtn->setIcon(aComputeIcon);
3278 myButtons << aDoubleNodesBtn; //1
3280 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3281 aDoubleEdgesBtn->setIcon(aComputeIcon);
3282 myButtons << aDoubleEdgesBtn; //2
3284 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3285 aDoubleFacesBtn->setIcon(aComputeIcon);
3286 myButtons << aDoubleFacesBtn; //3
3288 QToolButton* aOverContFacesBtn = new QToolButton( this );
3289 aOverContFacesBtn->setIcon(aComputeIcon);
3290 myButtons << aOverContFacesBtn; //4
3292 QToolButton* aComputeFaceBtn = new QToolButton( this );
3293 aComputeFaceBtn->setIcon(aComputeIcon);
3294 myButtons << aComputeFaceBtn; //5
3296 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3297 aDoubleVolumesBtn->setIcon(aComputeIcon);
3298 myButtons << aDoubleVolumesBtn; //6
3300 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3301 aOverContVolumesBtn->setIcon(aComputeIcon);
3302 myButtons << aOverContVolumesBtn; //7
3304 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3305 aComputeVolumeBtn->setIcon(aComputeIcon);
3306 myButtons << aComputeVolumeBtn; //8
3308 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3309 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3310 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3311 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3312 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3313 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3314 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3315 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3316 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3317 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3319 setFontAttributes( aNameLab );
3320 setFontAttributes( aNodesLab );
3321 setFontAttributes( anEdgesLab );
3322 setFontAttributes( aFacesLab );
3323 setFontAttributes( aVolumesLab );
3325 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3326 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3327 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3328 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3329 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3330 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3331 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3332 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3333 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3334 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3335 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3336 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3337 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3338 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3339 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3340 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3341 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3342 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3343 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3344 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3345 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3346 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3347 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3348 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3349 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3350 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3351 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3352 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3353 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3354 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3355 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3356 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3357 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3358 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3359 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3361 myMainLayout->setColumnStretch( 0, 0 );
3362 myMainLayout->setColumnStretch( 1, 5 );
3363 myMainLayout->setRowStretch ( 11, 5 );
3364 myMainLayout->setRowStretch ( 16, 5 );
3365 myMainLayout->setRowStretch ( 17, 1 );
3373 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3377 \brief Change widget font attributes (bold, ...).
3379 \param attr font attributes (XORed flags)
3381 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3384 QFont f = w->font();
3391 \brief Create info field
3392 \return new info field
3394 QLabel* SMESHGUI_CtrlInfo::createField()
3396 QLabel* lab = new QLabel( this );
3397 lab->setFrameStyle( StyledPanel | Sunken );
3398 lab->setAlignment( Qt::AlignCenter );
3399 lab->setAutoFillBackground( true );
3400 QPalette pal = lab->palette();
3401 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3402 lab->setPalette( pal );
3403 lab->setMinimumWidth( 60 );
3408 \brief Create QwtPlot
3411 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3413 QwtPlot* aPlot = new QwtPlot( parent );
3414 aPlot->setMinimumSize( 100, 100 );
3415 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3416 xFont.setPointSize( 5 );
3417 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3418 yFont.setPointSize( 5 );
3419 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3420 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3426 \brief Show controls information on the selected object
3428 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3432 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3433 if ( myObject->_is_nil() ) return;
3435 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3436 myWidgets[0]->setText( aSO->GetName().c_str() );
3438 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3439 if ( mesh->_is_nil() ) return;
3441 const bool meshLoaded = mesh->IsLoaded();
3442 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3443 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3444 for ( int i = 0; i < myButtons.count(); ++i )
3445 myButtons[i]->setEnabled( true );
3447 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3448 if ( ! &nbElemsByType.in() ) return;
3450 const CORBA::Long ctrlLimit =
3451 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3454 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3455 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3456 nbElemsByType[ SMESH::FACE ] +
3457 nbElemsByType[ SMESH::VOLUME ] );
3458 if ( nbNodes + nbElems > 0 ) {
3459 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3461 computeFreeNodesInfo();
3463 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3464 computeDoubleNodesInfo();
3467 myButtons[0]->setEnabled( true );
3468 myButtons[1]->setEnabled( true );
3472 for( int i=2; i<=10; i++)
3473 myMainLayout->itemAt(i)->widget()->setVisible( false );
3477 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3479 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3480 computeDoubleEdgesInfo();
3482 myButtons[2]->setEnabled( true );
3485 for( int i=11; i<=14; i++)
3486 myMainLayout->itemAt(i)->widget()->setVisible( false );
3490 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3491 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3493 computeDoubleFacesInfo();
3494 // over constrained faces
3495 computeOverConstrainedFacesInfo();
3496 // aspect Ratio histogram
3497 computeAspectRatio();
3500 myButtons[3]->setEnabled( true );
3501 myButtons[4]->setEnabled( true );
3502 myButtons[5]->setEnabled( true );
3504 #ifdef DISABLE_PLOT2DVIEWER
3505 myMainLayout->setRowStretch(11,0);
3506 for( int i=22; i<=24; i++)
3507 myMainLayout->itemAt(i)->widget()->setVisible( false );
3511 myMainLayout->setRowStretch(11,0);
3512 for( int i=15; i<=24; i++)
3513 myMainLayout->itemAt(i)->widget()->setVisible( false );
3517 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3518 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3520 computeDoubleVolumesInfo();
3521 // over constrained volumes
3522 computeOverConstrainedVolumesInfo();
3523 // aspect Ratio 3D histogram
3524 computeAspectRatio3D();
3527 myButtons[6]->setEnabled( true );
3528 myButtons[7]->setEnabled( true );
3529 myButtons[8]->setEnabled( true );
3531 #ifdef DISABLE_PLOT2DVIEWER
3532 myMainLayout->setRowStretch(16,0);
3533 for( int i=32; i<=34; i++)
3534 myMainLayout->itemAt(i)->widget()->setVisible( false );
3538 myMainLayout->setRowStretch(16,0);
3539 for( int i=25; i<=34; i++)
3540 myMainLayout->itemAt(i)->widget()->setVisible( false );
3544 //================================================================================
3546 * \brief Computes and shows nb of elements satisfying a given predicate
3547 * \param [in] ft - a predicate type (SMESH::FunctorType)
3548 * \param [in] iBut - index of one of myButtons to disable
3549 * \param [in] iWdg - index of one of myWidgets to show the computed number
3551 //================================================================================
3553 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3555 myButtons[ iBut ]->setEnabled( false );
3556 myWidgets[ iWdg ]->setText( "" );
3557 if ( myObject->_is_nil() ) return;
3559 SUIT_OverrideCursor wc;
3561 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3562 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3565 this->showInfo( myObject ); // try to show all values
3566 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3567 return; // <ft> predicate already computed
3569 // look for a predicate of type <ft>
3570 for ( int i = 0; i < myPredicates.count(); ++i )
3571 if ( myPredicates[i]->GetFunctorType() == ft )
3573 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3574 myWidgets[ iWdg ]->setText( QString::number( nb ));
3578 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3580 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3583 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3585 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3588 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3590 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3593 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3595 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3598 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3600 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3603 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3605 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3608 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3610 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3613 void SMESHGUI_CtrlInfo::computeAspectRatio()
3615 #ifndef DISABLE_PLOT2DVIEWER
3616 myButtons[5]->setEnabled( false );
3618 if ( myObject->_is_nil() ) return;
3620 SUIT_OverrideCursor wc;
3622 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3623 if ( aHistogram && !aHistogram->isEmpty() ) {
3624 QwtPlotItem* anItem = aHistogram->createPlotItem();
3625 anItem->attach( myPlot );
3632 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3634 #ifndef DISABLE_PLOT2DVIEWER
3635 myButtons[8]->setEnabled( false );
3637 if ( myObject->_is_nil() ) return;
3639 SUIT_OverrideCursor wc;
3641 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3642 if ( aHistogram && !aHistogram->isEmpty() ) {
3643 QwtPlotItem* anItem = aHistogram->createPlotItem();
3644 anItem->attach( myPlot3D );
3652 \brief Internal clean-up (reset widget)
3654 void SMESHGUI_CtrlInfo::clearInternal()
3656 for( int i=0; i<=34; i++)
3657 myMainLayout->itemAt(i)->widget()->setVisible( true );
3658 for( int i=0; i<=8; i++)
3659 myButtons[i]->setEnabled( false );
3660 myPlot->detachItems();
3661 myPlot3D->detachItems();
3664 myWidgets[0]->setText( QString() );
3665 for ( int i = 1; i < myWidgets.count(); i++ )
3666 myWidgets[i]->setText( "" );
3667 myMainLayout->setRowStretch(11,5);
3668 myMainLayout->setRowStretch(16,5);
3671 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3673 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3674 myButtons[1]->setEnabled( true );
3675 myWidgets[2]->setText("");
3678 #ifndef DISABLE_PLOT2DVIEWER
3679 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3681 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3682 if ( mesh->_is_nil() ) return 0;
3683 if ( !mesh->IsLoaded() )
3685 aNumFun->SetMesh( mesh );
3687 CORBA::Long cprecision = 6;
3688 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3689 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3690 aNumFun->SetPrecision( cprecision );
3692 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3694 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3695 /*isLogarithmic=*/false,
3697 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3698 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3699 if ( &histogramVar.in() )
3701 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3702 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3703 if ( histogramVar->length() >= 2 )
3704 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3710 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3711 out << QString( 20, '-' ) << "\n";
3712 out << tr( "CTRL_INFO" ) << "\n";
3713 out << QString( 20, '-' ) << "\n";
3714 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3715 out << tr( "NODES_INFO" ) << "\n";
3716 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3717 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3718 out << tr( "EDGES_INFO" ) << "\n";
3719 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3720 out << tr( "FACES_INFO" ) << "\n";
3721 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3722 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3723 out << tr( "VOLUMES_INFO" ) << "\n";
3724 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3725 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3729 \class SMESHGUI_CtrlInfoDlg
3730 \brief Controls information dialog box
3735 \param parent parent widget
3736 \param page specifies the dialog page to be shown at the start-up
3738 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3741 setAttribute( Qt::WA_DeleteOnClose, true );
3742 setWindowTitle( tr( "CTRL_INFO" ) );
3743 setMinimumSize( 400, 600 );
3745 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3748 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3749 okBtn->setAutoDefault( true );
3750 okBtn->setDefault( true );
3752 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3753 dumpBtn->setAutoDefault( true );
3754 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3755 helpBtn->setAutoDefault( true );
3757 QHBoxLayout* btnLayout = new QHBoxLayout;
3758 btnLayout->setSpacing( SPACING );
3759 btnLayout->setMargin( 0 );
3761 btnLayout->addWidget( okBtn );
3762 btnLayout->addWidget( dumpBtn );
3763 btnLayout->addStretch( 10 );
3764 btnLayout->addWidget( helpBtn );
3766 QVBoxLayout* l = new QVBoxLayout ( this );
3767 l->setMargin( MARGIN );
3768 l->setSpacing( SPACING );
3769 l->addWidget( myCtrlInfo );
3770 l->addLayout( btnLayout );
3772 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3773 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3774 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3775 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3776 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3784 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3789 \brief Show controls information
3790 \param IO interactive object
3792 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3794 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3795 myCtrlInfo->showInfo( obj );
3799 \brief Perform clean-up actions on the dialog box closing.
3801 void SMESHGUI_CtrlInfoDlg::reject()
3803 SMESH::SetPointRepresentation( false );
3808 \brief Setup selection mode depending on the current dialog box state.
3810 void SMESHGUI_CtrlInfoDlg::updateSelection()
3812 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3813 disconnect( selMgr, 0, this, 0 );
3814 SMESH::SetPointRepresentation( false );
3815 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3820 \brief Show mesh information
3822 void SMESHGUI_CtrlInfoDlg::updateInfo()
3824 SUIT_OverrideCursor wc;
3826 SALOME_ListIO selected;
3827 SMESHGUI::selectionMgr()->selectedObjects( selected );
3829 if ( selected.Extent() == 1 ) {
3830 Handle(SALOME_InteractiveObject) IO = selected.First();
3836 \brief Activate dialog box
3838 void SMESHGUI_CtrlInfoDlg::activate()
3840 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3841 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3846 \brief Deactivate dialog box
3848 void SMESHGUI_CtrlInfoDlg::deactivate()
3850 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3854 * \brief Dump contents into a file
3856 void SMESHGUI_CtrlInfoDlg::dump()
3858 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3860 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3861 if ( !appStudy ) return;
3862 _PTR( Study ) aStudy = appStudy->studyDS();
3864 QStringList aFilters;
3865 aFilters.append( tr( "TEXT_FILES" ) );
3867 DumpFileDlg fd( this );
3868 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3869 fd.setNameFilters( aFilters );
3870 fd.myBaseChk->hide();
3871 fd.myElemChk->hide();
3872 fd.myAddChk ->hide();
3873 fd.myCtrlChk->hide();
3874 if ( fd.exec() == QDialog::Accepted )
3876 QString aFileName = fd.selectedFile();
3877 if ( !aFileName.isEmpty() ) {
3878 QFileInfo aFileInfo( aFileName );
3879 if ( aFileInfo.isDir() )
3882 QFile aFile( aFileName );
3883 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3886 QTextStream out( &aFile );
3887 myCtrlInfo->saveInfo( out );
3895 void SMESHGUI_CtrlInfoDlg::help()
3897 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");