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* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3229 QLabel* aNodesNbConn = createField();
3230 myWidgets << aNodesNbConn;
3231 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3233 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3234 QLabel* aNodesDouble = createField();
3235 myWidgets << aNodesDouble;
3236 myPredicates << aFilterMgr->CreateEqualNodes();
3237 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3238 myToleranceWidget = new SMESHGUI_SpinBox( this );
3239 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3240 myToleranceWidget->setAcceptNames( false );
3241 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3244 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3245 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3246 QLabel* anEdgesDouble = createField();
3247 myWidgets << anEdgesDouble;
3248 myPredicates << aFilterMgr->CreateEqualEdges();
3251 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3252 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3253 QLabel* aFacesDouble = createField();
3254 myWidgets << aFacesDouble;
3255 myPredicates << aFilterMgr->CreateEqualFaces();
3256 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3257 QLabel* aFacesOver = createField();
3258 myWidgets << aFacesOver;
3259 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3260 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3261 myPlot = createPlot( this );
3262 myAspectRatio = aFilterMgr->CreateAspectRatio();
3265 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3266 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3267 QLabel* aVolumesDouble = createField();
3268 myWidgets << aVolumesDouble;
3269 myPredicates << aFilterMgr->CreateEqualVolumes();
3270 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3271 QLabel* aVolumesOver = createField();
3272 myWidgets << aVolumesOver;
3273 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3274 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3275 myPlot3D = createPlot( this );
3276 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3278 QToolButton* aFreeNodesBtn = new QToolButton( this );
3279 aFreeNodesBtn->setIcon(aComputeIcon);
3280 myButtons << aFreeNodesBtn; //0
3282 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3283 aNodesNbConnBtn->setIcon(aComputeIcon);
3284 myButtons << aNodesNbConnBtn; //1
3286 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3287 aDoubleNodesBtn->setIcon(aComputeIcon);
3288 myButtons << aDoubleNodesBtn; //2
3290 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3291 aDoubleEdgesBtn->setIcon(aComputeIcon);
3292 myButtons << aDoubleEdgesBtn; //3
3294 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3295 aDoubleFacesBtn->setIcon(aComputeIcon);
3296 myButtons << aDoubleFacesBtn; //4
3298 QToolButton* aOverContFacesBtn = new QToolButton( this );
3299 aOverContFacesBtn->setIcon(aComputeIcon);
3300 myButtons << aOverContFacesBtn; //5
3302 QToolButton* aComputeFaceBtn = new QToolButton( this );
3303 aComputeFaceBtn->setIcon(aComputeIcon);
3304 myButtons << aComputeFaceBtn; //6
3306 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3307 aDoubleVolumesBtn->setIcon(aComputeIcon);
3308 myButtons << aDoubleVolumesBtn; //7
3310 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3311 aOverContVolumesBtn->setIcon(aComputeIcon);
3312 myButtons << aOverContVolumesBtn; //8
3314 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3315 aComputeVolumeBtn->setIcon(aComputeIcon);
3316 myButtons << aComputeVolumeBtn; //9
3318 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3319 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3320 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3321 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3322 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3323 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3324 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3325 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3326 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3327 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3328 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3330 setFontAttributes( aNameLab );
3331 setFontAttributes( aNodesLab );
3332 setFontAttributes( anEdgesLab );
3333 setFontAttributes( aFacesLab );
3334 setFontAttributes( aVolumesLab );
3336 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3337 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3338 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3339 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3340 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3341 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3342 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3343 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3344 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3345 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3346 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3347 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3348 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3349 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3350 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3351 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3352 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3353 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3354 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3355 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3356 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3357 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3358 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3359 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3360 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3361 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3362 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3363 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3364 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3365 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3366 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3367 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3368 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3369 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3370 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3371 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3372 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3373 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3375 myMainLayout->setColumnStretch( 0, 0 );
3376 myMainLayout->setColumnStretch( 1, 5 );
3377 myMainLayout->setRowStretch ( 11, 5 );
3378 myMainLayout->setRowStretch ( 16, 5 );
3379 myMainLayout->setRowStretch ( 17, 1 );
3387 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3391 \brief Change widget font attributes (bold, ...).
3393 \param attr font attributes (XORed flags)
3395 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3398 QFont f = w->font();
3405 \brief Create info field
3406 \return new info field
3408 QLabel* SMESHGUI_CtrlInfo::createField()
3410 QLabel* lab = new QLabel( this );
3411 lab->setFrameStyle( StyledPanel | Sunken );
3412 lab->setAlignment( Qt::AlignCenter );
3413 lab->setAutoFillBackground( true );
3414 QPalette pal = lab->palette();
3415 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3416 lab->setPalette( pal );
3417 lab->setMinimumWidth( 60 );
3422 \brief Create QwtPlot
3425 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3427 QwtPlot* aPlot = new QwtPlot( parent );
3428 aPlot->setMinimumSize( 100, 100 );
3429 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3430 xFont.setPointSize( 5 );
3431 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3432 yFont.setPointSize( 5 );
3433 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3434 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3440 \brief Show controls information on the selected object
3442 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3446 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3447 if ( myObject->_is_nil() ) return;
3449 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3450 myWidgets[0]->setText( aSO->GetName().c_str() );
3452 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3453 if ( mesh->_is_nil() ) return;
3455 const bool meshLoaded = mesh->IsLoaded();
3456 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3457 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3458 for ( int i = 0; i < myButtons.count(); ++i )
3459 myButtons[i]->setEnabled( true );
3461 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3462 if ( ! &nbElemsByType.in() ) return;
3464 const CORBA::Long ctrlLimit =
3465 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3468 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3469 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3470 nbElemsByType[ SMESH::FACE ] +
3471 nbElemsByType[ SMESH::VOLUME ] );
3472 if ( nbNodes + nbElems > 0 ) {
3473 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3475 computeFreeNodesInfo();
3476 computeNodesNbConnInfo();
3478 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3479 computeDoubleNodesInfo();
3482 myButtons[0]->setEnabled( true );
3483 myButtons[1]->setEnabled( true );
3484 myButtons[2]->setEnabled( true );
3488 for( int i=2; i<=11; i++)
3489 myMainLayout->itemAt(i)->widget()->setVisible( false );
3493 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3495 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3496 computeDoubleEdgesInfo();
3498 myButtons[3]->setEnabled( true );
3501 for( int i=11; i<=14; i++)
3502 myMainLayout->itemAt(i)->widget()->setVisible( false );
3506 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3507 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3509 computeDoubleFacesInfo();
3510 // over constrained faces
3511 computeOverConstrainedFacesInfo();
3512 // aspect Ratio histogram
3513 computeAspectRatio();
3516 myButtons[4]->setEnabled( true );
3517 myButtons[5]->setEnabled( true );
3518 myButtons[6]->setEnabled( true );
3520 #ifdef DISABLE_PLOT2DVIEWER
3521 myMainLayout->setRowStretch(12,0);
3522 for( int i=25; i<=27; i++)
3523 myMainLayout->itemAt(i)->widget()->setVisible( false );
3527 myMainLayout->setRowStretch(12,0);
3528 for( int i=18; i<=27; i++)
3529 myMainLayout->itemAt(i)->widget()->setVisible( false );
3533 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3534 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3536 computeDoubleVolumesInfo();
3537 // over constrained volumes
3538 computeOverConstrainedVolumesInfo();
3539 // aspect Ratio 3D histogram
3540 computeAspectRatio3D();
3543 myButtons[7]->setEnabled( true );
3544 myButtons[8]->setEnabled( true );
3545 myButtons[9]->setEnabled( true );
3547 #ifdef DISABLE_PLOT2DVIEWER
3548 myMainLayout->setRowStretch(17,0);
3549 for( int i=35; i<=37; i++)
3550 myMainLayout->itemAt(i)->widget()->setVisible( false );
3554 myMainLayout->setRowStretch(17,0);
3555 for( int i=28; i<=37; i++)
3556 myMainLayout->itemAt(i)->widget()->setVisible( false );
3560 //================================================================================
3562 * \brief Computes and shows nb of elements satisfying a given predicate
3563 * \param [in] ft - a predicate type (SMESH::FunctorType)
3564 * \param [in] iBut - index of one of myButtons to disable
3565 * \param [in] iWdg - index of one of myWidgets to show the computed number
3567 //================================================================================
3569 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3571 myButtons[ iBut ]->setEnabled( false );
3572 myWidgets[ iWdg ]->setText( "" );
3573 if ( myObject->_is_nil() ) return;
3575 SUIT_OverrideCursor wc;
3577 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3578 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3581 this->showInfo( myObject ); // try to show all values
3582 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3583 return; // <ft> predicate already computed
3585 // look for a predicate of type <ft>
3586 for ( int i = 0; i < myPredicates.count(); ++i )
3587 if ( myPredicates[i]->GetFunctorType() == ft )
3589 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3590 myWidgets[ iWdg ]->setText( QString::number( nb ));
3594 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3596 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3599 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3601 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3604 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3606 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3609 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3611 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3614 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3616 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3619 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3621 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3624 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3626 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3629 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3631 myButtons[ 1 ]->setEnabled( false );
3632 myWidgets[ 2 ]->setText( "" );
3633 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3634 if ( mesh->_is_nil() ) return;
3635 if ( !mesh->IsLoaded() )
3638 this->showInfo( myObject ); // try to show all values
3639 if ( !myWidgets[ 2 ]->text().isEmpty() )
3640 return; // already computed
3642 myNodeConnFunctor->SetMesh( mesh );
3643 SMESH::Histogram_var histogram =
3644 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3646 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3649 void SMESHGUI_CtrlInfo::computeAspectRatio()
3651 #ifndef DISABLE_PLOT2DVIEWER
3652 myButtons[6]->setEnabled( false );
3654 if ( myObject->_is_nil() ) return;
3656 SUIT_OverrideCursor wc;
3658 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3659 if ( aHistogram && !aHistogram->isEmpty() ) {
3660 QwtPlotItem* anItem = aHistogram->createPlotItem();
3661 anItem->attach( myPlot );
3668 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3670 #ifndef DISABLE_PLOT2DVIEWER
3671 myButtons[9]->setEnabled( false );
3673 if ( myObject->_is_nil() ) return;
3675 SUIT_OverrideCursor wc;
3677 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3678 if ( aHistogram && !aHistogram->isEmpty() ) {
3679 QwtPlotItem* anItem = aHistogram->createPlotItem();
3680 anItem->attach( myPlot3D );
3688 \brief Internal clean-up (reset widget)
3690 void SMESHGUI_CtrlInfo::clearInternal()
3692 for( int i=0; i<=35; i++)
3693 myMainLayout->itemAt(i)->widget()->setVisible( true );
3694 for( int i=0; i<=9; i++)
3695 myButtons[i]->setEnabled( false );
3696 myPlot->detachItems();
3697 myPlot3D->detachItems();
3700 myWidgets[0]->setText( QString() );
3701 for ( int i = 1; i < myWidgets.count(); i++ )
3702 myWidgets[i]->setText( "" );
3703 myMainLayout->setRowStretch(11,5);
3704 myMainLayout->setRowStretch(16,5);
3707 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3709 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3710 myButtons[1]->setEnabled( true );
3711 myWidgets[2]->setText("");
3714 #ifndef DISABLE_PLOT2DVIEWER
3715 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3717 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3718 if ( mesh->_is_nil() ) return 0;
3719 if ( !mesh->IsLoaded() )
3721 aNumFun->SetMesh( mesh );
3723 CORBA::Long cprecision = 6;
3724 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3725 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3726 aNumFun->SetPrecision( cprecision );
3728 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3730 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3731 /*isLogarithmic=*/false,
3733 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3734 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3735 if ( &histogramVar.in() )
3737 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3738 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3739 if ( histogramVar->length() >= 2 )
3740 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3746 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3747 out << QString( 20, '-' ) << "\n";
3748 out << tr( "CTRL_INFO" ) << "\n";
3749 out << QString( 20, '-' ) << "\n";
3750 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3751 out << tr( "NODES_INFO" ) << "\n";
3752 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3753 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3754 out << tr( "EDGES_INFO" ) << "\n";
3755 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3756 out << tr( "FACES_INFO" ) << "\n";
3757 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3758 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3759 out << tr( "VOLUMES_INFO" ) << "\n";
3760 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3761 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3765 \class SMESHGUI_CtrlInfoDlg
3766 \brief Controls information dialog box
3771 \param parent parent widget
3773 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3776 setAttribute( Qt::WA_DeleteOnClose, true );
3777 setWindowTitle( tr( "CTRL_INFO" ) );
3778 setMinimumSize( 400, 600 );
3780 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3783 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3784 okBtn->setAutoDefault( true );
3785 okBtn->setDefault( true );
3787 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3788 dumpBtn->setAutoDefault( true );
3789 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3790 helpBtn->setAutoDefault( true );
3792 QHBoxLayout* btnLayout = new QHBoxLayout;
3793 btnLayout->setSpacing( SPACING );
3794 btnLayout->setMargin( 0 );
3796 btnLayout->addWidget( okBtn );
3797 btnLayout->addWidget( dumpBtn );
3798 btnLayout->addStretch( 10 );
3799 btnLayout->addWidget( helpBtn );
3801 QVBoxLayout* l = new QVBoxLayout ( this );
3802 l->setMargin( MARGIN );
3803 l->setSpacing( SPACING );
3804 l->addWidget( myCtrlInfo );
3805 l->addLayout( btnLayout );
3807 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3808 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3809 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3810 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3811 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3819 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3824 \brief Show controls information
3825 \param IO interactive object
3827 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3829 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3830 myCtrlInfo->showInfo( obj );
3834 \brief Perform clean-up actions on the dialog box closing.
3836 void SMESHGUI_CtrlInfoDlg::reject()
3838 SMESH::SetPointRepresentation( false );
3843 \brief Setup selection mode depending on the current dialog box state.
3845 void SMESHGUI_CtrlInfoDlg::updateSelection()
3847 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3848 disconnect( selMgr, 0, this, 0 );
3849 SMESH::SetPointRepresentation( false );
3850 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3855 \brief Show mesh information
3857 void SMESHGUI_CtrlInfoDlg::updateInfo()
3859 SUIT_OverrideCursor wc;
3861 SALOME_ListIO selected;
3862 SMESHGUI::selectionMgr()->selectedObjects( selected );
3864 if ( selected.Extent() == 1 ) {
3865 Handle(SALOME_InteractiveObject) IO = selected.First();
3871 \brief Activate dialog box
3873 void SMESHGUI_CtrlInfoDlg::activate()
3875 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3876 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3881 \brief Deactivate dialog box
3883 void SMESHGUI_CtrlInfoDlg::deactivate()
3885 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3889 * \brief Dump contents into a file
3891 void SMESHGUI_CtrlInfoDlg::dump()
3893 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3895 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3896 if ( !appStudy ) return;
3897 _PTR( Study ) aStudy = appStudy->studyDS();
3899 QStringList aFilters;
3900 aFilters.append( tr( "TEXT_FILES" ) );
3902 DumpFileDlg fd( this );
3903 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3904 fd.setNameFilters( aFilters );
3905 fd.myBaseChk->hide();
3906 fd.myElemChk->hide();
3907 fd.myAddChk ->hide();
3908 fd.myCtrlChk->hide();
3909 if ( fd.exec() == QDialog::Accepted )
3911 QString aFileName = fd.selectedFile();
3912 if ( !aFileName.isEmpty() ) {
3913 QFileInfo aFileInfo( aFileName );
3914 if ( aFileInfo.isDir() )
3917 QFile aFile( aFileName );
3918 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3921 QTextStream out( &aFile );
3922 myCtrlInfo->saveInfo( out );
3930 void SMESHGUI_CtrlInfoDlg::help()
3932 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");