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 )
2922 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2923 if ( !CORBA::is_nil( obj ) ) {
2924 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2925 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2926 myCtrlInfo->showInfo( obj );
2928 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2929 SVTK_Selector* selector = SMESH::GetSelector();
2932 if ( myActor && selector ) {
2933 nb = myMode->checkedId() == NodeMode ?
2934 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2935 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2937 myElemInfo->setSource( myActor ) ;
2939 myID->setText( ID.trimmed() );
2941 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2942 foreach ( ID, idTxt )
2943 ids << ID.trimmed().toLong();
2944 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2948 myElemInfo->clear();
2954 \brief Perform clean-up actions on the dialog box closing.
2956 void SMESHGUI_MeshInfoDlg::reject()
2958 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2959 selMgr->clearFilters();
2960 SMESH::SetPointRepresentation( false );
2961 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2962 aViewWindow->SetSelectionMode( ActorSelection );
2967 \brief Process keyboard event
2968 \param e key press event
2970 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2972 QDialog::keyPressEvent( e );
2973 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2980 \brief Reactivate dialog box, when mouse pointer goes into it.
2982 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2988 \brief Setup selection mode depending on the current dialog box state.
2990 void SMESHGUI_MeshInfoDlg::updateSelection()
2992 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2994 disconnect( selMgr, 0, this, 0 );
2995 selMgr->clearFilters();
2997 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2998 SMESH::SetPointRepresentation( false );
2999 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3000 aViewWindow->SetSelectionMode( ActorSelection );
3003 if ( myMode->checkedId() == NodeMode ) {
3004 SMESH::SetPointRepresentation( true );
3005 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3006 aViewWindow->SetSelectionMode( NodeSelection );
3009 SMESH::SetPointRepresentation( false );
3010 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3011 aViewWindow->SetSelectionMode( CellSelection );
3015 QString oldID = myID->text().trimmed();
3016 SMESH_Actor* oldActor = myActor;
3019 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3022 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3023 myID->setText( oldID );
3029 \brief Show help page
3031 void SMESHGUI_MeshInfoDlg::help()
3033 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3034 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3035 "mesh_infos_page.html#mesh_element_info_anchor" );
3039 \brief Show mesh information
3041 void SMESHGUI_MeshInfoDlg::updateInfo()
3043 SUIT_OverrideCursor wc;
3045 SALOME_ListIO selected;
3046 SMESHGUI::selectionMgr()->selectedObjects( selected );
3048 if ( selected.Extent() == 1 ) {
3049 Handle(SALOME_InteractiveObject) IO = selected.First();
3053 // myBaseInfo->clear();
3054 // myElemInfo->clear();
3055 // myAddInfo->clear();
3060 \brief Activate dialog box
3062 void SMESHGUI_MeshInfoDlg::activate()
3064 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3065 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3066 myTabWidget->setEnabled( true );
3071 \brief Deactivate dialog box
3073 void SMESHGUI_MeshInfoDlg::deactivate()
3075 myTabWidget->setEnabled( false );
3076 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3080 \brief Called when users switches between node / element modes.
3082 void SMESHGUI_MeshInfoDlg::modeChanged()
3089 \brief Caled when users prints mesh element ID in the corresponding field.
3091 void SMESHGUI_MeshInfoDlg::idChanged()
3093 SVTK_Selector* selector = SMESH::GetSelector();
3094 if ( myActor && selector ) {
3095 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3096 TColStd_MapOfInteger ID;
3098 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3099 foreach ( QString tid, idTxt ) {
3100 long id = tid.trimmed().toLong();
3101 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3102 myActor->GetObject()->GetMesh()->FindElement( id ) :
3103 myActor->GetObject()->GetMesh()->FindNode( id );
3109 selector->AddOrRemoveIndex( IO, ID, false );
3110 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3111 aViewWindow->highlight( IO, true, true );
3112 aViewWindow->Repaint();
3114 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3118 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3120 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3121 myMode->button( NodeMode )->click();
3122 myID->setText( QString::number( id ) );
3126 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3128 if ( !theStr.isEmpty() ) {
3129 myMode->button( ElemMode )->click();
3130 myID->setText( theStr );
3134 void SMESHGUI_MeshInfoDlg::dump()
3136 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3138 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3139 if ( !appStudy ) return;
3140 _PTR( Study ) aStudy = appStudy->studyDS();
3142 QStringList aFilters;
3143 aFilters.append( tr( "TEXT_FILES" ) );
3145 bool anIsBase = true;
3146 bool anIsElem = true;
3147 bool anIsAdd = true;
3148 bool anIsCtrl = true;
3150 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3151 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3152 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3153 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3154 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3157 DumpFileDlg fd( this );
3158 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3159 fd.setNameFilters( aFilters );
3160 fd.myBaseChk->setChecked( anIsBase );
3161 fd.myElemChk->setChecked( anIsElem );
3162 fd.myAddChk ->setChecked( anIsAdd );
3163 fd.myCtrlChk->setChecked( anIsCtrl );
3164 if ( fd.exec() == QDialog::Accepted )
3166 QString aFileName = fd.selectedFile();
3168 bool toBase = fd.myBaseChk->isChecked();
3169 bool toElem = fd.myElemChk->isChecked();
3170 bool toAdd = fd.myAddChk->isChecked();
3171 bool toCtrl = fd.myCtrlChk->isChecked();
3173 if ( !aFileName.isEmpty() ) {
3174 QFileInfo aFileInfo( aFileName );
3175 if ( aFileInfo.isDir() )
3178 QFile aFile( aFileName );
3179 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3182 QTextStream out( &aFile );
3184 if ( toBase ) myBaseInfo->saveInfo( out );
3185 if ( toElem ) myElemInfo->saveInfo( out );
3186 if ( toAdd ) myAddInfo ->saveInfo( out );
3187 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3193 \class SMESHGUI_CtrlInfo
3194 \brief Class for the mesh controls information widget.
3199 \param parent parent widget
3201 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3202 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3204 setFrameStyle( StyledPanel | Sunken );
3206 myMainLayout = new QGridLayout( this );
3207 myMainLayout->setMargin( MARGIN );
3208 myMainLayout->setSpacing( SPACING );
3211 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3212 QLabel* aName = createField();
3213 aName->setMinimumWidth( 150 );
3216 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3217 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3219 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3222 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3223 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3224 QLabel* aNodesFree = createField();
3225 myWidgets << aNodesFree;
3226 myPredicates << aFilterMgr->CreateFreeNodes();
3228 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3229 QLabel* aNodesDouble = createField();
3230 myWidgets << aNodesDouble;
3231 myPredicates << aFilterMgr->CreateEqualNodes();
3232 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3233 myToleranceWidget = new SMESHGUI_SpinBox( this );
3234 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3235 myToleranceWidget->setAcceptNames( false );
3236 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3239 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3240 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3241 QLabel* anEdgesDouble = createField();
3242 myWidgets << anEdgesDouble;
3243 myPredicates << aFilterMgr->CreateEqualEdges();
3246 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3247 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3248 QLabel* aFacesDouble = createField();
3249 myWidgets << aFacesDouble;
3250 myPredicates << aFilterMgr->CreateEqualFaces();
3251 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3252 QLabel* aFacesOver = createField();
3253 myWidgets << aFacesOver;
3254 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3255 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3256 myPlot = createPlot( this );
3257 myAspectRatio = aFilterMgr->CreateAspectRatio();
3260 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3261 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3262 QLabel* aVolumesDouble = createField();
3263 myWidgets << aVolumesDouble;
3264 myPredicates << aFilterMgr->CreateEqualVolumes();
3265 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3266 QLabel* aVolumesOver = createField();
3267 myWidgets << aVolumesOver;
3268 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3269 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3270 myPlot3D = createPlot( this );
3271 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3273 QToolButton* aFreeNodesBtn = new QToolButton( this );
3274 aFreeNodesBtn->setIcon(aComputeIcon);
3275 myButtons << aFreeNodesBtn; //0
3277 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3278 aDoubleNodesBtn->setIcon(aComputeIcon);
3279 myButtons << aDoubleNodesBtn; //1
3281 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3282 aDoubleEdgesBtn->setIcon(aComputeIcon);
3283 myButtons << aDoubleEdgesBtn; //2
3285 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3286 aDoubleFacesBtn->setIcon(aComputeIcon);
3287 myButtons << aDoubleFacesBtn; //3
3289 QToolButton* aOverContFacesBtn = new QToolButton( this );
3290 aOverContFacesBtn->setIcon(aComputeIcon);
3291 myButtons << aOverContFacesBtn; //4
3293 QToolButton* aComputeFaceBtn = new QToolButton( this );
3294 aComputeFaceBtn->setIcon(aComputeIcon);
3295 myButtons << aComputeFaceBtn; //5
3297 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3298 aDoubleVolumesBtn->setIcon(aComputeIcon);
3299 myButtons << aDoubleVolumesBtn; //6
3301 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3302 aOverContVolumesBtn->setIcon(aComputeIcon);
3303 myButtons << aOverContVolumesBtn; //7
3305 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3306 aComputeVolumeBtn->setIcon(aComputeIcon);
3307 myButtons << aComputeVolumeBtn; //8
3309 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3310 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3311 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3312 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3313 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3314 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3315 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3316 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3317 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3318 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3320 setFontAttributes( aNameLab );
3321 setFontAttributes( aNodesLab );
3322 setFontAttributes( anEdgesLab );
3323 setFontAttributes( aFacesLab );
3324 setFontAttributes( aVolumesLab );
3326 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3327 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3328 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3329 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3330 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3331 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3332 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3333 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3334 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3335 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3336 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3337 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3338 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3339 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3340 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3341 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3342 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3343 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3344 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3345 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3346 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3347 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3348 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3349 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3350 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3351 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3352 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3353 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3354 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3355 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3356 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3357 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3358 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3359 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3360 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3362 myMainLayout->setColumnStretch( 0, 0 );
3363 myMainLayout->setColumnStretch( 1, 5 );
3364 myMainLayout->setRowStretch ( 11, 5 );
3365 myMainLayout->setRowStretch ( 16, 5 );
3366 myMainLayout->setRowStretch ( 17, 1 );
3374 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3378 \brief Change widget font attributes (bold, ...).
3380 \param attr font attributes (XORed flags)
3382 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3385 QFont f = w->font();
3392 \brief Create info field
3393 \return new info field
3395 QLabel* SMESHGUI_CtrlInfo::createField()
3397 QLabel* lab = new QLabel( this );
3398 lab->setFrameStyle( StyledPanel | Sunken );
3399 lab->setAlignment( Qt::AlignCenter );
3400 lab->setAutoFillBackground( true );
3401 QPalette pal = lab->palette();
3402 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3403 lab->setPalette( pal );
3404 lab->setMinimumWidth( 60 );
3409 \brief Create QwtPlot
3412 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3414 QwtPlot* aPlot = new QwtPlot( parent );
3415 aPlot->setMinimumSize( 100, 100 );
3416 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3417 xFont.setPointSize( 5 );
3418 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3419 yFont.setPointSize( 5 );
3420 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3421 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3427 \brief Show controls information on the selected object
3429 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3433 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3434 if ( myObject->_is_nil() ) return;
3436 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3437 myWidgets[0]->setText( aSO->GetName().c_str() );
3439 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3440 if ( mesh->_is_nil() ) return;
3442 const bool meshLoaded = mesh->IsLoaded();
3443 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3444 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3445 for ( int i = 0; i < myButtons.count(); ++i )
3446 myButtons[i]->setEnabled( true );
3448 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3449 if ( ! &nbElemsByType.in() ) return;
3451 const CORBA::Long ctrlLimit =
3452 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3455 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3456 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3457 nbElemsByType[ SMESH::FACE ] +
3458 nbElemsByType[ SMESH::VOLUME ] );
3459 if ( nbNodes + nbElems > 0 ) {
3460 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3462 computeFreeNodesInfo();
3464 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3465 computeDoubleNodesInfo();
3468 myButtons[0]->setEnabled( true );
3469 myButtons[1]->setEnabled( true );
3473 for( int i=2; i<=10; i++)
3474 myMainLayout->itemAt(i)->widget()->setVisible( false );
3478 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3480 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3481 computeDoubleEdgesInfo();
3483 myButtons[2]->setEnabled( true );
3486 for( int i=11; i<=14; i++)
3487 myMainLayout->itemAt(i)->widget()->setVisible( false );
3491 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3492 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3494 computeDoubleFacesInfo();
3495 // over constrained faces
3496 computeOverConstrainedFacesInfo();
3497 // aspect Ratio histogram
3498 computeAspectRatio();
3501 myButtons[3]->setEnabled( true );
3502 myButtons[4]->setEnabled( true );
3503 myButtons[5]->setEnabled( true );
3505 #ifdef DISABLE_PLOT2DVIEWER
3506 myMainLayout->setRowStretch(11,0);
3507 for( int i=22; i<=24; i++)
3508 myMainLayout->itemAt(i)->widget()->setVisible( false );
3512 myMainLayout->setRowStretch(11,0);
3513 for( int i=15; i<=24; i++)
3514 myMainLayout->itemAt(i)->widget()->setVisible( false );
3518 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3519 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3521 computeDoubleVolumesInfo();
3522 // over constrained volumes
3523 computeOverConstrainedVolumesInfo();
3524 // aspect Ratio 3D histogram
3525 computeAspectRatio3D();
3528 myButtons[6]->setEnabled( true );
3529 myButtons[7]->setEnabled( true );
3530 myButtons[8]->setEnabled( true );
3532 #ifdef DISABLE_PLOT2DVIEWER
3533 myMainLayout->setRowStretch(16,0);
3534 for( int i=32; i<=34; i++)
3535 myMainLayout->itemAt(i)->widget()->setVisible( false );
3539 myMainLayout->setRowStretch(16,0);
3540 for( int i=25; i<=34; i++)
3541 myMainLayout->itemAt(i)->widget()->setVisible( false );
3545 //================================================================================
3547 * \brief Computes and shows nb of elements satisfying a given predicate
3548 * \param [in] ft - a predicate type (SMESH::FunctorType)
3549 * \param [in] iBut - index of one of myButtons to disable
3550 * \param [in] iWdg - index of one of myWidgets to show the computed number
3552 //================================================================================
3554 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3556 myButtons[ iBut ]->setEnabled( false );
3557 myWidgets[ iWdg ]->setText( "" );
3558 if ( myObject->_is_nil() ) return;
3560 SUIT_OverrideCursor wc;
3562 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3563 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3566 this->showInfo( myObject ); // try to show all values
3567 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3568 return; // <ft> predicate already computed
3570 // look for a predicate of type <ft>
3571 for ( int i = 0; i < myPredicates.count(); ++i )
3572 if ( myPredicates[i]->GetFunctorType() == ft )
3574 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3575 myWidgets[ iWdg ]->setText( QString::number( nb ));
3579 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3581 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3584 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3586 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3589 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3591 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3594 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3596 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3599 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3601 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3604 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3606 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3609 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3611 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3614 void SMESHGUI_CtrlInfo::computeAspectRatio()
3616 #ifndef DISABLE_PLOT2DVIEWER
3617 myButtons[5]->setEnabled( false );
3619 if ( myObject->_is_nil() ) return;
3621 SUIT_OverrideCursor wc;
3623 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3624 if ( aHistogram && !aHistogram->isEmpty() ) {
3625 QwtPlotItem* anItem = aHistogram->createPlotItem();
3626 anItem->attach( myPlot );
3633 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3635 #ifndef DISABLE_PLOT2DVIEWER
3636 myButtons[8]->setEnabled( false );
3638 if ( myObject->_is_nil() ) return;
3640 SUIT_OverrideCursor wc;
3642 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3643 if ( aHistogram && !aHistogram->isEmpty() ) {
3644 QwtPlotItem* anItem = aHistogram->createPlotItem();
3645 anItem->attach( myPlot3D );
3653 \brief Internal clean-up (reset widget)
3655 void SMESHGUI_CtrlInfo::clearInternal()
3657 for( int i=0; i<=34; i++)
3658 myMainLayout->itemAt(i)->widget()->setVisible( true );
3659 for( int i=0; i<=8; i++)
3660 myButtons[i]->setEnabled( false );
3661 myPlot->detachItems();
3662 myPlot3D->detachItems();
3665 myWidgets[0]->setText( QString() );
3666 for ( int i = 1; i < myWidgets.count(); i++ )
3667 myWidgets[i]->setText( "" );
3668 myMainLayout->setRowStretch(11,5);
3669 myMainLayout->setRowStretch(16,5);
3672 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3674 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3675 myButtons[1]->setEnabled( true );
3676 myWidgets[2]->setText("");
3679 #ifndef DISABLE_PLOT2DVIEWER
3680 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3682 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3683 if ( mesh->_is_nil() ) return 0;
3684 if ( !mesh->IsLoaded() )
3686 aNumFun->SetMesh( mesh );
3688 CORBA::Long cprecision = 6;
3689 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3690 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3691 aNumFun->SetPrecision( cprecision );
3693 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3695 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3696 /*isLogarithmic=*/false,
3698 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3699 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3700 if ( &histogramVar.in() )
3702 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3703 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3704 if ( histogramVar->length() >= 2 )
3705 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3711 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3712 out << QString( 20, '-' ) << "\n";
3713 out << tr( "CTRL_INFO" ) << "\n";
3714 out << QString( 20, '-' ) << "\n";
3715 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3716 out << tr( "NODES_INFO" ) << "\n";
3717 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3718 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3719 out << tr( "EDGES_INFO" ) << "\n";
3720 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3721 out << tr( "FACES_INFO" ) << "\n";
3722 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3723 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3724 out << tr( "VOLUMES_INFO" ) << "\n";
3725 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3726 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3730 \class SMESHGUI_CtrlInfoDlg
3731 \brief Controls information dialog box
3736 \param parent parent widget
3737 \param page specifies the dialog page to be shown at the start-up
3739 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3742 setAttribute( Qt::WA_DeleteOnClose, true );
3743 setWindowTitle( tr( "CTRL_INFO" ) );
3744 setMinimumSize( 400, 600 );
3746 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3749 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3750 okBtn->setAutoDefault( true );
3751 okBtn->setDefault( true );
3753 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3754 dumpBtn->setAutoDefault( true );
3755 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3756 helpBtn->setAutoDefault( true );
3758 QHBoxLayout* btnLayout = new QHBoxLayout;
3759 btnLayout->setSpacing( SPACING );
3760 btnLayout->setMargin( 0 );
3762 btnLayout->addWidget( okBtn );
3763 btnLayout->addWidget( dumpBtn );
3764 btnLayout->addStretch( 10 );
3765 btnLayout->addWidget( helpBtn );
3767 QVBoxLayout* l = new QVBoxLayout ( this );
3768 l->setMargin( MARGIN );
3769 l->setSpacing( SPACING );
3770 l->addWidget( myCtrlInfo );
3771 l->addLayout( btnLayout );
3773 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3774 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3775 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3776 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3777 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3785 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3790 \brief Show controls information
3791 \param IO interactive object
3793 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3795 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3796 myCtrlInfo->showInfo( obj );
3800 \brief Perform clean-up actions on the dialog box closing.
3802 void SMESHGUI_CtrlInfoDlg::reject()
3804 SMESH::SetPointRepresentation( false );
3809 \brief Setup selection mode depending on the current dialog box state.
3811 void SMESHGUI_CtrlInfoDlg::updateSelection()
3813 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3814 disconnect( selMgr, 0, this, 0 );
3815 SMESH::SetPointRepresentation( false );
3816 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3821 \brief Show mesh information
3823 void SMESHGUI_CtrlInfoDlg::updateInfo()
3825 SUIT_OverrideCursor wc;
3827 SALOME_ListIO selected;
3828 SMESHGUI::selectionMgr()->selectedObjects( selected );
3830 if ( selected.Extent() == 1 ) {
3831 Handle(SALOME_InteractiveObject) IO = selected.First();
3837 \brief Activate dialog box
3839 void SMESHGUI_CtrlInfoDlg::activate()
3841 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3842 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3847 \brief Deactivate dialog box
3849 void SMESHGUI_CtrlInfoDlg::deactivate()
3851 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3855 * \brief Dump contents into a file
3857 void SMESHGUI_CtrlInfoDlg::dump()
3859 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3861 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3862 if ( !appStudy ) return;
3863 _PTR( Study ) aStudy = appStudy->studyDS();
3865 QStringList aFilters;
3866 aFilters.append( tr( "TEXT_FILES" ) );
3868 DumpFileDlg fd( this );
3869 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3870 fd.setNameFilters( aFilters );
3871 fd.myBaseChk->hide();
3872 fd.myElemChk->hide();
3873 fd.myAddChk ->hide();
3874 fd.myCtrlChk->hide();
3875 if ( fd.exec() == QDialog::Accepted )
3877 QString aFileName = fd.selectedFile();
3878 if ( !aFileName.isEmpty() ) {
3879 QFileInfo aFileInfo( aFileName );
3880 if ( aFileInfo.isDir() )
3883 QFile aFile( aFileName );
3884 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3887 QTextStream out( &aFile );
3888 myCtrlInfo->saveInfo( out );
3896 void SMESHGUI_CtrlInfoDlg::help()
3898 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");