1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESHGUI_MeshInfo.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_MeshInfo.h"
27 #include "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 ) {
1230 double u = 0, v = 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 ) {
1754 double u = 0, v = 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 SUIT_OverrideCursor wc;
2328 QTreeWidgetItem* item = myItem;
2330 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2331 item->treeWidget()->removeItemWidget( item, 1 );
2332 item->setText( 1, QString::number( nb ));
2337 \class SMESHGUI_AddInfo
2338 \brief The wigdet shows additional information on the mesh object.
2343 \param parent parent widget
2345 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2346 : QTreeWidget( parent )
2348 setColumnCount( 2 );
2349 header()->setStretchLastSection( true );
2350 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2351 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2353 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2361 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2366 \brief Show additional information on the selected object
2367 \param obj object being processed (mesh, sub-mesh, group, ID source)
2369 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2371 setProperty( "group_index", 0 );
2372 setProperty( "submesh_index", 0 );
2373 myComputors.clear();
2376 if ( CORBA::is_nil( obj ) ) return;
2378 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2379 if ( !sobj ) return;
2382 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2383 nameItem->setText( 0, tr( "NAME" ) );
2384 nameItem->setText( 1, sobj->GetName().c_str() );
2386 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2387 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2388 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2390 if ( !aMesh->_is_nil() )
2391 meshInfo( aMesh, nameItem );
2392 else if ( !aSubMesh->_is_nil() )
2393 subMeshInfo( aSubMesh, nameItem );
2394 else if ( !aGroup->_is_nil() )
2395 groupInfo( aGroup.in(), nameItem );
2399 \brief Create new tree item.
2400 \param parent parent tree widget item
2401 \param flags item flag
2402 \return new tree widget item
2404 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2406 QTreeWidgetItem* item;
2409 item = new QTreeWidgetItem( parent );
2411 item = new QTreeWidgetItem( this );
2413 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2415 QFont f = item->font( 0 );
2417 for ( int i = 0; i < columnCount(); i++ ) {
2418 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2419 item->setFont( i, f );
2422 item->setExpanded( true );
2427 \brief Show mesh info
2428 \param mesh mesh object
2429 \param parent parent tree item
2431 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2434 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2435 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2436 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2437 typeItem->setText( 0, tr( "TYPE" ) );
2438 if ( !CORBA::is_nil( shape ) ) {
2439 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2440 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2442 QTreeWidgetItem* gobjItem = createItem( typeItem );
2443 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2444 gobjItem->setText( 1, sobj->GetName().c_str() );
2447 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2448 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2449 QTreeWidgetItem* fileItem = createItem( typeItem );
2450 fileItem->setText( 0, tr( "FILE_NAME" ) );
2451 fileItem->setText( 1, (char*)inf->fileName );
2454 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2458 myGroups = mesh->GetGroups();
2462 mySubMeshes = mesh->GetSubMeshes();
2467 \brief Show sub-mesh info
2468 \param subMesh sub-mesh object
2469 \param parent parent tree item
2471 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2473 bool isShort = parent->parent() != 0;
2477 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2479 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2480 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2481 nameItem->setText( 1, sobj->GetName().c_str() );
2486 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2487 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2489 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2490 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2491 gobjItem->setText( 1, sobj->GetName().c_str() );
2496 \brief Show group info
2497 \param grp mesh group object
2498 \param parent parent tree item
2500 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2502 bool isShort = parent->parent() != 0;
2504 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2505 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2506 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2510 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2512 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2513 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2514 nameItem->setText( 1, sobj->GetName().c_str() );
2518 // type : group on geometry, standalone group, group on filter
2519 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2520 typeItem->setText( 0, tr( "TYPE" ) );
2521 if ( !CORBA::is_nil( aStdGroup ) ) {
2522 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2524 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2525 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2526 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2527 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2529 QTreeWidgetItem* gobjItem = createItem( typeItem );
2530 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2531 gobjItem->setText( 1, sobj->GetName().c_str() );
2534 else if ( !CORBA::is_nil( aFltGroup ) ) {
2535 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2540 QString etype = tr( "UNKNOWN" );
2541 switch( grp->GetType() ) {
2543 etype = tr( "NODE" );
2546 etype = tr( "EDGE" );
2549 etype = tr( "FACE" );
2552 etype = tr( "VOLUME" );
2555 etype = tr( "0DELEM" );
2558 etype = tr( "BALL" );
2563 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2564 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2565 etypeItem->setText( 1, etype );
2568 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2569 bool meshLoaded = mesh->IsLoaded();
2571 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2573 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2574 groupSize = grp->Size();
2576 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2577 sizeItem->setText( 0, tr( "SIZE" ) );
2578 if ( groupSize > -1 ) {
2579 sizeItem->setText( 1, QString::number( groupSize ) );
2582 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2583 setItemWidget( sizeItem, 1, btn );
2584 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2585 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2586 myComputors.append( comp );
2588 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2592 SALOMEDS::Color color = grp->GetColor();
2593 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2594 colorItem->setText( 0, tr( "COLOR" ) );
2595 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2597 // nb of underlying nodes
2598 if ( grp->GetType() != SMESH::NODE) {
2599 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2600 nodesItem->setText( 0, tr( "NB_NODES" ) );
2601 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2602 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2603 if ( toShowNodes && meshLoaded ) {
2604 // already calculated and up-to-date
2605 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2608 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2609 setItemWidget( nodesItem, 1, btn );
2610 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2611 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2612 myComputors.append( comp );
2614 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2619 void SMESHGUI_AddInfo::showGroups()
2621 myComputors.clear();
2623 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2624 if ( !parent ) return;
2626 int idx = property( "group_index" ).toInt();
2628 QTreeWidgetItem* itemGroups = 0;
2629 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2630 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2631 itemGroups = parent->child( i );
2632 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2634 extra->updateControls( myGroups->length(), idx );
2635 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2639 QMap<int, QTreeWidgetItem*> grpItems;
2640 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2641 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2642 if ( CORBA::is_nil( grp ) ) continue;
2643 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2644 if ( !grpSObj ) continue;
2646 int grpType = grp->GetType();
2648 if ( !itemGroups ) {
2649 // create top-level groups container item
2650 itemGroups = createItem( parent, Bold | All );
2651 itemGroups->setText( 0, tr( "GROUPS" ) );
2652 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2654 // total number of groups > 10, show extra widgets for info browsing
2655 if ((int) myGroups->length() > MAXITEMS ) {
2656 ExtraWidget* extra = new ExtraWidget( this, true );
2657 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2658 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2659 setItemWidget( itemGroups, 1, extra );
2660 extra->updateControls( myGroups->length(), idx );
2664 if ( grpItems.find( grpType ) == grpItems.end() ) {
2665 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2666 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2667 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2671 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2672 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2675 groupInfo( grp.in(), grpNameItem );
2679 void SMESHGUI_AddInfo::showSubMeshes()
2681 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2682 if ( !parent ) return;
2684 int idx = property( "submesh_index" ).toInt();
2686 QTreeWidgetItem* itemSubMeshes = 0;
2687 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2688 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2689 itemSubMeshes = parent->child( i );
2690 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2692 extra->updateControls( mySubMeshes->length(), idx );
2693 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2697 QMap<int, QTreeWidgetItem*> smItems;
2698 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2699 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2700 if ( CORBA::is_nil( sm ) ) continue;
2701 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2702 if ( !smSObj ) continue;
2704 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2705 if ( CORBA::is_nil(gobj ) ) continue;
2707 int smType = gobj->GetShapeType();
2708 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2710 if ( !itemSubMeshes ) {
2711 itemSubMeshes = createItem( parent, Bold | All );
2712 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2713 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2715 // total number of sub-meshes > 10, show extra widgets for info browsing
2716 if ((int) mySubMeshes->length() > MAXITEMS ) {
2717 ExtraWidget* extra = new ExtraWidget( this, true );
2718 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2719 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2720 setItemWidget( itemSubMeshes, 1, extra );
2721 extra->updateControls( mySubMeshes->length(), idx );
2725 if ( smItems.find( smType ) == smItems.end() ) {
2726 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2727 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2728 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2732 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2733 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2736 subMeshInfo( sm.in(), smNameItem );
2741 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2743 void SMESHGUI_AddInfo::changeLoadToCompute()
2745 for ( int i = 0; i < myComputors.count(); ++i )
2747 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2749 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2750 btn->setText( tr("COMPUTE") );
2755 void SMESHGUI_AddInfo::showPreviousGroups()
2757 int idx = property( "group_index" ).toInt();
2758 setProperty( "group_index", idx-1 );
2762 void SMESHGUI_AddInfo::showNextGroups()
2764 int idx = property( "group_index" ).toInt();
2765 setProperty( "group_index", idx+1 );
2769 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2771 int idx = property( "submesh_index" ).toInt();
2772 setProperty( "submesh_index", idx-1 );
2776 void SMESHGUI_AddInfo::showNextSubMeshes()
2778 int idx = property( "submesh_index" ).toInt();
2779 setProperty( "submesh_index", idx+1 );
2783 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2785 out << QString( 15, '-') << "\n";
2786 out << tr( "ADDITIONAL_INFO" ) << "\n";
2787 out << QString( 15, '-' ) << "\n";
2788 QTreeWidgetItemIterator it( this );
2790 if ( !( ( *it )->text(0) ).isEmpty() ) {
2791 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2792 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2793 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2795 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2804 \class SMESHGUI_MeshInfoDlg
2805 \brief Mesh information dialog box
2810 \param parent parent widget
2811 \param page specifies the dialog page to be shown at the start-up
2813 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2814 : QDialog( parent ), myActor( 0 )
2817 setAttribute( Qt::WA_DeleteOnClose, true );
2818 setWindowTitle( tr( "MESH_INFO" ) );
2819 setSizeGripEnabled( true );
2821 myTabWidget = new QTabWidget( this );
2825 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2826 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2830 QWidget* w = new QWidget( myTabWidget );
2832 myMode = new QButtonGroup( this );
2833 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2834 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2835 myMode->button( NodeMode )->setChecked( true );
2836 myID = new QLineEdit( w );
2837 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2839 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2840 mode = qMin( 1, qMax( 0, mode ) );
2843 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2845 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2847 QGridLayout* elemLayout = new QGridLayout( w );
2848 elemLayout->setMargin( MARGIN );
2849 elemLayout->setSpacing( SPACING );
2850 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2851 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2852 elemLayout->addWidget( myID, 0, 2 );
2853 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2855 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2859 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2860 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2864 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2865 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2869 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2870 okBtn->setAutoDefault( true );
2871 okBtn->setDefault( true );
2873 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2874 dumpBtn->setAutoDefault( true );
2875 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2876 helpBtn->setAutoDefault( true );
2878 QHBoxLayout* btnLayout = new QHBoxLayout;
2879 btnLayout->setSpacing( SPACING );
2880 btnLayout->setMargin( 0 );
2882 btnLayout->addWidget( okBtn );
2883 btnLayout->addWidget( dumpBtn );
2884 btnLayout->addStretch( 10 );
2885 btnLayout->addWidget( helpBtn );
2887 QVBoxLayout* l = new QVBoxLayout ( this );
2888 l->setMargin( MARGIN );
2889 l->setSpacing( SPACING );
2890 l->addWidget( myTabWidget );
2891 l->addLayout( btnLayout );
2893 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2895 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2896 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2897 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2898 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2899 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2900 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2901 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2902 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2903 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2904 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2912 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2917 \brief Show mesh information
2918 \param IO interactive object
2920 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2925 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2926 if ( !CORBA::is_nil( obj ) )
2928 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2929 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2930 if ( myTabWidget->currentIndex() == CtrlInfo )
2931 myCtrlInfo->showInfo( obj );
2934 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2935 SVTK_Selector* selector = SMESH::GetSelector();
2938 if ( myActor && selector ) {
2939 nb = myMode->checkedId() == NodeMode ?
2940 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2941 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2943 myElemInfo->setSource( myActor ) ;
2945 myID->setText( ID.trimmed() );
2947 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2948 foreach ( ID, idTxt )
2949 ids << ID.trimmed().toLong();
2950 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2954 myElemInfo->clear();
2961 \brief Perform clean-up actions on the dialog box closing.
2963 void SMESHGUI_MeshInfoDlg::reject()
2965 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2966 selMgr->clearFilters();
2967 SMESH::SetPointRepresentation( false );
2968 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2969 aViewWindow->SetSelectionMode( ActorSelection );
2974 \brief Process keyboard event
2975 \param e key press event
2977 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2979 QDialog::keyPressEvent( e );
2980 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2987 \brief Reactivate dialog box, when mouse pointer goes into it.
2989 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2995 \brief Setup selection mode depending on the current dialog box state.
2997 void SMESHGUI_MeshInfoDlg::updateSelection()
2999 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3001 disconnect( selMgr, 0, this, 0 );
3002 selMgr->clearFilters();
3004 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
3005 SMESH::SetPointRepresentation( false );
3006 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3007 aViewWindow->SetSelectionMode( ActorSelection );
3010 if ( myMode->checkedId() == NodeMode ) {
3011 SMESH::SetPointRepresentation( true );
3012 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3013 aViewWindow->SetSelectionMode( NodeSelection );
3016 SMESH::SetPointRepresentation( false );
3017 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3018 aViewWindow->SetSelectionMode( CellSelection );
3022 QString oldID = myID->text().trimmed();
3023 SMESH_Actor* oldActor = myActor;
3026 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3029 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3030 myID->setText( oldID );
3036 \brief Show help page
3038 void SMESHGUI_MeshInfoDlg::help()
3040 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3041 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3042 "mesh_infos_page.html#mesh_element_info_anchor" );
3046 \brief Show mesh information
3048 void SMESHGUI_MeshInfoDlg::updateInfo()
3050 SUIT_OverrideCursor wc;
3052 SALOME_ListIO selected;
3053 SMESHGUI::selectionMgr()->selectedObjects( selected );
3055 if ( selected.Extent() == 1 ) {
3056 Handle(SALOME_InteractiveObject) IO = selected.First();
3065 \brief Activate dialog box
3067 void SMESHGUI_MeshInfoDlg::activate()
3069 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3070 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3071 myTabWidget->setEnabled( true );
3076 \brief Deactivate dialog box
3078 void SMESHGUI_MeshInfoDlg::deactivate()
3080 myTabWidget->setEnabled( false );
3081 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3085 \brief Called when users switches between node / element modes.
3087 void SMESHGUI_MeshInfoDlg::modeChanged()
3094 \brief Caled when users prints mesh element ID in the corresponding field.
3096 void SMESHGUI_MeshInfoDlg::idChanged()
3098 SVTK_Selector* selector = SMESH::GetSelector();
3099 if ( myActor && selector ) {
3100 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3101 TColStd_MapOfInteger ID;
3103 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3104 foreach ( QString tid, idTxt ) {
3105 long id = tid.trimmed().toLong();
3106 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3107 myActor->GetObject()->GetMesh()->FindElement( id ) :
3108 myActor->GetObject()->GetMesh()->FindNode( id );
3114 selector->AddOrRemoveIndex( IO, ID, false );
3115 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3116 aViewWindow->highlight( IO, true, true );
3117 aViewWindow->Repaint();
3119 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3123 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3125 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3126 myMode->button( NodeMode )->click();
3127 myID->setText( QString::number( id ) );
3131 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3133 if ( !theStr.isEmpty() ) {
3134 myMode->button( ElemMode )->click();
3135 myID->setText( theStr );
3139 void SMESHGUI_MeshInfoDlg::dump()
3141 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3143 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3144 if ( !appStudy ) return;
3145 _PTR( Study ) aStudy = appStudy->studyDS();
3147 QStringList aFilters;
3148 aFilters.append( tr( "TEXT_FILES" ) );
3150 bool anIsBase = true;
3151 bool anIsElem = true;
3152 bool anIsAdd = true;
3153 bool anIsCtrl = true;
3155 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3156 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3157 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3158 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3159 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3162 DumpFileDlg fd( this );
3163 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3164 fd.setNameFilters( aFilters );
3165 fd.myBaseChk->setChecked( anIsBase );
3166 fd.myElemChk->setChecked( anIsElem );
3167 fd.myAddChk ->setChecked( anIsAdd );
3168 fd.myCtrlChk->setChecked( anIsCtrl );
3169 if ( fd.exec() == QDialog::Accepted )
3171 QString aFileName = fd.selectedFile();
3173 bool toBase = fd.myBaseChk->isChecked();
3174 bool toElem = fd.myElemChk->isChecked();
3175 bool toAdd = fd.myAddChk->isChecked();
3176 bool toCtrl = fd.myCtrlChk->isChecked();
3178 if ( !aFileName.isEmpty() ) {
3179 QFileInfo aFileInfo( aFileName );
3180 if ( aFileInfo.isDir() )
3183 QFile aFile( aFileName );
3184 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3187 QTextStream out( &aFile );
3189 if ( toBase ) myBaseInfo->saveInfo( out );
3190 if ( toElem ) myElemInfo->saveInfo( out );
3191 if ( toAdd ) myAddInfo ->saveInfo( out );
3192 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3198 \class SMESHGUI_CtrlInfo
3199 \brief Class for the mesh controls information widget.
3204 \param parent parent widget
3206 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3207 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3209 setFrameStyle( StyledPanel | Sunken );
3211 myMainLayout = new QGridLayout( this );
3212 myMainLayout->setMargin( MARGIN );
3213 myMainLayout->setSpacing( SPACING );
3216 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3217 QLabel* aName = createField();
3218 aName->setMinimumWidth( 150 );
3221 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3222 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3224 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3227 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3228 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3229 QLabel* aNodesFree = createField();
3230 myWidgets << aNodesFree;
3231 myPredicates << aFilterMgr->CreateFreeNodes();
3233 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3234 QLabel* aNodesNbConn = createField();
3235 myWidgets << aNodesNbConn;
3236 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3238 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3239 QLabel* aNodesDouble = createField();
3240 myWidgets << aNodesDouble;
3241 myPredicates << aFilterMgr->CreateEqualNodes();
3242 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3243 myToleranceWidget = new SMESHGUI_SpinBox( this );
3244 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3245 myToleranceWidget->setAcceptNames( false );
3246 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3249 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3250 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3251 QLabel* anEdgesDouble = createField();
3252 myWidgets << anEdgesDouble;
3253 myPredicates << aFilterMgr->CreateEqualEdges();
3256 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3257 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3258 QLabel* aFacesDouble = createField();
3259 myWidgets << aFacesDouble;
3260 myPredicates << aFilterMgr->CreateEqualFaces();
3261 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3262 QLabel* aFacesOver = createField();
3263 myWidgets << aFacesOver;
3264 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3265 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3266 myPlot = createPlot( this );
3267 myAspectRatio = aFilterMgr->CreateAspectRatio();
3270 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3271 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3272 QLabel* aVolumesDouble = createField();
3273 myWidgets << aVolumesDouble;
3274 myPredicates << aFilterMgr->CreateEqualVolumes();
3275 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3276 QLabel* aVolumesOver = createField();
3277 myWidgets << aVolumesOver;
3278 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3279 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3280 myPlot3D = createPlot( this );
3281 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3283 QToolButton* aFreeNodesBtn = new QToolButton( this );
3284 aFreeNodesBtn->setIcon(aComputeIcon);
3285 myButtons << aFreeNodesBtn; //0
3287 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3288 aNodesNbConnBtn->setIcon(aComputeIcon);
3289 myButtons << aNodesNbConnBtn; //1
3291 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3292 aDoubleNodesBtn->setIcon(aComputeIcon);
3293 myButtons << aDoubleNodesBtn; //2
3295 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3296 aDoubleEdgesBtn->setIcon(aComputeIcon);
3297 myButtons << aDoubleEdgesBtn; //3
3299 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3300 aDoubleFacesBtn->setIcon(aComputeIcon);
3301 myButtons << aDoubleFacesBtn; //4
3303 QToolButton* aOverContFacesBtn = new QToolButton( this );
3304 aOverContFacesBtn->setIcon(aComputeIcon);
3305 myButtons << aOverContFacesBtn; //5
3307 QToolButton* aComputeFaceBtn = new QToolButton( this );
3308 aComputeFaceBtn->setIcon(aComputeIcon);
3309 myButtons << aComputeFaceBtn; //6
3311 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3312 aDoubleVolumesBtn->setIcon(aComputeIcon);
3313 myButtons << aDoubleVolumesBtn; //7
3315 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3316 aOverContVolumesBtn->setIcon(aComputeIcon);
3317 myButtons << aOverContVolumesBtn; //8
3319 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3320 aComputeVolumeBtn->setIcon(aComputeIcon);
3321 myButtons << aComputeVolumeBtn; //9
3323 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3324 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3325 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3326 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3327 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3328 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3329 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3330 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3331 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3332 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3333 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3335 setFontAttributes( aNameLab );
3336 setFontAttributes( aNodesLab );
3337 setFontAttributes( anEdgesLab );
3338 setFontAttributes( aFacesLab );
3339 setFontAttributes( aVolumesLab );
3341 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3342 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3343 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3344 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3345 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3346 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3347 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3348 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3349 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3350 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3351 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3352 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3353 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3354 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3355 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3356 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3357 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3358 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3359 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3360 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3361 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3362 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3363 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3364 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3365 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3366 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3367 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3368 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3369 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3370 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3371 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3372 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3373 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3374 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3375 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3376 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3377 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3378 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3380 myMainLayout->setColumnStretch( 0, 0 );
3381 myMainLayout->setColumnStretch( 1, 5 );
3382 myMainLayout->setRowStretch ( 11, 5 );
3383 myMainLayout->setRowStretch ( 16, 5 );
3384 myMainLayout->setRowStretch ( 17, 1 );
3392 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3396 \brief Change widget font attributes (bold, ...).
3398 \param attr font attributes (XORed flags)
3400 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3403 QFont f = w->font();
3410 \brief Create info field
3411 \return new info field
3413 QLabel* SMESHGUI_CtrlInfo::createField()
3415 QLabel* lab = new QLabel( this );
3416 lab->setFrameStyle( StyledPanel | Sunken );
3417 lab->setAlignment( Qt::AlignCenter );
3418 lab->setAutoFillBackground( true );
3419 QPalette pal = lab->palette();
3420 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3421 lab->setPalette( pal );
3422 lab->setMinimumWidth( 60 );
3427 \brief Create QwtPlot
3430 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3432 QwtPlot* aPlot = new QwtPlot( parent );
3433 aPlot->setMinimumSize( 100, 100 );
3434 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3435 xFont.setPointSize( 5 );
3436 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3437 yFont.setPointSize( 5 );
3438 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3439 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3445 \brief Show controls information on the selected object
3447 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3451 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3452 if ( myObject->_is_nil() ) return;
3454 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3455 myWidgets[0]->setText( aSO->GetName().c_str() );
3457 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3458 if ( mesh->_is_nil() ) return;
3460 const bool meshLoaded = mesh->IsLoaded();
3461 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3462 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3463 for ( int i = 0; i < myButtons.count(); ++i )
3464 myButtons[i]->setEnabled( true );
3466 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3467 if ( ! &nbElemsByType.in() ) return;
3469 const CORBA::Long ctrlLimit =
3470 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3473 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3474 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3475 nbElemsByType[ SMESH::FACE ] +
3476 nbElemsByType[ SMESH::VOLUME ] );
3477 if ( nbNodes + nbElems > 0 ) {
3478 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3480 computeFreeNodesInfo();
3481 computeNodesNbConnInfo();
3483 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3484 computeDoubleNodesInfo();
3487 myButtons[0]->setEnabled( true );
3488 myButtons[1]->setEnabled( true );
3489 myButtons[2]->setEnabled( true );
3493 for( int i=2; i<=11; i++)
3494 myMainLayout->itemAt(i)->widget()->setVisible( false );
3498 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3500 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3501 computeDoubleEdgesInfo();
3503 myButtons[3]->setEnabled( true );
3506 for( int i=11; i<=14; i++)
3507 myMainLayout->itemAt(i)->widget()->setVisible( false );
3511 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3512 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3514 computeDoubleFacesInfo();
3515 // over constrained faces
3516 computeOverConstrainedFacesInfo();
3517 // aspect Ratio histogram
3518 computeAspectRatio();
3521 myButtons[4]->setEnabled( true );
3522 myButtons[5]->setEnabled( true );
3523 myButtons[6]->setEnabled( true );
3525 #ifdef DISABLE_PLOT2DVIEWER
3526 myMainLayout->setRowStretch(12,0);
3527 for( int i=25; i<=27; i++)
3528 myMainLayout->itemAt(i)->widget()->setVisible( false );
3532 myMainLayout->setRowStretch(12,0);
3533 for( int i=18; i<=27; i++)
3534 myMainLayout->itemAt(i)->widget()->setVisible( false );
3538 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3539 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3541 computeDoubleVolumesInfo();
3542 // over constrained volumes
3543 computeOverConstrainedVolumesInfo();
3544 // aspect Ratio 3D histogram
3545 computeAspectRatio3D();
3548 myButtons[7]->setEnabled( true );
3549 myButtons[8]->setEnabled( true );
3550 myButtons[9]->setEnabled( true );
3552 #ifdef DISABLE_PLOT2DVIEWER
3553 myMainLayout->setRowStretch(17,0);
3554 for( int i=35; i<=37; i++)
3555 myMainLayout->itemAt(i)->widget()->setVisible( false );
3559 myMainLayout->setRowStretch(17,0);
3560 for( int i=28; i<=37; i++)
3561 myMainLayout->itemAt(i)->widget()->setVisible( false );
3565 //================================================================================
3567 * \brief Computes and shows nb of elements satisfying a given predicate
3568 * \param [in] ft - a predicate type (SMESH::FunctorType)
3569 * \param [in] iBut - index of one of myButtons to disable
3570 * \param [in] iWdg - index of one of myWidgets to show the computed number
3572 //================================================================================
3574 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3576 myButtons[ iBut ]->setEnabled( false );
3577 myWidgets[ iWdg ]->setText( "" );
3578 if ( myObject->_is_nil() ) return;
3580 SUIT_OverrideCursor wc;
3582 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3583 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3586 this->showInfo( myObject ); // try to show all values
3587 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3588 return; // <ft> predicate already computed
3590 // look for a predicate of type <ft>
3591 for ( int i = 0; i < myPredicates.count(); ++i )
3592 if ( myPredicates[i]->GetFunctorType() == ft )
3594 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3595 myWidgets[ iWdg ]->setText( QString::number( nb ));
3599 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3601 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3604 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3606 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3609 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3611 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3614 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3616 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3619 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3621 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3624 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3626 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3629 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3631 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3634 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3636 myButtons[ 1 ]->setEnabled( false );
3637 myWidgets[ 2 ]->setText( "" );
3638 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3639 if ( mesh->_is_nil() ) return;
3640 if ( !mesh->IsLoaded() )
3643 this->showInfo( myObject ); // try to show all values
3644 if ( !myWidgets[ 2 ]->text().isEmpty() )
3645 return; // already computed
3647 myNodeConnFunctor->SetMesh( mesh );
3648 SMESH::Histogram_var histogram =
3649 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3651 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3654 void SMESHGUI_CtrlInfo::computeAspectRatio()
3656 #ifndef DISABLE_PLOT2DVIEWER
3657 myButtons[6]->setEnabled( false );
3659 if ( myObject->_is_nil() ) return;
3661 SUIT_OverrideCursor wc;
3663 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3664 if ( aHistogram && !aHistogram->isEmpty() ) {
3665 QwtPlotItem* anItem = aHistogram->createPlotItem();
3666 anItem->attach( myPlot );
3673 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3675 #ifndef DISABLE_PLOT2DVIEWER
3676 myButtons[9]->setEnabled( false );
3678 if ( myObject->_is_nil() ) return;
3680 SUIT_OverrideCursor wc;
3682 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3683 if ( aHistogram && !aHistogram->isEmpty() ) {
3684 QwtPlotItem* anItem = aHistogram->createPlotItem();
3685 anItem->attach( myPlot3D );
3693 \brief Internal clean-up (reset widget)
3695 void SMESHGUI_CtrlInfo::clearInternal()
3697 for( int i=0; i<=35; i++)
3698 myMainLayout->itemAt(i)->widget()->setVisible( true );
3699 for( int i=0; i<=9; i++)
3700 myButtons[i]->setEnabled( false );
3701 myPlot->detachItems();
3702 myPlot3D->detachItems();
3705 myWidgets[0]->setText( QString() );
3706 for ( int i = 1; i < myWidgets.count(); i++ )
3707 myWidgets[i]->setText( "" );
3708 myMainLayout->setRowStretch(11,5);
3709 myMainLayout->setRowStretch(16,5);
3712 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3714 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3715 myButtons[1]->setEnabled( true );
3716 myWidgets[2]->setText("");
3719 #ifndef DISABLE_PLOT2DVIEWER
3720 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3722 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3723 if ( mesh->_is_nil() ) return 0;
3724 if ( !mesh->IsLoaded() )
3726 aNumFun->SetMesh( mesh );
3728 CORBA::Long cprecision = 6;
3729 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3730 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3731 aNumFun->SetPrecision( cprecision );
3733 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3735 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3736 /*isLogarithmic=*/false,
3738 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3739 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3740 if ( &histogramVar.in() )
3742 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3743 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3744 if ( histogramVar->length() >= 2 )
3745 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3751 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3752 out << QString( 20, '-' ) << "\n";
3753 out << tr( "CTRL_INFO" ) << "\n";
3754 out << QString( 20, '-' ) << "\n";
3755 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3756 out << tr( "NODES_INFO" ) << "\n";
3757 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3758 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3759 out << tr( "EDGES_INFO" ) << "\n";
3760 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3761 out << tr( "FACES_INFO" ) << "\n";
3762 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3763 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3764 out << tr( "VOLUMES_INFO" ) << "\n";
3765 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3766 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3770 \class SMESHGUI_CtrlInfoDlg
3771 \brief Controls information dialog box
3776 \param parent parent widget
3778 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3781 setAttribute( Qt::WA_DeleteOnClose, true );
3782 setWindowTitle( tr( "CTRL_INFO" ) );
3783 setMinimumSize( 400, 600 );
3785 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3788 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3789 okBtn->setAutoDefault( true );
3790 okBtn->setDefault( true );
3792 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3793 dumpBtn->setAutoDefault( true );
3794 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3795 helpBtn->setAutoDefault( true );
3797 QHBoxLayout* btnLayout = new QHBoxLayout;
3798 btnLayout->setSpacing( SPACING );
3799 btnLayout->setMargin( 0 );
3801 btnLayout->addWidget( okBtn );
3802 btnLayout->addWidget( dumpBtn );
3803 btnLayout->addStretch( 10 );
3804 btnLayout->addWidget( helpBtn );
3806 QVBoxLayout* l = new QVBoxLayout ( this );
3807 l->setMargin( MARGIN );
3808 l->setSpacing( SPACING );
3809 l->addWidget( myCtrlInfo );
3810 l->addLayout( btnLayout );
3812 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3813 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3814 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3815 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3816 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3824 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3829 \brief Show controls information
3830 \param IO interactive object
3832 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3834 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3835 myCtrlInfo->showInfo( obj );
3839 \brief Perform clean-up actions on the dialog box closing.
3841 void SMESHGUI_CtrlInfoDlg::reject()
3843 SMESH::SetPointRepresentation( false );
3848 \brief Setup selection mode depending on the current dialog box state.
3850 void SMESHGUI_CtrlInfoDlg::updateSelection()
3852 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3853 disconnect( selMgr, 0, this, 0 );
3854 SMESH::SetPointRepresentation( false );
3855 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3860 \brief Show mesh information
3862 void SMESHGUI_CtrlInfoDlg::updateInfo()
3864 SUIT_OverrideCursor wc;
3866 SALOME_ListIO selected;
3867 SMESHGUI::selectionMgr()->selectedObjects( selected );
3869 if ( selected.Extent() == 1 ) {
3870 Handle(SALOME_InteractiveObject) IO = selected.First();
3876 \brief Activate dialog box
3878 void SMESHGUI_CtrlInfoDlg::activate()
3880 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3881 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3886 \brief Deactivate dialog box
3888 void SMESHGUI_CtrlInfoDlg::deactivate()
3890 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3894 * \brief Dump contents into a file
3896 void SMESHGUI_CtrlInfoDlg::dump()
3898 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3900 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3901 if ( !appStudy ) return;
3902 _PTR( Study ) aStudy = appStudy->studyDS();
3904 QStringList aFilters;
3905 aFilters.append( tr( "TEXT_FILES" ) );
3907 DumpFileDlg fd( this );
3908 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3909 fd.setNameFilters( aFilters );
3910 fd.myBaseChk->hide();
3911 fd.myElemChk->hide();
3912 fd.myAddChk ->hide();
3913 fd.myCtrlChk->hide();
3914 if ( fd.exec() == QDialog::Accepted )
3916 QString aFileName = fd.selectedFile();
3917 if ( !aFileName.isEmpty() ) {
3918 QFileInfo aFileInfo( aFileName );
3919 if ( aFileInfo.isDir() )
3922 QFile aFile( aFileName );
3923 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3926 QTextStream out( &aFile );
3927 myCtrlInfo->saveInfo( out );
3935 void SMESHGUI_CtrlInfoDlg::help()
3937 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");