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_IdPreview.h"
37 #include "SMESHGUI_IdValidator.h"
38 #include "SMESHGUI_SpinBox.h"
39 #include "SMESHGUI_Utils.h"
40 #include "SMESHGUI_VTKUtils.h"
41 #include "SMESH_Actor.h"
43 #include <LightApp_SelectionMgr.h>
44 #include <SUIT_FileDlg.h>
45 #include <SUIT_OverrideCursor.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_Session.h>
48 #include <SVTK_ViewWindow.h>
50 #include <SALOMEDSClient_Study.hxx>
51 #include <SalomeApp_Study.h>
53 #include <QApplication>
54 #include <QButtonGroup>
56 #include <QContextMenuEvent>
57 #include <QGridLayout>
58 #include <QHBoxLayout>
59 #include <QHeaderView>
60 #include <QItemDelegate>
65 #include <QPushButton>
66 #include <QToolButton>
67 #include <QRadioButton>
68 #include <QTextStream>
70 #include <QTextBrowser>
71 #include <QVBoxLayout>
73 #include "utilities.h"
75 #include <SALOMEconfig.h>
76 #include CORBA_SERVER_HEADER(GEOM_Gen)
80 const int SPACING = 6;
82 const int MAXITEMS = 10;
83 const int GROUPS_ID = 100;
84 const int SUBMESHES_ID = 200;
85 const int SPACING_INFO = 2;
87 const char* id_preview_resource = "id_preview_resource";
90 TypeRole = Qt::UserRole + 10,
95 NodeConnectivity = 100,
104 class ExtraWidget : public QWidget
107 ExtraWidget( QWidget*, bool = false );
110 void updateControls( int, int, int = MAXITEMS );
119 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
121 current = new QLabel( this );
122 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
123 prev = new QPushButton( tr( "<<" ), this );
124 next = new QPushButton( tr( ">>" ), this );
125 QHBoxLayout* hbl = new QHBoxLayout( this );
126 hbl->setContentsMargins( 0, SPACING, 0, 0 );
127 hbl->setSpacing( SPACING );
129 hbl->addWidget( current );
130 hbl->addWidget( prev );
131 hbl->addWidget( next );
134 ExtraWidget::~ExtraWidget()
138 void ExtraWidget::updateControls( int total, int index, int blockSize )
140 setVisible( total > blockSize );
141 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
142 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total )).arg( total ));
143 prev->setEnabled( index > 0 );
144 next->setEnabled( (index+1)*blockSize < total );
149 \brief Customization of standard "Save file" dialog box for dump info operation
153 class DumpFileDlg : public SUIT_FileDlg
156 DumpFileDlg( QWidget* parent );
158 QCheckBox* myBaseChk;
159 QCheckBox* myElemChk;
161 QCheckBox* myCtrlChk;
168 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
170 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
172 QWidget* hB = new QWidget( this );
173 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
174 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
175 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
176 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
178 QGridLayout* layout = new QGridLayout( hB );
179 layout->addWidget( myBaseChk, 0, 0 );
180 layout->addWidget( myElemChk, 0, 1 );
181 layout->addWidget( myAddChk, 1, 0 );
182 layout->addWidget( myCtrlChk, 1, 1 );
184 QPushButton* pb = new QPushButton( this );
186 int row = grid->rowCount();
187 grid->addWidget( new QLabel( "", this ), row, 0 );
188 grid->addWidget( hB, row, 1, 1, 3 );
189 grid->addWidget( pb, row, 5 );
196 \brief Get depth of the tree item
198 \param theItem tree widget item
199 \return item's depth in tree widget (where top-level items have zero depth)
201 static int itemDepth( QTreeWidgetItem* item )
204 QTreeWidgetItem* p = item->parent();
213 \class SMESHGUI_MeshInfo
214 \brief Base mesh information widget
216 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
221 \param parent parent widget
223 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
224 : QFrame( parent ), myWidgets( iElementsEnd )
226 setFrameStyle( StyledPanel | Sunken );
228 QGridLayout* l = new QGridLayout( this );
229 l->setMargin( MARGIN );
230 l->setSpacing( SPACING );
235 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
236 QLabel* aName = createField();
237 aName->setObjectName("meshName");
238 aName->setMinimumWidth( 150 );
239 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
240 QLabel* aObj = createField();
241 aObj->setObjectName("meshType");
242 aObj->setMinimumWidth( 150 );
243 myWidgets[ index++ ] << aNameLab << aName;
244 myWidgets[ index++ ] << aObjLab << aObj;
247 QWidget* aNodesLine = createLine();
248 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
249 QLabel* aNodes = createField();
250 aNodes->setObjectName("nbNodes");
251 myWidgets[ index++ ] << aNodesLine;
252 myWidgets[ index++ ] << aNodesLab << aNodes;
255 QWidget* aElemLine = createLine();
256 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
257 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
258 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
259 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
260 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
261 myWidgets[ index++ ] << aElemLine;
262 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
264 // ... Number elements
265 QWidget* aNbLine = createLine();
266 QLabel* aNbTotal = createField();
267 aNbTotal->setObjectName("totalNbElems");
268 QLabel* aNbLin = createField();
269 aNbLin->setObjectName("totalNbLinearElems");
270 QLabel* aNbQuad = createField();
271 aNbQuad->setObjectName("totalNbQuadraticElems");
272 QLabel* aNbBiQuad = createField();
273 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
274 myWidgets[ index++ ] << aNbLine;
275 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
278 QWidget* a0DLine = createLine();
279 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
280 QLabel* a0DTotal = createField();
281 a0DTotal->setObjectName("nb0D");
283 myWidgets[ index++ ] << a0DLine;
284 myWidgets[ index++ ] << a0DLab << a0DTotal;
287 QWidget* aBallLine = createLine();
288 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
289 QLabel* aBallTotal = createField();
290 aBallTotal->setObjectName("nbBall");
291 myWidgets[ index++ ] << aBallLine;
292 myWidgets[ index++ ] << aBallLab << aBallTotal;
295 QWidget* a1DLine = createLine();
296 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
297 QLabel* a1DTotal = createField();
298 a1DTotal->setObjectName("nb1D");
299 QLabel* a1DLin = createField();
300 a1DLin->setObjectName("nbLinear1D");
301 QLabel* a1DQuad = createField();
302 a1DQuad->setObjectName("nbQuadratic1D");
303 myWidgets[ index++ ] << a1DLine;
304 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
307 QWidget* a2DLine = createLine();
308 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
309 QLabel* a2DTotal = createField();
310 a2DTotal->setObjectName("nb2D");
311 QLabel* a2DLin = createField();
312 a2DLin->setObjectName("nbLinear2D");
313 QLabel* a2DQuad = createField();
314 a2DQuad->setObjectName("nbQuadratic2D");
315 QLabel* a2DBiQuad = createField();
316 a2DBiQuad->setObjectName("nbBiQuadratic2D");
317 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
318 QLabel* a2DTriTotal = createField();
319 a2DTriTotal->setObjectName("nbTriangle");
320 QLabel* a2DTriLin = createField();
321 a2DTriLin->setObjectName("nbLinearTriangle");
322 QLabel* a2DTriQuad = createField();
323 a2DTriQuad->setObjectName("nbQuadraticTriangle");
324 QLabel* a2DTriBiQuad = createField();
325 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
326 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
327 QLabel* a2DQuaTotal = createField();
328 a2DQuaTotal->setObjectName("nbQuadrangle");
329 QLabel* a2DQuaLin = createField();
330 a2DQuaLin->setObjectName("nbLinearQuadrangle");
331 QLabel* a2DQuaQuad = createField();
332 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
333 QLabel* a2DQuaBiQuad = createField();
334 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
335 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
336 QLabel* a2DPolTotal = createField();
337 a2DPolTotal->setObjectName("nbPolygon");
338 QLabel* a2DPolLin = createField();
339 a2DPolLin->setObjectName("nbLinearPolygon");
340 QLabel* a2DPolQuad = createField();
341 a2DPolQuad->setObjectName("nbQuadraticPolygon");
342 myWidgets[ index++ ] << a2DLine;
343 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
344 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
345 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
346 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
349 QWidget* a3DLine = createLine();
350 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
351 QLabel* a3DTotal = createField();
352 a3DTotal->setObjectName("nb3D");
353 QLabel* a3DLin = createField();
354 a3DLin->setObjectName("nbLinear3D");
355 QLabel* a3DQuad = createField();
356 a3DQuad->setObjectName("nbQuadratic3D");
357 QLabel* a3DBiQuad = createField();
358 a3DBiQuad->setObjectName("nbBiQuadratic3D");
359 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
360 QLabel* a3DTetTotal = createField();
361 a3DTetTotal->setObjectName("nbTetrahedron");
362 QLabel* a3DTetLin = createField();
363 a3DTetLin->setObjectName("nbLinearTetrahedron");
364 QLabel* a3DTetQuad = createField();
365 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
366 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
367 QLabel* a3DHexTotal = createField();
368 a3DHexTotal->setObjectName("nbHexahedron");
369 QLabel* a3DHexLin = createField();
370 a3DHexLin->setObjectName("nbLinearHexahedron");
371 QLabel* a3DHexQuad = createField();
372 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
373 QLabel* a3DHexBiQuad = createField();
374 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
375 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
376 QLabel* a3DPyrTotal = createField();
377 a3DPyrTotal->setObjectName("nbPyramid");
378 QLabel* a3DPyrLin = createField();
379 a3DPyrLin->setObjectName("nbLinearPyramid");
380 QLabel* a3DPyrQuad = createField();
381 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
382 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
383 QLabel* a3DPriTotal = createField();
384 a3DPriTotal->setObjectName("nbPrism");
385 QLabel* a3DPriLin = createField();
386 a3DPriLin->setObjectName("nbLinearPrism");
387 QLabel* a3DPriQuad = createField();
388 a3DPriQuad->setObjectName("nbQuadraticPrism");
389 QLabel* a3DPriBiQuad = createField();
390 a3DPriBiQuad->setObjectName("nbBiQuadraticPrism");
391 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
392 QLabel* a3DHexPriTotal = createField();
393 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
394 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
395 QLabel* a3DPolTotal = createField();
396 a3DPolTotal->setObjectName("nbPolyhedron");
397 myWidgets[ index++ ] << a3DLine;
398 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
399 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
400 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
401 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
402 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad;
403 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
404 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
406 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
407 myLoadBtn->setAutoDefault( true );
408 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ));
410 setFontAttributes( aNameLab, Bold );
411 setFontAttributes( aObjLab, Bold );
412 setFontAttributes( aNodesLab, Bold );
413 setFontAttributes( aElemLab, Bold );
414 setFontAttributes( aElemTotal, Italic );
415 setFontAttributes( aElemLin, Italic );
416 setFontAttributes( aElemQuad, Italic );
417 setFontAttributes( aElemBiQuad, Italic );
418 setFontAttributes( a0DLab, Bold );
419 setFontAttributes( aBallLab, Bold );
420 setFontAttributes( a1DLab, Bold );
421 setFontAttributes( a2DLab, Bold );
422 setFontAttributes( a3DLab, Bold );
424 l->addWidget( aNameLab, 0, 0 );
425 l->addWidget( aName, 0, 1, 1, 4 );
426 l->addWidget( aObjLab, 1, 0 );
427 l->addWidget( aObj, 1, 1, 1, 4 );
428 l->addWidget( aNodesLine, 2, 0, 1, 5 );
429 l->addWidget( aNodesLab, 3, 0 );
430 l->addWidget( aNodes, 3, 1 );
431 l->addWidget( aElemLine, 4, 0, 1, 5 );
432 l->addWidget( aElemLab, 5, 0 );
433 l->addWidget( aElemTotal, 5, 1 );
434 l->addWidget( aElemLin, 5, 2 );
435 l->addWidget( aElemQuad, 5, 3 );
436 l->addWidget( aElemBiQuad, 5, 4 );
437 l->addWidget( aNbLine, 6, 1, 1, 4 );
438 l->addWidget( aNbTotal, 7, 1 );
439 l->addWidget( aNbLin, 7, 2 );
440 l->addWidget( aNbQuad, 7, 3 );
441 l->addWidget( aNbBiQuad, 7, 4 );
442 l->addWidget( a0DLine, 8, 1, 1, 4 );
443 l->addWidget( a0DLab, 9, 0 );
444 l->addWidget( a0DTotal, 9, 1 );
445 l->addWidget( aBallLine, 10, 1, 1, 4 );
446 l->addWidget( aBallLab, 11, 0 );
447 l->addWidget( aBallTotal, 11, 1 );
448 l->addWidget( a1DLine, 12, 1, 1, 4 );
449 l->addWidget( a1DLab, 13, 0 );
450 l->addWidget( a1DTotal, 13, 1 );
451 l->addWidget( a1DLin, 13, 2 );
452 l->addWidget( a1DQuad, 13, 3 );
453 l->addWidget( a2DLine, 14, 1, 1, 4 );
454 l->addWidget( a2DLab, 15, 0 );
455 l->addWidget( a2DTotal, 15, 1 );
456 l->addWidget( a2DLin, 15, 2 );
457 l->addWidget( a2DQuad, 15, 3 );
458 l->addWidget( a2DBiQuad, 15, 4 );
459 l->addWidget( a2DTriLab, 16, 0 );
460 l->addWidget( a2DTriTotal, 16, 1 );
461 l->addWidget( a2DTriLin, 16, 2 );
462 l->addWidget( a2DTriQuad, 16, 3 );
463 l->addWidget( a2DTriBiQuad, 16, 4 );
464 l->addWidget( a2DQuaLab, 17, 0 );
465 l->addWidget( a2DQuaTotal, 17, 1 );
466 l->addWidget( a2DQuaLin, 17, 2 );
467 l->addWidget( a2DQuaQuad, 17, 3 );
468 l->addWidget( a2DQuaBiQuad, 17, 4 );
469 l->addWidget( a2DPolLab, 18, 0 );
470 l->addWidget( a2DPolTotal, 18, 1 );
471 l->addWidget( a2DPolLin, 18, 2 );
472 l->addWidget( a2DPolQuad, 18, 3 );
473 l->addWidget( a3DLine, 19, 1, 1, 4 );
474 l->addWidget( a3DLab, 20, 0 );
475 l->addWidget( a3DTotal, 20, 1 );
476 l->addWidget( a3DLin, 20, 2 );
477 l->addWidget( a3DQuad, 20, 3 );
478 l->addWidget( a3DBiQuad, 20, 4 );
479 l->addWidget( a3DTetLab, 21, 0 );
480 l->addWidget( a3DTetTotal, 21, 1 );
481 l->addWidget( a3DTetLin, 21, 2 );
482 l->addWidget( a3DTetQuad, 21, 3 );
483 l->addWidget( a3DHexLab, 22, 0 );
484 l->addWidget( a3DHexTotal, 22, 1 );
485 l->addWidget( a3DHexLin, 22, 2 );
486 l->addWidget( a3DHexQuad, 22, 3 );
487 l->addWidget( a3DHexBiQuad, 22, 4 );
488 l->addWidget( a3DPyrLab, 23, 0 );
489 l->addWidget( a3DPyrTotal, 23, 1 );
490 l->addWidget( a3DPyrLin, 23, 2 );
491 l->addWidget( a3DPyrQuad, 23, 3 );
492 l->addWidget( a3DPriLab, 24, 0 );
493 l->addWidget( a3DPriTotal, 24, 1 );
494 l->addWidget( a3DPriLin, 24, 2 );
495 l->addWidget( a3DPriQuad, 24, 3 );
496 l->addWidget( a3DPriBiQuad, 24, 4 );
497 l->addWidget( a3DHexPriLab, 25, 0 );
498 l->addWidget( a3DHexPriTotal, 25, 1 );
499 l->addWidget( a3DPolLab, 26, 0 );
500 l->addWidget( a3DPolTotal, 26, 1 );
501 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
503 l->setColumnStretch( 0, 0 );
504 l->setColumnStretch( 1, 5 );
505 l->setColumnStretch( 2, 5 );
506 l->setColumnStretch( 3, 5 );
507 l->setColumnStretch( 4, 5 );
508 l->setRowStretch( 27, 5 );
516 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
521 \brief Show information on the mesh object.
522 \param obj object being processed (mesh, sub-mesh, group, ID source)
524 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
527 if ( !CORBA::is_nil( obj )) {
528 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
530 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
531 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
532 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
533 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
534 if ( !aMesh->_is_nil() ) {
535 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ));
537 else if ( !aSubMesh->_is_nil() ) {
538 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ));
540 else if ( !aGroup->_is_nil() ) {
542 switch( aGroup->GetType() ) {
543 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
544 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
545 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
546 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
547 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
548 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
549 default: objType = tr( "OBJECT_GROUP" );break;
551 myWidgets[iObject][iSingle]->setProperty( "text", objType );
553 SMESH::long_array_var info = obj->GetMeshInfo();
554 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ));
555 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ));
556 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ));
557 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
558 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ));
559 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ));
560 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ));
561 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
562 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
563 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
564 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
565 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
566 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
567 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
569 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
570 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ));
571 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ));
572 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ));
573 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ));
574 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ));
575 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ));
576 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ));
577 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ));
578 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ));
579 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ));
580 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ));
581 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
582 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ));
583 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ));
584 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
585 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
586 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
587 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta];
588 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
589 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
590 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta];
591 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
592 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ));
593 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ));
594 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ));
595 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ));
596 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ));
597 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ));
598 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ));
599 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ));
600 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ));
601 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ));
602 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ));
603 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ));
604 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ));
605 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ));
606 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ));
607 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ));
608 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ));
609 myWidgets[i3DPrisms][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] ));
610 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ));
611 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ));
612 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
613 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
614 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
615 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
616 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ));
617 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ));
618 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ));
619 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ));
620 // before full loading from study file, type of elements in a sub-mesh can't be defined
622 bool infoOK = obj->IsMeshInfoCorrect();
623 myLoadBtn->setVisible( !infoOK );
627 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
628 // 2. No info at all (for a group on geom or filter)
629 bool hasAnyInfo = false;
630 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
631 hasAnyInfo = info[i];
632 if ( hasAnyInfo ) // believe it is a sub-mesh
634 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
636 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
637 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
638 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
640 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
643 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
644 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
645 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
647 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
648 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
649 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
650 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
651 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
652 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
653 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
655 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
657 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
661 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
662 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
667 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
668 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
669 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
670 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
671 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
672 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
673 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
674 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
675 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
676 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
677 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
678 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
683 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
684 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
685 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
686 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
687 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
688 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
690 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
691 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
692 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
694 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
695 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
696 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
697 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
698 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
699 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
700 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
703 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
704 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
706 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
707 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
712 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
713 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
714 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
715 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
716 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
717 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
718 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
719 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
720 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
721 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
722 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
723 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
730 \brief Load mesh from a study file
732 void SMESHGUI_MeshInfo::loadMesh()
734 SUIT_OverrideCursor wc;
736 SALOME_ListIO selected;
737 SMESHGUI::selectionMgr()->selectedObjects( selected );
739 if ( selected.Extent() == 1 ) {
740 Handle(SALOME_InteractiveObject) IO = selected.First();
741 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
742 if ( !CORBA::is_nil( obj )) {
743 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
744 if ( !mesh->_is_nil() )
754 \brief Reset the widget to the initial state (nullify all fields).
756 void SMESHGUI_MeshInfo::clear()
758 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
759 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
760 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ));
761 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ));
762 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ));
763 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ));
764 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ));
765 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
766 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ));
767 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ));
768 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
769 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
770 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ));
771 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ));
772 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
773 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
774 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ));
775 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ));
776 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
777 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
778 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ));
779 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
780 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ));
781 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ));
782 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ));
783 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
784 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
785 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
786 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
787 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
788 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
789 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
790 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
791 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
792 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ));
793 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ));
794 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ));
795 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
796 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ));
797 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ));
798 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
799 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
800 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ));
801 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ));
802 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ));
803 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
807 \brief Create info field
808 \return new info field
810 QLabel* SMESHGUI_MeshInfo::createField()
812 QLabel* lab = new QLabel( this );
813 lab->setFrameStyle( StyledPanel | Sunken );
814 lab->setAlignment( Qt::AlignCenter );
815 lab->setAutoFillBackground( true );
816 QPalette pal = lab->palette();
817 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
818 lab->setPalette( pal );
819 lab->setMinimumWidth( 70 );
824 \brief Create horizontal rule.
825 \return new line object
827 QWidget* SMESHGUI_MeshInfo::createLine()
829 QFrame* line = new QFrame( this );
830 line->setFrameStyle( HLine | Sunken );
835 \brief Change widget font attributes (bold, italic, ...).
837 \param attr font attributes (XORed flags)
838 \param val value to be set to attributes
840 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
844 if ( attr & Bold ) f.setBold( val );
845 if ( attr & Italic ) f.setItalic( val );
851 \brief Show/hide group(s) of fields.
852 \param start beginning of the block
853 \param end end of the block
854 \param on visibility flag
856 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
858 start = qMax( 0, start );
859 end = qMin( end, (int)iElementsEnd );
860 for ( int i = start; i < end; i++ ) {
861 wlist wl = myWidgets[i];
862 foreach ( QWidget* w, wl ) w->setVisible( on );
866 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
868 out << QString( 9, '-' ) << "\n";
869 out << tr( "BASE_INFO" ) << "\n";
870 out << QString( 9, '-' ) << "\n";
871 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" )).toString() << "\n";
872 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" )).toString() << "\n";
873 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" )).toString() << "\n";
874 out << tr( "ELEMENTS_LAB" ) << "\n";
875 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" )).toString() << "\n";
876 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" )).toString() << "\n";
877 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" )).toString() << "\n";
878 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" )).toString() << "\n";
879 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
880 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" )).toString() << "\n";
881 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" )).toString() << "\n";
883 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" )).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" )).toString() << "\n";
886 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" )).toString() << "\n";
887 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
888 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" )).toString() << "\n";
889 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" )).toString() << "\n";
890 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" )).toString() << "\n";
891 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" )).toString() << "\n";
892 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" )).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" )).toString() << "\n";
895 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" )).toString() << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" )).toString() << "\n";
897 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" )).toString() << "\n";
899 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" )).toString() << "\n";
900 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" )).toString() << "\n";
901 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" )).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
903 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" )).toString() << "\n";
904 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" )).toString() << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" )).toString() << "\n";
906 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
907 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" )).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" )).toString() << "\n";
909 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" )).toString() << "\n";
910 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" )).toString() << "\n";
911 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" )).toString() << "\n";
913 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" )).toString() << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" )).toString() << "\n";
915 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" )).toString() << "\n";
917 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" )).toString() << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" )).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" )).toString() << "\n";
920 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
921 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" )).toString() << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" )).toString() << "\n";
923 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" )).toString() << "\n";
924 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
925 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" )).toString() << "\n";
926 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" )).toString() << "\n";
927 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" )).toString() << "\n";
928 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
929 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" )).toString() << "\n";
930 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
931 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" )).toString() << "\n" << "\n";
935 \class SMESHGUI_ElemInfo
936 \brief Base class for the mesh element information widget.
941 \param parent parent widget
943 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
944 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
946 myFrame = new QWidget( this );
947 myExtra = new ExtraWidget( this );
948 QVBoxLayout* vbl = new QVBoxLayout( this );
950 vbl->setSpacing( 0 );
951 vbl->addWidget( myFrame );
952 vbl->addWidget( myExtra );
953 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ));
954 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ));
961 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
966 \brief Set mesh data source (actor)
967 \param actor mesh object actor
969 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
971 if ( myActor != actor ) {
979 \brief Show mesh element information
980 \param id mesh node / element ID
981 \param isElem show mesh element information if \c true or mesh node information if \c false
983 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
987 showInfo( ids, isElem );
991 \brief Show mesh element information
992 \param ids mesh nodes / elements identifiers
993 \param isElem show mesh element information if \c true or mesh node information if \c false
995 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
997 QList<long> newIds = ids.toList();
999 if ( myIDs == newIds && myIsElement == isElem ) return;
1002 myIsElement = isElem;
1005 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1009 \brief Clear mesh element information widget
1011 void SMESHGUI_ElemInfo::clear()
1020 \brief Get central area widget
1021 \return central widget
1023 QWidget* SMESHGUI_ElemInfo::frame() const
1030 \return actor being used
1032 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1038 \brief Get current info mode.
1039 \return \c true if mesh element information is shown or \c false if node information is shown
1041 bool SMESHGUI_ElemInfo::isElements() const
1047 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1048 \brief Show information on the specified nodes / elements
1050 This function is to be redefined in sub-classes.
1052 \param ids nodes / elements identifiers information is to be shown on
1056 \brief Internal clean-up (reset widget)
1058 void SMESHGUI_ElemInfo::clearInternal()
1063 \brief Get node connectivity
1064 \param node mesh node
1065 \return node connectivity map
1067 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1071 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1072 while ( it && it->more() ) {
1073 const SMDS_MeshElement* ne = it->next();
1074 elmap[ ne->GetType() ] << ne->GetID();
1081 \brief Format connectivity data to string representation
1082 \param connectivity connetivity map
1083 \param type element type
1084 \return string representation of the connectivity
1086 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1089 if ( connectivity.contains( type )) {
1090 QList<int> elements = connectivity[ type ];
1092 foreach( int id, elements )
1093 str << QString::number( id );
1095 return str.join( " " );
1099 \brief Calculate gravity center of the mesh element
1100 \param element mesh element
1102 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1106 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1107 while ( nodeIt->more() ) {
1108 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1109 xyz.add( node->X(), node->Y(), node->Z() );
1111 xyz.divide( element->NbNodes() );
1117 \brief Calculate normal vector to the mesh face
1118 \param element mesh face
1120 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1122 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ));
1123 return XYZ(n.X(), n.Y(), n.Z());
1127 \brief This slot is called from "Show Previous" button click.
1128 Shows information on the previous group of the items.
1130 void SMESHGUI_ElemInfo::showPrevious()
1132 myIndex = qMax( 0, myIndex-1 );
1134 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1138 \brief This slot is called from "Show Next" button click.
1139 Shows information on the next group of the items.
1141 void SMESHGUI_ElemInfo::showNext()
1143 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1145 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1149 \brief Update widgets state
1151 void SMESHGUI_ElemInfo::updateControls()
1153 myExtra->updateControls( myIDs.count(), myIndex );
1157 \class SMESHGUI_SimpleElemInfo
1158 \brief Represents mesh element information in the simple text area.
1163 \param parent parent widget
1165 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1166 : SMESHGUI_ElemInfo( parent )
1168 myInfo = new QTextBrowser( frame() );
1169 QVBoxLayout* l = new QVBoxLayout( frame() );
1171 l->addWidget( myInfo );
1175 \brief Show mesh element information
1176 \param ids mesh nodes / elements identifiers
1178 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1183 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1184 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1185 int cprecision = -1;
1186 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1187 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1188 foreach ( long id, ids ) {
1189 if ( !isElements() ) {
1193 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1194 if ( !node ) return;
1197 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id ));
1199 myInfo->append( "" );
1201 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1202 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1203 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1204 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1206 myInfo->append( "" );
1208 Connectivity connectivity = nodeConnectivity( node );
1209 if ( !connectivity.isEmpty() ) {
1210 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1211 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1212 if ( !con.isEmpty() )
1213 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1214 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1215 if ( !con.isEmpty() )
1216 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1217 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1218 if ( !con.isEmpty() )
1219 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con ));
1220 con = formatConnectivity( connectivity, SMDSAbs_Face );
1221 if ( !con.isEmpty() )
1222 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1223 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1224 if ( !con.isEmpty() )
1225 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1228 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1231 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1232 if ( !CORBA::is_nil( aMeshPtr )) {
1233 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1234 int shapeID = pos->shapeID;
1235 if ( shapeID > 0 ) {
1237 double u = 0, v = 0;
1238 switch ( pos->shapeType ) {
1240 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1241 if ( pos->params.length() == 1 )
1245 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1246 if ( pos->params.length() == 2 ) {
1252 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1255 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1259 myInfo->append( "" );
1260 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) );
1261 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ));
1262 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1263 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )).
1264 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1265 if ( pos->shapeType == GEOM::FACE ) {
1266 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )).
1267 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1272 // groups node belongs to
1273 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1274 if ( !CORBA::is_nil( aMesh )) {
1275 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1276 myInfo->append( "" ); // separator
1277 bool top_created = false;
1278 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1279 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1280 if ( CORBA::is_nil( aGrp )) continue;
1281 QString aName = aGrp->GetName();
1282 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1283 if ( !top_created ) {
1284 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1287 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1288 if ( grp_details ) {
1289 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1290 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1291 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1293 // type : group on geometry, standalone group, group on filter
1294 if ( !CORBA::is_nil( aStdGroup )) {
1295 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1296 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1298 else if ( !CORBA::is_nil( aGeomGroup )) {
1299 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1300 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1301 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1302 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1304 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1305 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1308 else if ( !CORBA::is_nil( aFltGroup )) {
1309 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1310 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1314 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1315 arg( QString::number( aGrp->Size() )) );
1318 SALOMEDS::Color color = aGrp->GetColor();
1319 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1320 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1328 // show element info
1330 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1331 SMESH::Controls::NumericalFunctorPtr afunctor;
1334 // Element ID && Type
1336 switch( e->GetType() ) {
1337 case SMDSAbs_0DElement:
1338 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1340 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1342 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1344 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1345 case SMDSAbs_Volume:
1346 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1350 if ( stype.isEmpty() ) return;
1351 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ));
1353 myInfo->append( "" );
1357 switch( e->GetEntityType() ) {
1358 case SMDSEntity_Triangle:
1359 case SMDSEntity_Quad_Triangle:
1360 case SMDSEntity_BiQuad_Triangle:
1361 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1362 case SMDSEntity_Quadrangle:
1363 case SMDSEntity_Quad_Quadrangle:
1364 case SMDSEntity_BiQuad_Quadrangle:
1365 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1366 case SMDSEntity_Polygon:
1367 case SMDSEntity_Quad_Polygon:
1368 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1369 case SMDSEntity_Tetra:
1370 case SMDSEntity_Quad_Tetra:
1371 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1372 case SMDSEntity_Pyramid:
1373 case SMDSEntity_Quad_Pyramid:
1374 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1375 case SMDSEntity_Hexa:
1376 case SMDSEntity_Quad_Hexa:
1377 case SMDSEntity_TriQuad_Hexa:
1378 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1379 case SMDSEntity_Penta:
1380 case SMDSEntity_Quad_Penta:
1381 case SMDSEntity_BiQuad_Penta:
1382 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1383 case SMDSEntity_Hexagonal_Prism:
1384 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1385 case SMDSEntity_Polyhedra:
1386 case SMDSEntity_Quad_Polyhedra:
1387 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1391 if ( !gtype.isEmpty() )
1392 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype ));
1394 // Quadratic flag (any element except 0D)
1395 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1396 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) );
1398 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1400 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() ));
1403 myInfo->append( "" );
1406 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1407 for ( int idx = 1; nodeIt->more(); idx++ ) {
1408 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1409 // node number and ID
1410 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ));
1412 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1413 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1414 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1415 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1416 // node connectivity
1417 Connectivity connectivity = nodeConnectivity( node );
1418 if ( !connectivity.isEmpty() ) {
1419 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1420 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1421 if ( !con.isEmpty() )
1422 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1423 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1424 if ( !con.isEmpty() )
1425 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1426 con = formatConnectivity( connectivity, SMDSAbs_Face );
1427 if ( !con.isEmpty() )
1428 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1429 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1430 if ( !con.isEmpty() )
1431 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1434 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1438 myInfo->append( "" );
1441 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) );
1443 if ( e->GetType() == SMDSAbs_Edge ) {
1444 afunctor.reset( new SMESH::Controls::Length() );
1445 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1446 afunctor->SetPrecision( cprecision );
1447 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) );
1449 if( e->GetType() == SMDSAbs_Face ) {
1451 afunctor.reset( new SMESH::Controls::Area() );
1452 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1453 afunctor->SetPrecision( cprecision );
1454 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1456 afunctor.reset( new SMESH::Controls::Taper() );
1457 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1458 afunctor->SetPrecision( cprecision );
1459 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1461 afunctor.reset( new SMESH::Controls::AspectRatio() );
1462 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1463 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1465 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1466 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1467 afunctor->SetPrecision( cprecision );
1468 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1470 afunctor.reset( new SMESH::Controls::Warping() );
1471 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1472 afunctor->SetPrecision( cprecision );
1473 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1475 afunctor.reset( new SMESH::Controls::Skew() );
1476 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1477 afunctor->SetPrecision( cprecision );
1478 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1480 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1481 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1482 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) );
1484 if( e->GetType() == SMDSAbs_Volume ) {
1486 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1487 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1488 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1490 afunctor.reset( new SMESH::Controls::Volume() );
1491 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1492 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1494 afunctor.reset( new SMESH::Controls::Volume() );
1495 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1496 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) );
1499 myInfo->append( "" );
1502 XYZ gc = gravityCenter( e );
1503 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1506 if( e->GetType() == SMDSAbs_Face ) {
1507 XYZ gc = normal( e );
1508 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1512 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1513 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1514 if ( !CORBA::is_nil( aMesh )) {
1515 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1516 int shapeID = pos.shapeID;
1517 if ( shapeID > 0 ) {
1518 myInfo->append( "" ); // separator
1520 switch ( pos.shapeType ) {
1521 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1522 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1523 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1524 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1525 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1526 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1528 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID ));
1533 // Groups the element belongs to
1534 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1535 if ( !CORBA::is_nil( aMesh )) {
1536 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1537 myInfo->append( "" ); // separator
1538 bool top_created = false;
1539 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1540 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1541 if ( CORBA::is_nil( aGrp )) continue;
1542 QString aName = aGrp->GetName();
1543 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1544 if ( !top_created ) {
1545 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1548 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1549 if ( grp_details ) {
1550 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1551 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1552 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1554 // type : group on geometry, standalone group, group on filter
1555 if ( !CORBA::is_nil( aStdGroup )) {
1556 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1557 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1559 else if ( !CORBA::is_nil( aGeomGroup )) {
1560 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1561 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1562 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1563 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1565 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1566 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1569 else if ( !CORBA::is_nil( aFltGroup )) {
1570 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1571 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1574 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1575 arg( QString::number( aGrp->Size() )) );
1578 SALOMEDS::Color color = aGrp->GetColor();
1579 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1580 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1587 if ( ids.count() > 1 ) {
1588 myInfo->append( "" );
1589 myInfo->append( "------" );
1590 myInfo->append( "" );
1597 \brief Internal clean-up (reset widget)
1599 void SMESHGUI_SimpleElemInfo::clearInternal()
1604 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1606 out << QString( 12, '-' ) << "\n";
1607 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1608 out << QString( 12, '-' ) << "\n";
1609 out << myInfo->toPlainText();
1615 \class SMESHGUI_TreeElemInfo::ItemDelegate
1616 \brief Item delegate for tree mesh info widget
1619 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1622 ItemDelegate( QObject* );
1623 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1630 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1635 \brief Create item editor widget
1638 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1640 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1641 if ( qobject_cast<QLineEdit*>( w )) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1646 \class SMESHGUI_TreeElemInfo
1647 \brief Represents mesh element information in the tree-like form.
1652 \param parent parent widget
1654 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1655 : SMESHGUI_ElemInfo( parent )
1657 myInfo = new QTreeWidget( frame() );
1658 myInfo->setColumnCount( 2 );
1659 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ));
1660 myInfo->header()->setStretchLastSection( true );
1661 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1662 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1664 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1666 myInfo->setItemDelegate( new ItemDelegate( myInfo ));
1667 QVBoxLayout* l = new QVBoxLayout( frame() );
1669 l->addWidget( myInfo );
1670 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) );
1671 connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1672 connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1676 \brief Show mesh element information
1677 \param ids mesh nodes / elements identifiers
1679 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1684 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1685 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1686 int cprecision = -1;
1687 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1688 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1689 foreach ( long id, ids ) {
1690 if ( !isElements() ) {
1694 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1696 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1699 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1700 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ));
1701 nodeItem->setText( 1, QString( "#%1" ).arg( id ));
1703 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1704 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
1705 QTreeWidgetItem* xItem = createItem( coordItem );
1706 xItem->setText( 0, "X" );
1707 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1708 QTreeWidgetItem* yItem = createItem( coordItem );
1709 yItem->setText( 0, "Y" );
1710 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1711 QTreeWidgetItem* zItem = createItem( coordItem );
1712 zItem->setText( 0, "Z" );
1713 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1715 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1716 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1717 Connectivity connectivity = nodeConnectivity( node );
1718 if ( !connectivity.isEmpty() ) {
1719 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1720 if ( !con.isEmpty() ) {
1721 QTreeWidgetItem* i = createItem( conItem );
1722 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
1723 i->setText( 1, con );
1725 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1726 if ( !con.isEmpty() ) {
1727 QTreeWidgetItem* i = createItem( conItem );
1728 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
1729 i->setText( 1, con );
1730 i->setData( 1, TypeRole, NodeConnectivity );
1732 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1733 if ( !con.isEmpty() ) {
1734 QTreeWidgetItem* i = createItem( conItem );
1735 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
1736 i->setText( 1, con );
1737 i->setData( 1, TypeRole, NodeConnectivity );
1739 con = formatConnectivity( connectivity, SMDSAbs_Face );
1740 if ( !con.isEmpty() ) {
1741 QTreeWidgetItem* i = createItem( conItem );
1742 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
1743 i->setText( 1, con );
1744 i->setData( 1, TypeRole, NodeConnectivity );
1746 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1747 if ( !con.isEmpty() ) {
1748 QTreeWidgetItem* i = createItem( conItem );
1749 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
1750 i->setText( 1, con );
1751 i->setData( 1, TypeRole, NodeConnectivity );
1755 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ));
1758 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1759 if ( !CORBA::is_nil( aMeshPtr )) {
1760 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1761 int shapeID = pos->shapeID;
1762 if ( shapeID > 0 ) {
1764 double u = 0, v = 0;
1765 switch ( pos->shapeType ) {
1767 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1768 if ( pos->params.length() == 1 )
1772 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1773 if ( pos->params.length() == 2 ) {
1779 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1782 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1785 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1786 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1787 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1788 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1789 QTreeWidgetItem* uItem = createItem( posItem );
1790 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1791 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1792 if ( pos->shapeType == GEOM::FACE ) {
1793 QTreeWidgetItem* vItem = createItem( posItem );
1794 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1795 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1800 // groups node belongs to
1801 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1802 if ( !CORBA::is_nil( aMesh )) {
1803 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1804 QTreeWidgetItem* groupsItem = 0;
1805 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1806 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1807 if ( CORBA::is_nil( aGrp )) continue;
1808 QString aName = aGrp->GetName();
1809 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1810 if ( !groupsItem ) {
1811 groupsItem = createItem( nodeItem, Bold );
1812 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
1814 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1815 it->setText( 0, aName.trimmed() );
1816 if ( grp_details ) {
1817 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1818 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1819 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1821 // type : group on geometry, standalone group, group on filter
1822 QTreeWidgetItem* typeItem = createItem( it );
1823 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
1824 if ( !CORBA::is_nil( aStdGroup )) {
1825 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
1827 else if ( !CORBA::is_nil( aGeomGroup )) {
1828 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
1829 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1830 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1832 QTreeWidgetItem* gobjItem = createItem( typeItem );
1833 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
1834 gobjItem->setText( 1, sobj->GetName().c_str() );
1837 else if ( !CORBA::is_nil( aFltGroup )) {
1838 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
1842 QTreeWidgetItem* sizeItem = createItem( it );
1843 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
1844 sizeItem->setText( 1, QString::number( aGrp->Size() ));
1847 SALOMEDS::Color color = aGrp->GetColor();
1848 QTreeWidgetItem* colorItem = createItem( it );
1849 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
1850 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
1858 // show element info
1860 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1861 SMESH::Controls::NumericalFunctorPtr afunctor;
1864 // element ID && type
1866 switch( e->GetType() ) {
1867 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1868 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1869 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1870 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1871 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1874 if ( stype.isEmpty() ) return;
1875 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1876 elemItem->setText( 0, stype );
1877 elemItem->setText( 1, QString( "#%1" ).arg( id ));
1880 switch( e->GetEntityType() ) {
1881 case SMDSEntity_Triangle:
1882 case SMDSEntity_Quad_Triangle:
1883 case SMDSEntity_BiQuad_Triangle:
1884 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1885 case SMDSEntity_Quadrangle:
1886 case SMDSEntity_Quad_Quadrangle:
1887 case SMDSEntity_BiQuad_Quadrangle:
1888 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1889 case SMDSEntity_Polygon:
1890 case SMDSEntity_Quad_Polygon:
1891 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1892 case SMDSEntity_Tetra:
1893 case SMDSEntity_Quad_Tetra:
1894 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1895 case SMDSEntity_Pyramid:
1896 case SMDSEntity_Quad_Pyramid:
1897 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1898 case SMDSEntity_Hexa:
1899 case SMDSEntity_Quad_Hexa:
1900 case SMDSEntity_TriQuad_Hexa:
1901 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1902 case SMDSEntity_Penta:
1903 case SMDSEntity_Quad_Penta:
1904 case SMDSEntity_BiQuad_Penta:
1905 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1906 case SMDSEntity_Hexagonal_Prism:
1907 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1908 case SMDSEntity_Polyhedra:
1909 case SMDSEntity_Quad_Polyhedra:
1910 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1914 if ( !gtype.isEmpty() ) {
1915 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1916 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ));
1917 typeItem->setText( 1, gtype );
1919 // quadratic flag (for edges, faces and volumes)
1920 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1922 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1923 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ));
1924 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ));
1926 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1928 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1929 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ));
1930 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1933 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1934 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1937 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1938 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1939 for ( int idx = 1; nodeIt->more(); idx++ ) {
1940 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1941 nodeInfo( node, idx, e->NbNodes(), conItem );
1945 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1946 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1947 QList<const SMDS_MeshElement*> uniqueNodes;
1948 while ( nodeIt->more() )
1949 uniqueNodes.append( nodeIt->next() );
1951 SMDS_VolumeTool vtool( e );
1952 const int nbFaces = vtool.NbFaces();
1953 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1954 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1955 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces ));
1956 faceItem->setExpanded( true );
1958 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1959 const int nbNodes = vtool.NbFaceNodes( face_id );
1960 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1961 const SMDS_MeshNode* node = aNodeIds[node_id];
1962 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1967 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1968 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ));
1970 if( e->GetType()==SMDSAbs_Edge){
1971 afunctor.reset( new SMESH::Controls::Length() );
1972 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1973 afunctor->SetPrecision( cprecision );
1974 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1975 lenItem->setText( 0, tr( "LENGTH_EDGES" ));
1976 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1978 if( e->GetType() == SMDSAbs_Face ) {
1980 afunctor.reset( new SMESH::Controls::Area() );
1981 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1982 afunctor->SetPrecision( cprecision );
1983 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1984 areaItem->setText( 0, tr( "AREA_ELEMENTS" ));
1985 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ));
1987 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1989 afunctor.reset( new SMESH::Controls::Taper() );
1990 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1991 afunctor->SetPrecision( cprecision );
1992 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1993 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ));
1994 taperlItem->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 )) );
2006 afunctor.reset( new SMESH::Controls::AspectRatio() );
2007 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2008 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
2009 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2010 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2013 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2014 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2015 afunctor->SetPrecision( cprecision );
2016 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2017 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ));
2018 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2020 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2022 afunctor.reset( new SMESH::Controls::Skew() );
2023 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2024 afunctor->SetPrecision( cprecision );
2025 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2026 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ));
2027 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2032 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2033 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2034 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2035 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2036 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2039 if( e->GetType() == SMDSAbs_Volume ) {
2043 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2044 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2045 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2046 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ));
2047 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2050 afunctor.reset( new SMESH::Controls::Volume() );
2051 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2052 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2053 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ));
2054 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2056 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2057 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2058 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2059 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ));
2060 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2064 XYZ gc = gravityCenter( e );
2065 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2066 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ));
2067 QTreeWidgetItem* xItem = createItem( gcItem );
2068 xItem->setText( 0, "X" );
2069 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2070 QTreeWidgetItem* yItem = createItem( gcItem );
2071 yItem->setText( 0, "Y" );
2072 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2073 QTreeWidgetItem* zItem = createItem( gcItem );
2074 zItem->setText( 0, "Z" );
2075 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2078 if( e->GetType() == SMDSAbs_Face ) {
2079 XYZ gc = normal( e );
2080 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2081 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ));
2082 QTreeWidgetItem* xItem = createItem( nItem );
2083 xItem->setText( 0, "X" );
2084 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2085 QTreeWidgetItem* yItem = createItem( nItem );
2086 yItem->setText( 0, "Y" );
2087 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2088 QTreeWidgetItem* zItem = createItem( nItem );
2089 zItem->setText( 0, "Z" );
2090 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2094 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2095 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2096 if ( !CORBA::is_nil( aMesh )) {
2097 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2098 int shapeID = pos.shapeID;
2099 if ( shapeID > 0 ) {
2100 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2102 switch ( pos.shapeType ) {
2103 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2104 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2105 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2106 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2107 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2108 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2110 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ));
2111 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ));
2115 // groups element belongs to
2116 if ( !CORBA::is_nil( aMesh )) {
2117 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2118 QTreeWidgetItem* groupsItem = 0;
2119 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2120 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2121 if ( CORBA::is_nil( aGrp )) continue;
2122 QString aName = aGrp->GetName();
2123 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
2124 if ( !groupsItem ) {
2125 groupsItem = createItem( elemItem, Bold );
2126 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
2128 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2129 it->setText( 0, aName.trimmed() );
2130 if ( grp_details ) {
2131 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2132 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2133 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2135 // type : group on geometry, standalone group, group on filter
2136 QTreeWidgetItem* typeItem = createItem( it );
2137 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
2138 if ( !CORBA::is_nil( aStdGroup )) {
2139 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
2141 else if ( !CORBA::is_nil( aGeomGroup )) {
2142 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
2143 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2144 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2146 QTreeWidgetItem* gobjItem = createItem( typeItem );
2147 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2148 gobjItem->setText( 1, sobj->GetName().c_str() );
2151 else if ( !CORBA::is_nil( aFltGroup )) {
2152 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2156 QTreeWidgetItem* sizeItem = createItem( it );
2157 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2158 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2161 SALOMEDS::Color color = aGrp->GetColor();
2162 QTreeWidgetItem* colorItem = createItem( it );
2163 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2164 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2175 \brief Show node information
2176 \param node mesh node for showing
2177 \param index index of current node
2178 \param nbNodes number of unique nodes in element
2179 \param parentItem parent item of tree
2181 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2182 int nbNodes, QTreeWidgetItem* parentItem )
2184 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2185 // node number and ID
2186 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2187 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2188 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2189 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2190 nodeItem->setData( 1, IdRole, node->GetID() );
2191 nodeItem->setExpanded( false );
2193 QTreeWidgetItem* coordItem = createItem( nodeItem );
2194 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2195 QTreeWidgetItem* xItem = createItem( coordItem );
2196 xItem->setText( 0, "X" );
2197 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2198 QTreeWidgetItem* yItem = createItem( coordItem );
2199 yItem->setText( 0, "Y" );
2200 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2201 QTreeWidgetItem* zItem = createItem( coordItem );
2202 zItem->setText( 0, "Z" );
2203 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2204 // node connectivity
2205 QTreeWidgetItem* nconItem = createItem( nodeItem );
2206 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2207 Connectivity connectivity = nodeConnectivity( node );
2208 if ( !connectivity.isEmpty() ) {
2209 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2210 if ( !con.isEmpty() ) {
2211 QTreeWidgetItem* i = createItem( nconItem );
2212 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2213 i->setText( 1, con );
2215 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2216 if ( !con.isEmpty() ) {
2217 QTreeWidgetItem* i = createItem( nconItem );
2218 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2219 i->setText( 1, con );
2220 i->setData( 1, TypeRole, NodeConnectivity );
2222 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2223 if ( !con.isEmpty() ) {
2224 QTreeWidgetItem* i = createItem( nconItem );
2225 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2226 i->setText( 1, con );
2227 i->setData( 1, TypeRole, NodeConnectivity );
2229 con = formatConnectivity( connectivity, SMDSAbs_Face );
2230 if ( !con.isEmpty() ) {
2231 QTreeWidgetItem* i = createItem( nconItem );
2232 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2233 i->setText( 1, con );
2234 i->setData( 1, TypeRole, NodeConnectivity );
2236 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2237 if ( !con.isEmpty() ) {
2238 QTreeWidgetItem* i = createItem( nconItem );
2239 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2240 i->setText( 1, con );
2241 i->setData( 1, TypeRole, NodeConnectivity );
2246 \brief Internal clean-up (reset widget)
2248 void SMESHGUI_TreeElemInfo::clearInternal()
2255 \brief Create new tree item.
2256 \param parent parent tree widget item
2257 \param flags item flag
2258 \return new tree widget item
2260 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2262 QTreeWidgetItem* item;
2264 item = new QTreeWidgetItem( parent );
2266 item = new QTreeWidgetItem( myInfo );
2268 item->setFlags( item->flags() | Qt::ItemIsEditable );
2270 QFont f = item->font( 0 );
2272 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2273 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2274 item->setFont( i, f );
2277 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2279 QString resName = expandedResource( parent );
2280 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2283 item->setExpanded( true );
2287 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2289 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2290 if ( widgets.isEmpty() ) return;
2291 QTreeWidgetItem* aTreeItem = widgets.first();
2292 int type = aTreeItem->data( 1, TypeRole ).toInt();
2293 int id = aTreeItem->data( 1, IdRole ).toInt();
2295 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2296 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2297 emit( itemInfo( id ));
2298 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2299 emit( itemInfo( aTreeItem->text( 1 )) );
2302 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2305 int type = theItem->data( 1, TypeRole ).toInt();
2306 int id = theItem->data( 1, IdRole ).toInt();
2307 if ( type == ElemConnectivity && id > 0 )
2308 emit( itemInfo( id ));
2309 else if ( type == NodeConnectivity )
2310 emit( itemInfo( theItem->text( 1 )) );
2314 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2317 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2320 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2322 return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0);
2325 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2327 out << QString( 12, '-' ) << "\n";
2328 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2329 out << QString( 12, '-' ) << "\n";
2331 QTreeWidgetItemIterator it( myInfo );
2333 if ( !( *it )->text(0).isEmpty() ) {
2334 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2335 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2345 \brief Mesh information computer
2348 The class is created for different computation operation. Currently it is used
2349 to compute number of underlying nodes for the groups.
2355 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2356 QTreeWidgetItem* item,
2359 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2361 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2365 \brief Compute function
2367 void GrpComputor::compute()
2369 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2370 SUIT_OverrideCursor wc;
2371 QTreeWidgetItem* item = myItem;
2373 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2374 item->treeWidget()->removeItemWidget( item, 1 );
2375 item->setText( 1, QString::number( nb ));
2380 \class SMESHGUI_AddInfo
2381 \brief The wigdet shows additional information on the mesh object.
2386 \param parent parent widget
2388 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2389 : QTreeWidget( parent )
2391 setColumnCount( 2 );
2392 header()->setStretchLastSection( true );
2393 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2394 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2396 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2404 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2409 \brief Show additional information on the selected object
2410 \param obj object being processed (mesh, sub-mesh, group, ID source)
2412 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2414 setProperty( "group_index", 0 );
2415 setProperty( "submesh_index", 0 );
2416 myComputors.clear();
2419 if ( CORBA::is_nil( obj )) return;
2421 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2422 if ( !sobj ) return;
2425 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2426 nameItem->setText( 0, tr( "NAME" ));
2427 nameItem->setText( 1, sobj->GetName().c_str() );
2429 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2430 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2431 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2433 if ( !aMesh->_is_nil() )
2434 meshInfo( aMesh, nameItem );
2435 else if ( !aSubMesh->_is_nil() )
2436 subMeshInfo( aSubMesh, nameItem );
2437 else if ( !aGroup->_is_nil() )
2438 groupInfo( aGroup.in(), nameItem );
2442 \brief Create new tree item.
2443 \param parent parent tree widget item
2444 \param flags item flag
2445 \return new tree widget item
2447 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2449 QTreeWidgetItem* item;
2452 item = new QTreeWidgetItem( parent );
2454 item = new QTreeWidgetItem( this );
2456 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2458 QFont f = item->font( 0 );
2460 for ( int i = 0; i < columnCount(); i++ ) {
2461 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2462 item->setFont( i, f );
2465 item->setExpanded( true );
2470 \brief Show mesh info
2471 \param mesh mesh object
2472 \param parent parent tree item
2474 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2477 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2478 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2479 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2480 typeItem->setText( 0, tr( "TYPE" ));
2481 if ( !CORBA::is_nil( shape )) {
2482 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ));
2483 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2485 QTreeWidgetItem* gobjItem = createItem( typeItem );
2486 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2487 gobjItem->setText( 1, sobj->GetName().c_str() );
2490 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2491 typeItem->setText( 1, tr( "MESH_FROM_FILE" ));
2492 QTreeWidgetItem* fileItem = createItem( typeItem );
2493 fileItem->setText( 0, tr( "FILE_NAME" ));
2494 fileItem->setText( 1, (char*)inf->fileName );
2497 typeItem->setText( 1, tr( "STANDALONE_MESH" ));
2501 myGroups = mesh->GetGroups();
2505 mySubMeshes = mesh->GetSubMeshes();
2510 \brief Show sub-mesh info
2511 \param subMesh sub-mesh object
2512 \param parent parent tree item
2514 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2516 bool isShort = parent->parent() != 0;
2520 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2522 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2523 nameItem->setText( 0, tr( "PARENT_MESH" ));
2524 nameItem->setText( 1, sobj->GetName().c_str() );
2529 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2530 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2532 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2533 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2534 gobjItem->setText( 1, sobj->GetName().c_str() );
2539 \brief Show group info
2540 \param grp mesh group object
2541 \param parent parent tree item
2543 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2545 bool isShort = parent->parent() != 0;
2547 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2548 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2549 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2553 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2555 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2556 nameItem->setText( 0, tr( "PARENT_MESH" ));
2557 nameItem->setText( 1, sobj->GetName().c_str() );
2561 // type : group on geometry, standalone group, group on filter
2562 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2563 typeItem->setText( 0, tr( "TYPE" ));
2564 if ( !CORBA::is_nil( aStdGroup )) {
2565 typeItem->setText( 1, tr( "STANDALONE_GROUP" ));
2567 else if ( !CORBA::is_nil( aGeomGroup )) {
2568 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ));
2569 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2570 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2572 QTreeWidgetItem* gobjItem = createItem( typeItem );
2573 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2574 gobjItem->setText( 1, sobj->GetName().c_str() );
2577 else if ( !CORBA::is_nil( aFltGroup )) {
2578 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ));
2583 QString etype = tr( "UNKNOWN" );
2584 switch( grp->GetType() ) {
2586 etype = tr( "NODE" );
2589 etype = tr( "EDGE" );
2592 etype = tr( "FACE" );
2595 etype = tr( "VOLUME" );
2598 etype = tr( "0DELEM" );
2601 etype = tr( "BALL" );
2606 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2607 etypeItem->setText( 0, tr( "ENTITY_TYPE" ));
2608 etypeItem->setText( 1, etype );
2611 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2612 bool meshLoaded = mesh->IsLoaded();
2614 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2616 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2617 groupSize = grp->Size();
2619 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2620 sizeItem->setText( 0, tr( "SIZE" ));
2621 if ( groupSize > -1 ) {
2622 sizeItem->setText( 1, QString::number( groupSize ));
2625 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2626 setItemWidget( sizeItem, 1, btn );
2627 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2628 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2629 myComputors.append( comp );
2631 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2635 SALOMEDS::Color color = grp->GetColor();
2636 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2637 colorItem->setText( 0, tr( "COLOR" ));
2638 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2640 // nb of underlying nodes
2641 if ( grp->GetType() != SMESH::NODE) {
2642 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2643 nodesItem->setText( 0, tr( "NB_NODES" ));
2644 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2645 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2646 if ( toShowNodes && meshLoaded ) {
2647 // already calculated and up-to-date
2648 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ));
2651 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2652 setItemWidget( nodesItem, 1, btn );
2653 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2654 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2655 myComputors.append( comp );
2657 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2662 void SMESHGUI_AddInfo::showGroups()
2664 myComputors.clear();
2666 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2667 if ( !parent ) return;
2669 int idx = property( "group_index" ).toInt();
2671 QTreeWidgetItem* itemGroups = 0;
2672 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2673 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2674 itemGroups = parent->child( i );
2675 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ));
2677 extra->updateControls( myGroups->length(), idx );
2678 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2682 QMap<int, QTreeWidgetItem*> grpItems;
2683 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2684 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2685 if ( CORBA::is_nil( grp )) continue;
2686 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2687 if ( !grpSObj ) continue;
2689 int grpType = grp->GetType();
2691 if ( !itemGroups ) {
2692 // create top-level groups container item
2693 itemGroups = createItem( parent, Bold | All );
2694 itemGroups->setText( 0, tr( "GROUPS" ));
2695 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2697 // total number of groups > 10, show extra widgets for info browsing
2698 if ((int) myGroups->length() > MAXITEMS ) {
2699 ExtraWidget* extra = new ExtraWidget( this, true );
2700 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ));
2701 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ));
2702 setItemWidget( itemGroups, 1, extra );
2703 extra->updateControls( myGroups->length(), idx );
2707 if ( grpItems.find( grpType ) == grpItems.end() ) {
2708 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2709 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ));
2710 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2714 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2715 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2718 groupInfo( grp.in(), grpNameItem );
2722 void SMESHGUI_AddInfo::showSubMeshes()
2724 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2725 if ( !parent ) return;
2727 int idx = property( "submesh_index" ).toInt();
2729 QTreeWidgetItem* itemSubMeshes = 0;
2730 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2731 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2732 itemSubMeshes = parent->child( i );
2733 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ));
2735 extra->updateControls( mySubMeshes->length(), idx );
2736 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2740 QMap<int, QTreeWidgetItem*> smItems;
2741 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2742 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2743 if ( CORBA::is_nil( sm )) continue;
2744 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2745 if ( !smSObj ) continue;
2747 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2748 if ( CORBA::is_nil(gobj )) continue;
2750 int smType = gobj->GetShapeType();
2751 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2753 if ( !itemSubMeshes ) {
2754 itemSubMeshes = createItem( parent, Bold | All );
2755 itemSubMeshes->setText( 0, tr( "SUBMESHES" ));
2756 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2758 // total number of sub-meshes > 10, show extra widgets for info browsing
2759 if ((int) mySubMeshes->length() > MAXITEMS ) {
2760 ExtraWidget* extra = new ExtraWidget( this, true );
2761 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ));
2762 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ));
2763 setItemWidget( itemSubMeshes, 1, extra );
2764 extra->updateControls( mySubMeshes->length(), idx );
2768 if ( smItems.find( smType ) == smItems.end() ) {
2769 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2770 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ));
2771 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2775 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2776 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2779 subMeshInfo( sm.in(), smNameItem );
2784 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2786 void SMESHGUI_AddInfo::changeLoadToCompute()
2788 for ( int i = 0; i < myComputors.count(); ++i )
2790 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2792 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 )) )
2793 btn->setText( tr("COMPUTE") );
2798 void SMESHGUI_AddInfo::showPreviousGroups()
2800 int idx = property( "group_index" ).toInt();
2801 setProperty( "group_index", idx-1 );
2805 void SMESHGUI_AddInfo::showNextGroups()
2807 int idx = property( "group_index" ).toInt();
2808 setProperty( "group_index", idx+1 );
2812 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2814 int idx = property( "submesh_index" ).toInt();
2815 setProperty( "submesh_index", idx-1 );
2819 void SMESHGUI_AddInfo::showNextSubMeshes()
2821 int idx = property( "submesh_index" ).toInt();
2822 setProperty( "submesh_index", idx+1 );
2826 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2828 out << QString( 15, '-') << "\n";
2829 out << tr( "ADDITIONAL_INFO" ) << "\n";
2830 out << QString( 15, '-' ) << "\n";
2831 QTreeWidgetItemIterator it( this );
2833 if ( !( ( *it )->text(0) ).isEmpty() ) {
2834 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2835 if ( ( *it )->text(0) == tr( "COLOR" )) {
2836 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2838 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2847 \class SMESHGUI_MeshInfoDlg
2848 \brief Mesh information dialog box
2853 \param parent parent widget
2854 \param page specifies the dialog page to be shown at the start-up
2856 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2857 : QDialog( parent ), myActor( 0 )
2860 setAttribute( Qt::WA_DeleteOnClose, true );
2861 setWindowTitle( tr( "MESH_INFO" ));
2862 setSizeGripEnabled( true );
2864 myTabWidget = new QTabWidget( this );
2868 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2869 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ));
2873 QWidget* w = new QWidget( myTabWidget );
2875 myMode = new QButtonGroup( this );
2876 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2877 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2878 myMode->button( NodeMode )->setChecked( true );
2879 myID = new QLineEdit( w );
2880 myID->setValidator( new SMESHGUI_IdValidator( this ));
2881 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
2882 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
2884 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2885 mode = qMin( 1, qMax( 0, mode ));
2888 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2890 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2892 QGridLayout* elemLayout = new QGridLayout( w );
2893 elemLayout->setMargin( MARGIN );
2894 elemLayout->setSpacing( SPACING );
2895 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2896 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2897 elemLayout->addWidget( myID, 0, 2 );
2898 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 );
2899 elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 );
2901 myTabWidget->addTab( w, tr( "ELEM_INFO" ));
2905 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2906 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ));
2910 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2911 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ));
2915 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2916 okBtn->setAutoDefault( true );
2917 okBtn->setDefault( true );
2919 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2920 dumpBtn->setAutoDefault( true );
2921 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2922 helpBtn->setAutoDefault( true );
2924 QHBoxLayout* btnLayout = new QHBoxLayout;
2925 btnLayout->setSpacing( SPACING );
2926 btnLayout->setMargin( 0 );
2928 btnLayout->addWidget( okBtn );
2929 btnLayout->addWidget( dumpBtn );
2930 btnLayout->addStretch( 10 );
2931 btnLayout->addWidget( helpBtn );
2933 QVBoxLayout* l = new QVBoxLayout ( this );
2934 l->setMargin( MARGIN );
2935 l->setSpacing( SPACING );
2936 l->addWidget( myTabWidget );
2937 l->addLayout( btnLayout );
2939 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page )));
2941 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
2942 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
2943 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
2944 connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() ));
2945 connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() ));
2946 connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() ));
2947 connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) ));
2948 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
2949 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
2950 connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int )));
2951 connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
2953 myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false ));
2961 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2967 \brief Show mesh information
2968 \param IO interactive object
2970 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2975 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2976 if ( !CORBA::is_nil( obj ))
2978 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2979 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2980 if ( myTabWidget->currentIndex() == CtrlInfo )
2981 myCtrlInfo->showInfo( obj );
2984 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2985 SVTK_Selector* selector = SMESH::GetSelector();
2988 if ( myActor && selector ) {
2989 nb = myMode->checkedId() == NodeMode ?
2990 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2991 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2993 myElemInfo->setSource( myActor ) ;
2995 myID->setText( ID.trimmed() );
2997 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2998 foreach ( ID, idTxt )
2999 ids << ID.trimmed().toLong();
3000 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3004 myElemInfo->clear();
3011 \brief Perform clean-up actions on the dialog box closing.
3013 void SMESHGUI_MeshInfoDlg::reject()
3015 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3016 selMgr->clearFilters();
3017 SMESH::SetPointRepresentation( false );
3018 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3019 aViewWindow->SetSelectionMode( ActorSelection );
3021 myIDPreview->SetPointsLabeled(false);
3025 \brief Process keyboard event
3026 \param e key press event
3028 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3030 QDialog::keyPressEvent( e );
3031 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3038 \brief Reactivate dialog box, when mouse pointer goes into it.
3040 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3046 \brief Setup selection mode depending on the current dialog box state.
3048 void SMESHGUI_MeshInfoDlg::updateSelection()
3050 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3052 disconnect( selMgr, 0, this, 0 );
3053 selMgr->clearFilters();
3055 if ( myTabWidget->currentIndex() == BaseInfo ||
3056 myTabWidget->currentIndex() == AddInfo ||
3057 myTabWidget->currentIndex() == CtrlInfo ) {
3058 SMESH::SetPointRepresentation( false );
3059 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3060 aViewWindow->SetSelectionMode( ActorSelection );
3063 if ( myMode->checkedId() == NodeMode ) {
3064 SMESH::SetPointRepresentation( true );
3065 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3066 aViewWindow->SetSelectionMode( NodeSelection );
3069 SMESH::SetPointRepresentation( false );
3070 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3071 aViewWindow->SetSelectionMode( CellSelection );
3075 QString oldID = myID->text().trimmed();
3076 SMESH_Actor* oldActor = myActor;
3079 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3082 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3083 myID->setText( oldID );
3089 \brief Show help page
3091 void SMESHGUI_MeshInfoDlg::help()
3093 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3094 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3095 "mesh_infos_page.html#mesh_element_info_anchor" );
3099 \brief Show mesh information
3101 void SMESHGUI_MeshInfoDlg::updateInfo()
3103 SUIT_OverrideCursor wc;
3105 SALOME_ListIO selected;
3106 SMESHGUI::selectionMgr()->selectedObjects( selected );
3108 if ( selected.Extent() == 1 ) {
3109 Handle(SALOME_InteractiveObject) IO = selected.First();
3118 \brief Activate dialog box
3120 void SMESHGUI_MeshInfoDlg::activate()
3122 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3123 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3124 myTabWidget->setEnabled( true );
3129 \brief Deactivate dialog box
3131 void SMESHGUI_MeshInfoDlg::deactivate()
3133 myTabWidget->setEnabled( false );
3134 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3138 \brief Called when users switches between node / element modes.
3140 void SMESHGUI_MeshInfoDlg::modeChanged()
3147 \brief Called when users prints mesh element ID in the corresponding field.
3149 void SMESHGUI_MeshInfoDlg::idChanged()
3151 myIDPreview->SetPointsLabeled( false );
3153 SVTK_Selector* selector = SMESH::GetSelector();
3154 if ( myActor && selector ) {
3155 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3156 TColStd_MapOfInteger ID;
3158 std::vector<int> idVec;
3159 std::list< gp_XYZ > aGrCentersXYZ;
3160 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3161 foreach ( QString tid, idTxt ) {
3162 long id = tid.trimmed().toLong();
3163 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3164 myActor->GetObject()->GetMesh()->FindElement( id ) :
3165 myActor->GetObject()->GetMesh()->FindNode( id );
3169 if ( myMode->checkedId() == ElemMode )
3171 idVec.push_back( id );
3172 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ));
3176 selector->AddOrRemoveIndex( IO, ID, false );
3177 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3179 if ( myMode->checkedId() == NodeMode )
3180 myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID );
3182 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3184 bool showIDs = ( !ID.IsEmpty() &&
3185 myIDPreviewCheck->isChecked() &&
3186 myTabWidget->currentIndex() == ElemInfo );
3187 myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() );
3189 aViewWindow->highlight( IO, true, true );
3190 aViewWindow->Repaint();
3192 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3197 * \brief Show IDs clicked
3199 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3201 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3202 SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn );
3203 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3204 aViewWindow->Repaint();
3207 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3209 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) {
3210 myMode->button( NodeMode )->click();
3211 myID->setText( QString::number( id ));
3215 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3217 if ( !theStr.isEmpty() ) {
3218 myMode->button( ElemMode )->click();
3219 myID->setText( theStr );
3223 void SMESHGUI_MeshInfoDlg::dump()
3225 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3227 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3228 if ( !appStudy ) return;
3229 _PTR( Study ) aStudy = appStudy->studyDS();
3231 QStringList aFilters;
3232 aFilters.append( tr( "TEXT_FILES" ));
3234 bool anIsBase = true;
3235 bool anIsElem = true;
3236 bool anIsAdd = true;
3237 bool anIsCtrl = true;
3239 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3240 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3241 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3242 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3243 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3246 DumpFileDlg fd( this );
3247 fd.setWindowTitle( tr( "SAVE_INFO" ));
3248 fd.setNameFilters( aFilters );
3249 fd.myBaseChk->setChecked( anIsBase );
3250 fd.myElemChk->setChecked( anIsElem );
3251 fd.myAddChk ->setChecked( anIsAdd );
3252 fd.myCtrlChk->setChecked( anIsCtrl );
3253 if ( fd.exec() == QDialog::Accepted )
3255 QString aFileName = fd.selectedFile();
3257 bool toBase = fd.myBaseChk->isChecked();
3258 bool toElem = fd.myElemChk->isChecked();
3259 bool toAdd = fd.myAddChk->isChecked();
3260 bool toCtrl = fd.myCtrlChk->isChecked();
3262 if ( !aFileName.isEmpty() ) {
3263 QFileInfo aFileInfo( aFileName );
3264 if ( aFileInfo.isDir() )
3267 QFile aFile( aFileName );
3268 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3271 QTextStream out( &aFile );
3273 if ( toBase ) myBaseInfo->saveInfo( out );
3274 if ( toElem ) myElemInfo->saveInfo( out );
3275 if ( toAdd ) myAddInfo ->saveInfo( out );
3276 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3282 \class SMESHGUI_CtrlInfo
3283 \brief Class for the mesh controls information widget.
3288 \param parent parent widget
3290 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3291 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3293 setFrameStyle( StyledPanel | Sunken );
3295 myMainLayout = new QGridLayout( this );
3296 myMainLayout->setMargin( MARGIN );
3297 myMainLayout->setSpacing( SPACING );
3300 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3301 QLabel* aName = createField();
3302 aName->setMinimumWidth( 150 );
3305 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3306 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) );
3308 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3311 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3312 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3313 QLabel* aNodesFree = createField();
3314 myWidgets << aNodesFree;
3315 myPredicates << aFilterMgr->CreateFreeNodes();
3317 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3318 QLabel* aNodesNbConn = createField();
3319 myWidgets << aNodesNbConn;
3320 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3322 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3323 QLabel* aNodesDouble = createField();
3324 myWidgets << aNodesDouble;
3325 myPredicates << aFilterMgr->CreateEqualNodes();
3326 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3327 myToleranceWidget = new SMESHGUI_SpinBox( this );
3328 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3329 myToleranceWidget->setAcceptNames( false );
3330 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ));
3333 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3334 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3335 QLabel* anEdgesDouble = createField();
3336 myWidgets << anEdgesDouble;
3337 myPredicates << aFilterMgr->CreateEqualEdges();
3340 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3341 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3342 QLabel* aFacesDouble = createField();
3343 myWidgets << aFacesDouble;
3344 myPredicates << aFilterMgr->CreateEqualFaces();
3345 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3346 QLabel* aFacesOver = createField();
3347 myWidgets << aFacesOver;
3348 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3349 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3350 myPlot = createPlot( this );
3351 myAspectRatio = aFilterMgr->CreateAspectRatio();
3354 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3355 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3356 QLabel* aVolumesDouble = createField();
3357 myWidgets << aVolumesDouble;
3358 myPredicates << aFilterMgr->CreateEqualVolumes();
3359 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3360 QLabel* aVolumesOver = createField();
3361 myWidgets << aVolumesOver;
3362 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3363 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3364 myPlot3D = createPlot( this );
3365 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3367 QToolButton* aFreeNodesBtn = new QToolButton( this );
3368 aFreeNodesBtn->setIcon(aComputeIcon);
3369 myButtons << aFreeNodesBtn; //0
3371 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3372 aNodesNbConnBtn->setIcon(aComputeIcon);
3373 myButtons << aNodesNbConnBtn; //1
3375 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3376 aDoubleNodesBtn->setIcon(aComputeIcon);
3377 myButtons << aDoubleNodesBtn; //2
3379 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3380 aDoubleEdgesBtn->setIcon(aComputeIcon);
3381 myButtons << aDoubleEdgesBtn; //3
3383 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3384 aDoubleFacesBtn->setIcon(aComputeIcon);
3385 myButtons << aDoubleFacesBtn; //4
3387 QToolButton* aOverContFacesBtn = new QToolButton( this );
3388 aOverContFacesBtn->setIcon(aComputeIcon);
3389 myButtons << aOverContFacesBtn; //5
3391 QToolButton* aComputeFaceBtn = new QToolButton( this );
3392 aComputeFaceBtn->setIcon(aComputeIcon);
3393 myButtons << aComputeFaceBtn; //6
3395 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3396 aDoubleVolumesBtn->setIcon(aComputeIcon);
3397 myButtons << aDoubleVolumesBtn; //7
3399 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3400 aOverContVolumesBtn->setIcon(aComputeIcon);
3401 myButtons << aOverContVolumesBtn; //8
3403 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3404 aComputeVolumeBtn->setIcon(aComputeIcon);
3405 myButtons << aComputeVolumeBtn; //9
3407 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ));
3408 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ));
3409 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ));
3410 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ));
3411 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ));
3412 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ));
3413 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ));
3414 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ));
3415 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ));
3416 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ));
3417 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3419 setFontAttributes( aNameLab );
3420 setFontAttributes( aNodesLab );
3421 setFontAttributes( anEdgesLab );
3422 setFontAttributes( aFacesLab );
3423 setFontAttributes( aVolumesLab );
3425 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3426 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3427 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3428 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3429 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3430 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3431 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3432 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3433 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3434 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3435 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3436 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3437 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3438 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3439 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3440 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3441 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3442 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3443 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3444 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3445 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3446 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3447 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3448 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3449 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3450 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3451 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3452 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3453 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3454 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3455 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3456 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3457 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3458 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3459 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3460 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3461 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3462 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3464 myMainLayout->setColumnStretch( 0, 0 );
3465 myMainLayout->setColumnStretch( 1, 5 );
3466 myMainLayout->setRowStretch ( 11, 5 );
3467 myMainLayout->setRowStretch ( 16, 5 );
3468 myMainLayout->setRowStretch ( 17, 1 );
3476 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3480 \brief Change widget font attributes (bold, ...).
3482 \param attr font attributes (XORed flags)
3484 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3487 QFont f = w->font();
3494 \brief Create info field
3495 \return new info field
3497 QLabel* SMESHGUI_CtrlInfo::createField()
3499 QLabel* lab = new QLabel( this );
3500 lab->setFrameStyle( StyledPanel | Sunken );
3501 lab->setAlignment( Qt::AlignCenter );
3502 lab->setAutoFillBackground( true );
3503 QPalette pal = lab->palette();
3504 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
3505 lab->setPalette( pal );
3506 lab->setMinimumWidth( 60 );
3511 \brief Create QwtPlot
3514 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3516 QwtPlot* aPlot = new QwtPlot( parent );
3517 aPlot->setMinimumSize( 100, 100 );
3518 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3519 xFont.setPointSize( 5 );
3520 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3521 yFont.setPointSize( 5 );
3522 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3523 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3529 \brief Show controls information on the selected object
3531 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3535 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3536 if ( myObject->_is_nil() ) return;
3538 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3539 myWidgets[0]->setText( aSO->GetName().c_str() );
3541 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3542 if ( mesh->_is_nil() ) return;
3544 const bool meshLoaded = mesh->IsLoaded();
3545 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3546 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3547 for ( int i = 0; i < myButtons.count(); ++i )
3548 myButtons[i]->setEnabled( true );
3550 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3551 if ( ! &nbElemsByType.in() ) return;
3553 const CORBA::Long ctrlLimit =
3554 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3557 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3558 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3559 nbElemsByType[ SMESH::FACE ] +
3560 nbElemsByType[ SMESH::VOLUME ] );
3561 if ( nbNodes + nbElems > 0 ) {
3562 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3564 computeFreeNodesInfo();
3565 computeNodesNbConnInfo();
3567 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3568 computeDoubleNodesInfo();
3571 myButtons[0]->setEnabled( true );
3572 myButtons[1]->setEnabled( true );
3573 myButtons[2]->setEnabled( true );
3577 for( int i=2; i<=11; i++)
3578 myMainLayout->itemAt(i)->widget()->setVisible( false );
3582 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3584 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3585 computeDoubleEdgesInfo();
3587 myButtons[3]->setEnabled( true );
3590 for( int i=11; i<=14; i++)
3591 myMainLayout->itemAt(i)->widget()->setVisible( false );
3595 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3596 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3598 computeDoubleFacesInfo();
3599 // over constrained faces
3600 computeOverConstrainedFacesInfo();
3601 // aspect Ratio histogram
3602 computeAspectRatio();
3605 myButtons[4]->setEnabled( true );
3606 myButtons[5]->setEnabled( true );
3607 myButtons[6]->setEnabled( true );
3609 #ifdef DISABLE_PLOT2DVIEWER
3610 myMainLayout->setRowStretch(12,0);
3611 for( int i=25; i<=27; i++)
3612 myMainLayout->itemAt(i)->widget()->setVisible( false );
3616 myMainLayout->setRowStretch(12,0);
3617 for( int i=18; i<=27; i++)
3618 myMainLayout->itemAt(i)->widget()->setVisible( false );
3622 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3623 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3625 computeDoubleVolumesInfo();
3626 // over constrained volumes
3627 computeOverConstrainedVolumesInfo();
3628 // aspect Ratio 3D histogram
3629 computeAspectRatio3D();
3632 myButtons[7]->setEnabled( true );
3633 myButtons[8]->setEnabled( true );
3634 myButtons[9]->setEnabled( true );
3636 #ifdef DISABLE_PLOT2DVIEWER
3637 myMainLayout->setRowStretch(17,0);
3638 for( int i=35; i<=37; i++)
3639 myMainLayout->itemAt(i)->widget()->setVisible( false );
3643 myMainLayout->setRowStretch(17,0);
3644 for( int i=28; i<=37; i++)
3645 myMainLayout->itemAt(i)->widget()->setVisible( false );
3649 //================================================================================
3651 * \brief Computes and shows nb of elements satisfying a given predicate
3652 * \param [in] ft - a predicate type (SMESH::FunctorType)
3653 * \param [in] iBut - index of one of myButtons to disable
3654 * \param [in] iWdg - index of one of myWidgets to show the computed number
3656 //================================================================================
3658 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3660 myButtons[ iBut ]->setEnabled( false );
3661 myWidgets[ iWdg ]->setText( "" );
3662 if ( myObject->_is_nil() ) return;
3664 SUIT_OverrideCursor wc;
3666 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3667 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3670 this->showInfo( myObject ); // try to show all values
3671 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3672 return; // <ft> predicate already computed
3674 // look for a predicate of type <ft>
3675 for ( int i = 0; i < myPredicates.count(); ++i )
3676 if ( myPredicates[i]->GetFunctorType() == ft )
3678 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3679 myWidgets[ iWdg ]->setText( QString::number( nb ));
3683 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3685 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3688 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3690 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3693 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3695 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3698 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3700 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3703 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3705 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3708 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3710 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3713 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3715 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3718 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3720 myButtons[ 1 ]->setEnabled( false );
3721 myWidgets[ 2 ]->setText( "" );
3722 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3723 if ( mesh->_is_nil() ) return;
3724 if ( !mesh->IsLoaded() )
3727 this->showInfo( myObject ); // try to show all values
3728 if ( !myWidgets[ 2 ]->text().isEmpty() )
3729 return; // already computed
3731 myNodeConnFunctor->SetMesh( mesh );
3732 SMESH::Histogram_var histogram =
3733 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3735 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3738 void SMESHGUI_CtrlInfo::computeAspectRatio()
3740 #ifndef DISABLE_PLOT2DVIEWER
3741 myButtons[6]->setEnabled( false );
3743 if ( myObject->_is_nil() ) return;
3745 SUIT_OverrideCursor wc;
3747 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3748 if ( aHistogram && !aHistogram->isEmpty() ) {
3749 QwtPlotItem* anItem = aHistogram->createPlotItem();
3750 anItem->attach( myPlot );
3757 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3759 #ifndef DISABLE_PLOT2DVIEWER
3760 myButtons[9]->setEnabled( false );
3762 if ( myObject->_is_nil() ) return;
3764 SUIT_OverrideCursor wc;
3766 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3767 if ( aHistogram && !aHistogram->isEmpty() ) {
3768 QwtPlotItem* anItem = aHistogram->createPlotItem();
3769 anItem->attach( myPlot3D );
3777 \brief Internal clean-up (reset widget)
3779 void SMESHGUI_CtrlInfo::clearInternal()
3781 for( int i=0; i<=35; i++)
3782 myMainLayout->itemAt(i)->widget()->setVisible( true );
3783 for( int i=0; i<=9; i++)
3784 myButtons[i]->setEnabled( false );
3785 myPlot->detachItems();
3786 myPlot3D->detachItems();
3789 myWidgets[0]->setText( QString() );
3790 for ( int i = 1; i < myWidgets.count(); i++ )
3791 myWidgets[i]->setText( "" );
3792 myMainLayout->setRowStretch(11,5);
3793 myMainLayout->setRowStretch(16,5);
3796 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3798 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3799 myButtons[1]->setEnabled( true );
3800 myWidgets[2]->setText("");
3803 #ifndef DISABLE_PLOT2DVIEWER
3804 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3806 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3807 if ( mesh->_is_nil() ) return 0;
3808 if ( !mesh->IsLoaded() )
3810 aNumFun->SetMesh( mesh );
3812 CORBA::Long cprecision = 6;
3813 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
3814 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3815 aNumFun->SetPrecision( cprecision );
3817 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3819 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3820 /*isLogarithmic=*/false,
3822 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3823 aHistogram->setColor( palette().color( QPalette::Highlight ));
3824 if ( &histogramVar.in() )
3826 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3827 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3828 if ( histogramVar->length() >= 2 )
3829 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3835 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3836 out << QString( 20, '-' ) << "\n";
3837 out << tr( "CTRL_INFO" ) << "\n";
3838 out << QString( 20, '-' ) << "\n";
3839 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3840 out << tr( "NODES_INFO" ) << "\n";
3841 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3842 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3843 out << tr( "EDGES_INFO" ) << "\n";
3844 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3845 out << tr( "FACES_INFO" ) << "\n";
3846 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3847 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3848 out << tr( "VOLUMES_INFO" ) << "\n";
3849 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3850 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3854 \class SMESHGUI_CtrlInfoDlg
3855 \brief Controls information dialog box
3860 \param parent parent widget
3862 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3865 setAttribute( Qt::WA_DeleteOnClose, true );
3866 setWindowTitle( tr( "CTRL_INFO" ));
3867 setMinimumSize( 400, 600 );
3869 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3872 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3873 okBtn->setAutoDefault( true );
3874 okBtn->setDefault( true );
3876 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3877 dumpBtn->setAutoDefault( true );
3878 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3879 helpBtn->setAutoDefault( true );
3881 QHBoxLayout* btnLayout = new QHBoxLayout;
3882 btnLayout->setSpacing( SPACING );
3883 btnLayout->setMargin( 0 );
3885 btnLayout->addWidget( okBtn );
3886 btnLayout->addWidget( dumpBtn );
3887 btnLayout->addStretch( 10 );
3888 btnLayout->addWidget( helpBtn );
3890 QVBoxLayout* l = new QVBoxLayout ( this );
3891 l->setMargin( MARGIN );
3892 l->setSpacing( SPACING );
3893 l->addWidget( myCtrlInfo );
3894 l->addLayout( btnLayout );
3896 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
3897 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
3898 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
3899 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
3900 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
3908 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3913 \brief Show controls information
3914 \param IO interactive object
3916 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3918 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ))
3919 myCtrlInfo->showInfo( obj );
3923 \brief Perform clean-up actions on the dialog box closing.
3925 void SMESHGUI_CtrlInfoDlg::reject()
3927 SMESH::SetPointRepresentation( false );
3932 \brief Setup selection mode depending on the current dialog box state.
3934 void SMESHGUI_CtrlInfoDlg::updateSelection()
3936 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3937 disconnect( selMgr, 0, this, 0 );
3938 SMESH::SetPointRepresentation( false );
3939 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3944 \brief Show mesh information
3946 void SMESHGUI_CtrlInfoDlg::updateInfo()
3948 SUIT_OverrideCursor wc;
3950 SALOME_ListIO selected;
3951 SMESHGUI::selectionMgr()->selectedObjects( selected );
3953 if ( selected.Extent() == 1 ) {
3954 Handle(SALOME_InteractiveObject) IO = selected.First();
3960 \brief Activate dialog box
3962 void SMESHGUI_CtrlInfoDlg::activate()
3964 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3965 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3970 \brief Deactivate dialog box
3972 void SMESHGUI_CtrlInfoDlg::deactivate()
3974 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3978 * \brief Dump contents into a file
3980 void SMESHGUI_CtrlInfoDlg::dump()
3982 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3984 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3985 if ( !appStudy ) return;
3986 _PTR( Study ) aStudy = appStudy->studyDS();
3988 QStringList aFilters;
3989 aFilters.append( tr( "TEXT_FILES" ));
3991 DumpFileDlg fd( this );
3992 fd.setWindowTitle( tr( "SAVE_INFO" ));
3993 fd.setNameFilters( aFilters );
3994 fd.myBaseChk->hide();
3995 fd.myElemChk->hide();
3996 fd.myAddChk ->hide();
3997 fd.myCtrlChk->hide();
3998 if ( fd.exec() == QDialog::Accepted )
4000 QString aFileName = fd.selectedFile();
4001 if ( !aFileName.isEmpty() ) {
4002 QFileInfo aFileInfo( aFileName );
4003 if ( aFileInfo.isDir() )
4006 QFile aFile( aFileName );
4007 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
4010 QTextStream out( &aFile );
4011 myCtrlInfo->saveInfo( out );
4019 void SMESHGUI_CtrlInfoDlg::help()
4021 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");