1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESHGUI_MeshInfo.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_MeshInfo.h"
27 #include "SMDSAbs_ElementType.hxx"
28 #include "SMDS_BallElement.hxx"
29 #include "SMDS_EdgePosition.hxx"
30 #include "SMDS_FacePosition.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_VolumeTool.hxx"
33 #include "SMESHDS_Mesh.hxx"
35 #include "SMESHGUI_FilterUtils.h"
36 #include "SMESHGUI_IdValidator.h"
37 #include "SMESHGUI_SpinBox.h"
38 #include "SMESHGUI_Utils.h"
39 #include "SMESHGUI_VTKUtils.h"
40 #include "SMESH_Actor.h"
42 #include <LightApp_SelectionMgr.h>
43 #include <SUIT_FileDlg.h>
44 #include <SUIT_OverrideCursor.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SVTK_ViewWindow.h>
49 #include <SALOMEDSClient_Study.hxx>
50 #include <SalomeApp_Study.h>
52 #include <QApplication>
53 #include <QButtonGroup>
55 #include <QContextMenuEvent>
56 #include <QGridLayout>
57 #include <QHBoxLayout>
58 #include <QHeaderView>
59 #include <QItemDelegate>
64 #include <QPushButton>
65 #include <QToolButton>
66 #include <QRadioButton>
67 #include <QTextStream>
69 #include <QTextBrowser>
70 #include <QVBoxLayout>
72 #include "utilities.h"
74 #include <SALOMEconfig.h>
75 #include CORBA_SERVER_HEADER(GEOM_Gen)
79 const int SPACING = 6;
81 const int MAXITEMS = 10;
82 const int GROUPS_ID = 100;
83 const int SUBMESHES_ID = 200;
84 const int SPACING_INFO = 2;
87 TypeRole = Qt::UserRole + 10,
92 NodeConnectivity = 100,
101 class ExtraWidget : public QWidget
104 ExtraWidget( QWidget*, bool = false );
107 void updateControls( int, int, int = MAXITEMS );
116 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
118 current = new QLabel( this );
119 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
120 prev = new QPushButton( tr( "<<" ), this );
121 next = new QPushButton( tr( ">>" ), this );
122 QHBoxLayout* hbl = new QHBoxLayout( this );
123 hbl->setContentsMargins( 0, SPACING, 0, 0 );
124 hbl->setSpacing( SPACING );
126 hbl->addWidget( current );
127 hbl->addWidget( prev );
128 hbl->addWidget( next );
131 ExtraWidget::~ExtraWidget()
135 void ExtraWidget::updateControls( int total, int index, int blockSize )
137 setVisible( total > blockSize );
138 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
139 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) );
140 prev->setEnabled( index > 0 );
141 next->setEnabled( (index+1)*blockSize < total );
146 \brief Customization of standard "Save file" dialog box for dump info operation
150 class DumpFileDlg : public SUIT_FileDlg
153 DumpFileDlg( QWidget* parent );
155 QCheckBox* myBaseChk;
156 QCheckBox* myElemChk;
158 QCheckBox* myCtrlChk;
165 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
167 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
169 QWidget* hB = new QWidget( this );
170 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
171 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
172 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
173 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
175 QGridLayout* layout = new QGridLayout( hB );
176 layout->addWidget( myBaseChk, 0, 0 );
177 layout->addWidget( myElemChk, 0, 1 );
178 layout->addWidget( myAddChk, 1, 0 );
179 layout->addWidget( myCtrlChk, 1, 1 );
181 QPushButton* pb = new QPushButton( this );
183 int row = grid->rowCount();
184 grid->addWidget( new QLabel( "", this ), row, 0 );
185 grid->addWidget( hB, row, 1, 1, 3 );
186 grid->addWidget( pb, row, 5 );
193 \brief Get depth of the tree item
195 \param theItem tree widget item
196 \return item's depth in tree widget (where top-level items have zero depth)
198 static int itemDepth( QTreeWidgetItem* item )
201 QTreeWidgetItem* p = item->parent();
210 \class SMESHGUI_MeshInfo
211 \brief Base mesh information widget
213 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
218 \param parent parent widget
220 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
221 : QFrame( parent ), myWidgets( iElementsEnd )
223 setFrameStyle( StyledPanel | Sunken );
225 QGridLayout* l = new QGridLayout( this );
226 l->setMargin( MARGIN );
227 l->setSpacing( SPACING );
232 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
233 QLabel* aName = createField();
234 aName->setObjectName("meshName");
235 aName->setMinimumWidth( 150 );
236 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
237 QLabel* aObj = createField();
238 aObj->setObjectName("meshType");
239 aObj->setMinimumWidth( 150 );
240 myWidgets[ index++ ] << aNameLab << aName;
241 myWidgets[ index++ ] << aObjLab << aObj;
244 QWidget* aNodesLine = createLine();
245 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
246 QLabel* aNodes = createField();
247 aNodes->setObjectName("nbNodes");
248 myWidgets[ index++ ] << aNodesLine;
249 myWidgets[ index++ ] << aNodesLab << aNodes;
252 QWidget* aElemLine = createLine();
253 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
254 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
255 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
256 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
257 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
258 myWidgets[ index++ ] << aElemLine;
259 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
261 // ... Number elements
262 QWidget* aNbLine = createLine();
263 QLabel* aNbTotal = createField();
264 aNbTotal->setObjectName("totalNbElems");
265 QLabel* aNbLin = createField();
266 aNbLin->setObjectName("totalNbLinearElems");
267 QLabel* aNbQuad = createField();
268 aNbQuad->setObjectName("totalNbQuadraticElems");
269 QLabel* aNbBiQuad = createField();
270 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
271 myWidgets[ index++ ] << aNbLine;
272 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
275 QWidget* a0DLine = createLine();
276 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
277 QLabel* a0DTotal = createField();
278 a0DTotal->setObjectName("nb0D");
280 myWidgets[ index++ ] << a0DLine;
281 myWidgets[ index++ ] << a0DLab << a0DTotal;
284 QWidget* aBallLine = createLine();
285 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
286 QLabel* aBallTotal = createField();
287 aBallTotal->setObjectName("nbBall");
288 myWidgets[ index++ ] << aBallLine;
289 myWidgets[ index++ ] << aBallLab << aBallTotal;
292 QWidget* a1DLine = createLine();
293 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
294 QLabel* a1DTotal = createField();
295 a1DTotal->setObjectName("nb1D");
296 QLabel* a1DLin = createField();
297 a1DLin->setObjectName("nbLinear1D");
298 QLabel* a1DQuad = createField();
299 a1DQuad->setObjectName("nbQuadratic1D");
300 myWidgets[ index++ ] << a1DLine;
301 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
304 QWidget* a2DLine = createLine();
305 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
306 QLabel* a2DTotal = createField();
307 a2DTotal->setObjectName("nb2D");
308 QLabel* a2DLin = createField();
309 a2DLin->setObjectName("nbLinear2D");
310 QLabel* a2DQuad = createField();
311 a2DQuad->setObjectName("nbQuadratic2D");
312 QLabel* a2DBiQuad = createField();
313 a2DBiQuad->setObjectName("nbBiQuadratic2D");
314 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
315 QLabel* a2DTriTotal = createField();
316 a2DTriTotal->setObjectName("nbTriangle");
317 QLabel* a2DTriLin = createField();
318 a2DTriLin->setObjectName("nbLinearTriangle");
319 QLabel* a2DTriQuad = createField();
320 a2DTriQuad->setObjectName("nbQuadraticTriangle");
321 QLabel* a2DTriBiQuad = createField();
322 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
323 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
324 QLabel* a2DQuaTotal = createField();
325 a2DQuaTotal->setObjectName("nbQuadrangle");
326 QLabel* a2DQuaLin = createField();
327 a2DQuaLin->setObjectName("nbLinearQuadrangle");
328 QLabel* a2DQuaQuad = createField();
329 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
330 QLabel* a2DQuaBiQuad = createField();
331 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
332 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
333 QLabel* a2DPolTotal = createField();
334 a2DPolTotal->setObjectName("nbPolygon");
335 QLabel* a2DPolLin = createField();
336 a2DPolLin->setObjectName("nbLinearPolygon");
337 QLabel* a2DPolQuad = createField();
338 a2DPolQuad->setObjectName("nbQuadraticPolygon");
339 myWidgets[ index++ ] << a2DLine;
340 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
341 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
342 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
343 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
346 QWidget* a3DLine = createLine();
347 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
348 QLabel* a3DTotal = createField();
349 a3DTotal->setObjectName("nb3D");
350 QLabel* a3DLin = createField();
351 a3DLin->setObjectName("nbLinear3D");
352 QLabel* a3DQuad = createField();
353 a3DQuad->setObjectName("nbQuadratic3D");
354 QLabel* a3DBiQuad = createField();
355 a3DBiQuad->setObjectName("nbBiQuadratic3D");
356 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
357 QLabel* a3DTetTotal = createField();
358 a3DTetTotal->setObjectName("nbTetrahedron");
359 QLabel* a3DTetLin = createField();
360 a3DTetLin->setObjectName("nbLinearTetrahedron");
361 QLabel* a3DTetQuad = createField();
362 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
363 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
364 QLabel* a3DHexTotal = createField();
365 a3DHexTotal->setObjectName("nbHexahedron");
366 QLabel* a3DHexLin = createField();
367 a3DHexLin->setObjectName("nbLinearHexahedron");
368 QLabel* a3DHexQuad = createField();
369 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
370 QLabel* a3DHexBiQuad = createField();
371 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
372 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
373 QLabel* a3DPyrTotal = createField();
374 a3DPyrTotal->setObjectName("nbPyramid");
375 QLabel* a3DPyrLin = createField();
376 a3DPyrLin->setObjectName("nbLinearPyramid");
377 QLabel* a3DPyrQuad = createField();
378 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
379 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
380 QLabel* a3DPriTotal = createField();
381 a3DPriTotal->setObjectName("nbPrism");
382 QLabel* a3DPriLin = createField();
383 a3DPriLin->setObjectName("nbLinearPrism");
384 QLabel* a3DPriQuad = createField();
385 a3DPriQuad->setObjectName("nbQuadraticPrism");
386 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
387 QLabel* a3DHexPriTotal = createField();
388 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
389 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
390 QLabel* a3DPolTotal = createField();
391 a3DPolTotal->setObjectName("nbPolyhedron");
392 myWidgets[ index++ ] << a3DLine;
393 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
394 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
395 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
396 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
397 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
398 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
399 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
401 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
402 myLoadBtn->setAutoDefault( true );
403 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
405 setFontAttributes( aNameLab, Bold );
406 setFontAttributes( aObjLab, Bold );
407 setFontAttributes( aNodesLab, Bold );
408 setFontAttributes( aElemLab, Bold );
409 setFontAttributes( aElemTotal, Italic );
410 setFontAttributes( aElemLin, Italic );
411 setFontAttributes( aElemQuad, Italic );
412 setFontAttributes( aElemBiQuad, Italic );
413 setFontAttributes( a0DLab, Bold );
414 setFontAttributes( aBallLab, Bold );
415 setFontAttributes( a1DLab, Bold );
416 setFontAttributes( a2DLab, Bold );
417 setFontAttributes( a3DLab, Bold );
419 l->addWidget( aNameLab, 0, 0 );
420 l->addWidget( aName, 0, 1, 1, 4 );
421 l->addWidget( aObjLab, 1, 0 );
422 l->addWidget( aObj, 1, 1, 1, 4 );
423 l->addWidget( aNodesLine, 2, 0, 1, 5 );
424 l->addWidget( aNodesLab, 3, 0 );
425 l->addWidget( aNodes, 3, 1 );
426 l->addWidget( aElemLine, 4, 0, 1, 5 );
427 l->addWidget( aElemLab, 5, 0 );
428 l->addWidget( aElemTotal, 5, 1 );
429 l->addWidget( aElemLin, 5, 2 );
430 l->addWidget( aElemQuad, 5, 3 );
431 l->addWidget( aElemBiQuad, 5, 4 );
432 l->addWidget( aNbLine, 6, 1, 1, 4 );
433 l->addWidget( aNbTotal, 7, 1 );
434 l->addWidget( aNbLin, 7, 2 );
435 l->addWidget( aNbQuad, 7, 3 );
436 l->addWidget( aNbBiQuad, 7, 4 );
437 l->addWidget( a0DLine, 8, 1, 1, 4 );
438 l->addWidget( a0DLab, 9, 0 );
439 l->addWidget( a0DTotal, 9, 1 );
440 l->addWidget( aBallLine, 10, 1, 1, 4 );
441 l->addWidget( aBallLab, 11, 0 );
442 l->addWidget( aBallTotal, 11, 1 );
443 l->addWidget( a1DLine, 12, 1, 1, 4 );
444 l->addWidget( a1DLab, 13, 0 );
445 l->addWidget( a1DTotal, 13, 1 );
446 l->addWidget( a1DLin, 13, 2 );
447 l->addWidget( a1DQuad, 13, 3 );
448 l->addWidget( a2DLine, 14, 1, 1, 4 );
449 l->addWidget( a2DLab, 15, 0 );
450 l->addWidget( a2DTotal, 15, 1 );
451 l->addWidget( a2DLin, 15, 2 );
452 l->addWidget( a2DQuad, 15, 3 );
453 l->addWidget( a2DBiQuad, 15, 4 );
454 l->addWidget( a2DTriLab, 16, 0 );
455 l->addWidget( a2DTriTotal, 16, 1 );
456 l->addWidget( a2DTriLin, 16, 2 );
457 l->addWidget( a2DTriQuad, 16, 3 );
458 l->addWidget( a2DTriBiQuad, 16, 4 );
459 l->addWidget( a2DQuaLab, 17, 0 );
460 l->addWidget( a2DQuaTotal, 17, 1 );
461 l->addWidget( a2DQuaLin, 17, 2 );
462 l->addWidget( a2DQuaQuad, 17, 3 );
463 l->addWidget( a2DQuaBiQuad, 17, 4 );
464 l->addWidget( a2DPolLab, 18, 0 );
465 l->addWidget( a2DPolTotal, 18, 1 );
466 l->addWidget( a2DPolLin, 18, 2 );
467 l->addWidget( a2DPolQuad, 18, 3 );
468 l->addWidget( a3DLine, 19, 1, 1, 4 );
469 l->addWidget( a3DLab, 20, 0 );
470 l->addWidget( a3DTotal, 20, 1 );
471 l->addWidget( a3DLin, 20, 2 );
472 l->addWidget( a3DQuad, 20, 3 );
473 l->addWidget( a3DBiQuad, 20, 4 );
474 l->addWidget( a3DTetLab, 21, 0 );
475 l->addWidget( a3DTetTotal, 21, 1 );
476 l->addWidget( a3DTetLin, 21, 2 );
477 l->addWidget( a3DTetQuad, 21, 3 );
478 l->addWidget( a3DHexLab, 22, 0 );
479 l->addWidget( a3DHexTotal, 22, 1 );
480 l->addWidget( a3DHexLin, 22, 2 );
481 l->addWidget( a3DHexQuad, 22, 3 );
482 l->addWidget( a3DHexBiQuad, 22, 4 );
483 l->addWidget( a3DPyrLab, 23, 0 );
484 l->addWidget( a3DPyrTotal, 23, 1 );
485 l->addWidget( a3DPyrLin, 23, 2 );
486 l->addWidget( a3DPyrQuad, 23, 3 );
487 l->addWidget( a3DPriLab, 24, 0 );
488 l->addWidget( a3DPriTotal, 24, 1 );
489 l->addWidget( a3DPriLin, 24, 2 );
490 l->addWidget( a3DPriQuad, 24, 3 );
491 l->addWidget( a3DHexPriLab, 25, 0 );
492 l->addWidget( a3DHexPriTotal, 25, 1 );
493 l->addWidget( a3DPolLab, 26, 0 );
494 l->addWidget( a3DPolTotal, 26, 1 );
495 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
497 l->setColumnStretch( 0, 0 );
498 l->setColumnStretch( 1, 5 );
499 l->setColumnStretch( 2, 5 );
500 l->setColumnStretch( 3, 5 );
501 l->setColumnStretch( 4, 5 );
502 l->setRowStretch( 27, 5 );
510 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
515 \brief Show information on the mesh object.
516 \param obj object being processed (mesh, sub-mesh, group, ID source)
518 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
521 if ( !CORBA::is_nil( obj ) ) {
522 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
524 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
525 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
526 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
527 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
528 if ( !aMesh->_is_nil() ) {
529 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
531 else if ( !aSubMesh->_is_nil() ) {
532 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
534 else if ( !aGroup->_is_nil() ) {
536 switch( aGroup->GetType() ) {
537 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
538 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
539 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
540 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
541 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
542 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
543 default: objType = tr( "OBJECT_GROUP" );break;
545 myWidgets[iObject][iSingle]->setProperty( "text", objType );
547 SMESH::long_array_var info = obj->GetMeshInfo();
548 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
549 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
550 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
551 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
552 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
553 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
554 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
555 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
556 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
557 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
558 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
559 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
560 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
561 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
563 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
564 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
565 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
566 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
567 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
568 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
569 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
570 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
571 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
572 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
573 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
574 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
575 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
576 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
577 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
578 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
579 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
580 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
581 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
582 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
583 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
584 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
585 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
586 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
587 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
588 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
589 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
590 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
591 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
592 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
593 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
594 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
595 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
596 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
597 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
598 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
599 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
600 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
601 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
602 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
603 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
604 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
605 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
606 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
607 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
608 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
609 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
610 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
611 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
612 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
613 // before full loading from study file, type of elements in a sub-mesh can't be defined
615 bool infoOK = obj->IsMeshInfoCorrect();
616 myLoadBtn->setVisible( !infoOK );
620 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
621 // 2. No info at all (for a group on geom or filter)
622 bool hasAnyInfo = false;
623 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
624 hasAnyInfo = info[i];
625 if ( hasAnyInfo ) // believe it is a sub-mesh
627 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
629 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
630 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
631 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
632 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
633 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
634 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
635 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
636 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
637 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
638 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
640 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
643 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
644 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
645 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
648 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
650 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
651 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
652 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
653 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
654 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
655 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
656 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
661 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
662 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
667 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
668 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
669 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
670 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
671 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
676 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
677 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
678 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
679 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
681 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
682 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
683 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
684 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
685 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
686 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
687 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
688 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
690 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
691 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
692 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
694 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
695 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
696 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
697 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
698 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
699 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
700 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
703 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
704 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
706 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
707 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
712 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
713 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
714 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
715 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
716 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
723 \brief Load mesh from a study file
725 void SMESHGUI_MeshInfo::loadMesh()
727 SUIT_OverrideCursor wc;
729 SALOME_ListIO selected;
730 SMESHGUI::selectionMgr()->selectedObjects( selected );
732 if ( selected.Extent() == 1 ) {
733 Handle(SALOME_InteractiveObject) IO = selected.First();
734 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
735 if ( !CORBA::is_nil( obj ) ) {
736 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
737 if ( !mesh->_is_nil() )
747 \brief Reset the widget to the initial state (nullify all fields).
749 void SMESHGUI_MeshInfo::clear()
751 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
752 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
753 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
754 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
755 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
756 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
757 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
758 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
759 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
760 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
761 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
762 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
763 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
764 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
765 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
766 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
767 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
768 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
769 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
770 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
771 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ) );
772 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
773 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
774 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
775 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
776 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
777 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
778 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
779 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
780 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
781 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
782 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
783 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
784 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
785 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
786 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
787 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
788 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
789 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
790 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
791 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
792 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
793 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
794 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
795 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
796 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
800 \brief Create info field
801 \return new info field
803 QLabel* SMESHGUI_MeshInfo::createField()
805 QLabel* lab = new QLabel( this );
806 lab->setFrameStyle( StyledPanel | Sunken );
807 lab->setAlignment( Qt::AlignCenter );
808 lab->setAutoFillBackground( true );
809 QPalette pal = lab->palette();
810 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
811 lab->setPalette( pal );
812 lab->setMinimumWidth( 70 );
817 \brief Create horizontal rule.
818 \return new line object
820 QWidget* SMESHGUI_MeshInfo::createLine()
822 QFrame* line = new QFrame( this );
823 line->setFrameStyle( HLine | Sunken );
828 \brief Change widget font attributes (bold, italic, ...).
830 \param attr font attributes (XORed flags)
831 \param val value to be set to attributes
833 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
837 if ( attr & Bold ) f.setBold( val );
838 if ( attr & Italic ) f.setItalic( val );
844 \brief Show/hide group(s) of fields.
845 \param start beginning of the block
846 \param end end of the block
847 \param on visibility flag
849 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
851 start = qMax( 0, start );
852 end = qMin( end, (int)iElementsEnd );
853 for ( int i = start; i < end; i++ ) {
854 wlist wl = myWidgets[i];
855 foreach ( QWidget* w, wl ) w->setVisible( on );
859 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
861 out << QString( 9, '-' ) << "\n";
862 out << tr( "BASE_INFO" ) << "\n";
863 out << QString( 9, '-' ) << "\n";
864 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
865 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
866 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
867 out << tr( "ELEMENTS_LAB" ) << "\n";
868 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
869 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
870 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
871 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
872 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
873 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
874 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
875 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
876 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
877 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
878 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
879 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
880 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
881 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
883 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
886 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
887 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
888 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
889 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
890 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
891 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
895 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
899 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
900 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
901 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
903 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
904 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
906 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
907 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
909 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
910 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
911 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
913 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
915 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
917 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
920 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
921 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
923 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
924 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
928 \class SMESHGUI_ElemInfo
929 \brief Base class for the mesh element information widget.
934 \param parent parent widget
936 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
937 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
939 myFrame = new QWidget( this );
940 myExtra = new ExtraWidget( this );
941 QVBoxLayout* vbl = new QVBoxLayout( this );
943 vbl->setSpacing( 0 );
944 vbl->addWidget( myFrame );
945 vbl->addWidget( myExtra );
946 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
947 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
954 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
959 \brief Set mesh data source (actor)
960 \param actor mesh object actor
962 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
964 if ( myActor != actor ) {
972 \brief Show mesh element information
973 \param id mesh node / element ID
974 \param isElem show mesh element information if \c true or mesh node information if \c false
976 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
980 showInfo( ids, isElem );
984 \brief Show mesh element information
985 \param ids mesh nodes / elements identifiers
986 \param isElem show mesh element information if \c true or mesh node information if \c false
988 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
990 QList<long> newIds = ids.toList();
992 if ( myIDs == newIds && myIsElement == isElem ) return;
995 myIsElement = isElem;
998 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1002 \brief Clear mesh element information widget
1004 void SMESHGUI_ElemInfo::clear()
1013 \brief Get central area widget
1014 \return central widget
1016 QWidget* SMESHGUI_ElemInfo::frame() const
1023 \return actor being used
1025 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1031 \brief Get current info mode.
1032 \return \c true if mesh element information is shown or \c false if node information is shown
1034 bool SMESHGUI_ElemInfo::isElements() const
1040 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1041 \brief Show information on the specified nodes / elements
1043 This function is to be redefined in sub-classes.
1045 \param ids nodes / elements identifiers information is to be shown on
1049 \brief Internal clean-up (reset widget)
1051 void SMESHGUI_ElemInfo::clearInternal()
1056 \brief Get node connectivity
1057 \param node mesh node
1058 \return node connectivity map
1060 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1064 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1065 while ( it && it->more() ) {
1066 const SMDS_MeshElement* ne = it->next();
1067 elmap[ ne->GetType() ] << ne->GetID();
1074 \brief Format connectivity data to string representation
1075 \param connectivity connetivity map
1076 \param type element type
1077 \return string representation of the connectivity
1079 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1082 if ( connectivity.contains( type ) ) {
1083 QList<int> elements = connectivity[ type ];
1085 foreach( int id, elements )
1086 str << QString::number( id );
1088 return str.join( " " );
1092 \brief Calculate gravity center of the mesh element
1093 \param element mesh element
1095 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1099 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1100 while ( nodeIt->more() ) {
1101 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1102 xyz.add( node->X(), node->Y(), node->Z() );
1104 xyz.divide( element->NbNodes() );
1110 \brief Calculate normal vector to the mesh face
1111 \param element mesh face
1113 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1115 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1116 return XYZ(n.X(), n.Y(), n.Z());
1120 \brief This slot is called from "Show Previous" button click.
1121 Shows information on the previous group of the items.
1123 void SMESHGUI_ElemInfo::showPrevious()
1125 myIndex = qMax( 0, myIndex-1 );
1127 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1131 \brief This slot is called from "Show Next" button click.
1132 Shows information on the next group of the items.
1134 void SMESHGUI_ElemInfo::showNext()
1136 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1138 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1142 \brief Update widgets state
1144 void SMESHGUI_ElemInfo::updateControls()
1146 myExtra->updateControls( myIDs.count(), myIndex );
1150 \class SMESHGUI_SimpleElemInfo
1151 \brief Represents mesh element information in the simple text area.
1156 \param parent parent widget
1158 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1159 : SMESHGUI_ElemInfo( parent )
1161 myInfo = new QTextBrowser( frame() );
1162 QVBoxLayout* l = new QVBoxLayout( frame() );
1164 l->addWidget( myInfo );
1168 \brief Show mesh element information
1169 \param ids mesh nodes / elements identifiers
1171 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1176 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1177 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1178 int cprecision = -1;
1179 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1180 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1181 foreach ( long id, ids ) {
1182 if ( !isElements() ) {
1186 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1187 if ( !node ) return;
1190 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1192 myInfo->append( "" );
1194 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1195 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1196 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1197 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1199 myInfo->append( "" );
1201 Connectivity connectivity = nodeConnectivity( node );
1202 if ( !connectivity.isEmpty() ) {
1203 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1204 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1205 if ( !con.isEmpty() )
1206 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1207 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1208 if ( !con.isEmpty() )
1209 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1210 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1211 if ( !con.isEmpty() )
1212 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1213 con = formatConnectivity( connectivity, SMDSAbs_Face );
1214 if ( !con.isEmpty() )
1215 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1216 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1217 if ( !con.isEmpty() )
1218 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1221 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1224 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1225 if ( !CORBA::is_nil( aMeshPtr ) ) {
1226 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1227 int shapeID = pos->shapeID;
1228 if ( shapeID > 0 ) {
1231 switch ( pos->shapeType ) {
1233 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1234 if ( pos->params.length() == 1 )
1238 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1239 if ( pos->params.length() == 2 ) {
1245 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1248 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1252 myInfo->append( "" );
1253 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1254 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1255 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1256 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1257 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1258 if ( pos->shapeType == GEOM::FACE ) {
1259 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1260 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1265 // groups node belongs to
1266 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1267 if ( !CORBA::is_nil( aMesh ) ) {
1268 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1269 myInfo->append( "" ); // separator
1270 bool top_created = false;
1271 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1272 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1273 if ( CORBA::is_nil( aGrp ) ) continue;
1274 QString aName = aGrp->GetName();
1275 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1276 if ( !top_created ) {
1277 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1280 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1281 if ( grp_details ) {
1282 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1283 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1284 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1286 // type : group on geometry, standalone group, group on filter
1287 if ( !CORBA::is_nil( aStdGroup ) ) {
1288 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1289 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1291 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1292 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1293 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1294 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1295 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1297 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1298 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1301 else if ( !CORBA::is_nil( aFltGroup ) ) {
1302 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1303 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1307 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1308 arg( QString::number( aGrp->Size() ) ) );
1311 SALOMEDS::Color color = aGrp->GetColor();
1312 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1313 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1321 // show element info
1323 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1324 SMESH::Controls::NumericalFunctorPtr afunctor;
1327 // Element ID && Type
1329 switch( e->GetType() ) {
1330 case SMDSAbs_0DElement:
1331 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1333 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1335 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1337 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1338 case SMDSAbs_Volume:
1339 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1343 if ( stype.isEmpty() ) return;
1344 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1346 myInfo->append( "" );
1350 switch( e->GetEntityType() ) {
1351 case SMDSEntity_Triangle:
1352 case SMDSEntity_Quad_Triangle:
1353 case SMDSEntity_BiQuad_Triangle:
1354 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1355 case SMDSEntity_Quadrangle:
1356 case SMDSEntity_Quad_Quadrangle:
1357 case SMDSEntity_BiQuad_Quadrangle:
1358 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1359 case SMDSEntity_Polygon:
1360 case SMDSEntity_Quad_Polygon:
1361 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1362 case SMDSEntity_Tetra:
1363 case SMDSEntity_Quad_Tetra:
1364 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1365 case SMDSEntity_Pyramid:
1366 case SMDSEntity_Quad_Pyramid:
1367 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1368 case SMDSEntity_Hexa:
1369 case SMDSEntity_Quad_Hexa:
1370 case SMDSEntity_TriQuad_Hexa:
1371 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1372 case SMDSEntity_Penta:
1373 case SMDSEntity_Quad_Penta:
1374 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1375 case SMDSEntity_Hexagonal_Prism:
1376 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1377 case SMDSEntity_Polyhedra:
1378 case SMDSEntity_Quad_Polyhedra:
1379 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1383 if ( !gtype.isEmpty() )
1384 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1386 // Quadratic flag (any element except 0D)
1387 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1388 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1390 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1392 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1395 myInfo->append( "" );
1398 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1399 for ( int idx = 1; nodeIt->more(); idx++ ) {
1400 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1401 // node number and ID
1402 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1404 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1405 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1406 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1407 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1408 // node connectivity
1409 Connectivity connectivity = nodeConnectivity( node );
1410 if ( !connectivity.isEmpty() ) {
1411 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1412 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1413 if ( !con.isEmpty() )
1414 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1415 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1416 if ( !con.isEmpty() )
1417 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1418 con = formatConnectivity( connectivity, SMDSAbs_Face );
1419 if ( !con.isEmpty() )
1420 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1421 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1422 if ( !con.isEmpty() )
1423 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1426 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1430 myInfo->append( "" );
1433 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1435 if ( e->GetType() == SMDSAbs_Edge ) {
1436 afunctor.reset( new SMESH::Controls::Length() );
1437 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1438 afunctor->SetPrecision( cprecision );
1439 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1441 if( e->GetType() == SMDSAbs_Face ) {
1443 afunctor.reset( new SMESH::Controls::Area() );
1444 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1445 afunctor->SetPrecision( cprecision );
1446 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1448 afunctor.reset( new SMESH::Controls::Taper() );
1449 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1450 afunctor->SetPrecision( cprecision );
1451 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1453 afunctor.reset( new SMESH::Controls::AspectRatio() );
1454 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1455 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1457 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1458 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1459 afunctor->SetPrecision( cprecision );
1460 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1462 afunctor.reset( new SMESH::Controls::Warping() );
1463 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1464 afunctor->SetPrecision( cprecision );
1465 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1467 afunctor.reset( new SMESH::Controls::Skew() );
1468 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1469 afunctor->SetPrecision( cprecision );
1470 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1472 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1473 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1474 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1476 if( e->GetType() == SMDSAbs_Volume ) {
1478 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1479 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1480 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1482 afunctor.reset( new SMESH::Controls::Volume() );
1483 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1484 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1486 afunctor.reset( new SMESH::Controls::Volume() );
1487 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1488 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1491 myInfo->append( "" );
1494 XYZ gc = gravityCenter( e );
1495 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1498 if( e->GetType() == SMDSAbs_Face ) {
1499 XYZ gc = normal( e );
1500 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1504 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1505 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1506 if ( !CORBA::is_nil( aMesh ) ) {
1507 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1508 int shapeID = pos.shapeID;
1509 if ( shapeID > 0 ) {
1510 myInfo->append( "" ); // separator
1512 switch ( pos.shapeType ) {
1513 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1514 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1515 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1516 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1517 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1518 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1520 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1525 // Groups the element belongs to
1526 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1527 if ( !CORBA::is_nil( aMesh ) ) {
1528 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1529 myInfo->append( "" ); // separator
1530 bool top_created = false;
1531 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1532 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1533 if ( CORBA::is_nil( aGrp ) ) continue;
1534 QString aName = aGrp->GetName();
1535 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1536 if ( !top_created ) {
1537 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1540 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1541 if ( grp_details ) {
1542 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1543 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1544 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1546 // type : group on geometry, standalone group, group on filter
1547 if ( !CORBA::is_nil( aStdGroup ) ) {
1548 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1549 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1551 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1552 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1553 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1554 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1555 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1557 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1558 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1561 else if ( !CORBA::is_nil( aFltGroup ) ) {
1562 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1563 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1566 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1567 arg( QString::number( aGrp->Size() ) ) );
1570 SALOMEDS::Color color = aGrp->GetColor();
1571 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1572 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1579 if ( ids.count() > 1 ) {
1580 myInfo->append( "" );
1581 myInfo->append( "------" );
1582 myInfo->append( "" );
1589 \brief Internal clean-up (reset widget)
1591 void SMESHGUI_SimpleElemInfo::clearInternal()
1596 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1598 out << QString( 12, '-' ) << "\n";
1599 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1600 out << QString( 12, '-' ) << "\n";
1601 out << myInfo->toPlainText();
1607 \class SMESHGUI_TreeElemInfo::ItemDelegate
1608 \brief Item delegate for tree mesh info widget
1611 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1614 ItemDelegate( QObject* );
1615 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1622 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1627 \brief Create item editor widget
1630 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1632 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1633 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1638 \class SMESHGUI_TreeElemInfo
1639 \brief Represents mesh element information in the tree-like form.
1644 \param parent parent widget
1646 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1647 : SMESHGUI_ElemInfo( parent )
1649 myInfo = new QTreeWidget( frame() );
1650 myInfo->setColumnCount( 2 );
1651 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1652 myInfo->header()->setStretchLastSection( true );
1653 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1654 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1655 QVBoxLayout* l = new QVBoxLayout( frame() );
1657 l->addWidget( myInfo );
1658 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1662 \brief Show mesh element information
1663 \param ids mesh nodes / elements identifiers
1665 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1670 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1671 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1672 int cprecision = -1;
1673 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1674 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1675 foreach ( long id, ids ) {
1676 if ( !isElements() ) {
1680 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1682 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1685 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1686 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1687 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1689 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1690 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1691 QTreeWidgetItem* xItem = createItem( coordItem );
1692 xItem->setText( 0, "X" );
1693 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1694 QTreeWidgetItem* yItem = createItem( coordItem );
1695 yItem->setText( 0, "Y" );
1696 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1697 QTreeWidgetItem* zItem = createItem( coordItem );
1698 zItem->setText( 0, "Z" );
1699 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1701 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1702 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1703 Connectivity connectivity = nodeConnectivity( node );
1704 if ( !connectivity.isEmpty() ) {
1705 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1706 if ( !con.isEmpty() ) {
1707 QTreeWidgetItem* i = createItem( conItem );
1708 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1709 i->setText( 1, con );
1711 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1712 if ( !con.isEmpty() ) {
1713 QTreeWidgetItem* i = createItem( conItem );
1714 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1715 i->setText( 1, con );
1716 i->setData( 1, TypeRole, NodeConnectivity );
1718 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1719 if ( !con.isEmpty() ) {
1720 QTreeWidgetItem* i = createItem( conItem );
1721 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1722 i->setText( 1, con );
1723 i->setData( 1, TypeRole, NodeConnectivity );
1725 con = formatConnectivity( connectivity, SMDSAbs_Face );
1726 if ( !con.isEmpty() ) {
1727 QTreeWidgetItem* i = createItem( conItem );
1728 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1729 i->setText( 1, con );
1730 i->setData( 1, TypeRole, NodeConnectivity );
1732 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1733 if ( !con.isEmpty() ) {
1734 QTreeWidgetItem* i = createItem( conItem );
1735 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1736 i->setText( 1, con );
1737 i->setData( 1, TypeRole, NodeConnectivity );
1741 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1744 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1745 if ( !CORBA::is_nil( aMeshPtr ) ) {
1746 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1747 int shapeID = pos->shapeID;
1748 if ( shapeID > 0 ) {
1751 switch ( pos->shapeType ) {
1753 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1754 if ( pos->params.length() == 1 )
1758 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1759 if ( pos->params.length() == 2 ) {
1765 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1768 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1771 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1772 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1773 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1774 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1775 QTreeWidgetItem* uItem = createItem( posItem );
1776 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1777 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1778 if ( pos->shapeType == GEOM::FACE ) {
1779 QTreeWidgetItem* vItem = createItem( posItem );
1780 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1781 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1786 // groups node belongs to
1787 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1788 if ( !CORBA::is_nil( aMesh ) ) {
1789 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1790 QTreeWidgetItem* groupsItem = 0;
1791 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1792 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1793 if ( CORBA::is_nil( aGrp ) ) continue;
1794 QString aName = aGrp->GetName();
1795 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1796 if ( !groupsItem ) {
1797 groupsItem = createItem( nodeItem, Bold );
1798 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1800 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1801 it->setText( 0, aName.trimmed() );
1802 if ( grp_details ) {
1803 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1804 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1805 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1807 // type : group on geometry, standalone group, group on filter
1808 QTreeWidgetItem* typeItem = createItem( it );
1809 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1810 if ( !CORBA::is_nil( aStdGroup ) ) {
1811 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1813 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1814 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1815 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1816 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1818 QTreeWidgetItem* gobjItem = createItem( typeItem );
1819 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1820 gobjItem->setText( 1, sobj->GetName().c_str() );
1823 else if ( !CORBA::is_nil( aFltGroup ) ) {
1824 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1828 QTreeWidgetItem* sizeItem = createItem( it );
1829 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1830 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1833 SALOMEDS::Color color = aGrp->GetColor();
1834 QTreeWidgetItem* colorItem = createItem( it );
1835 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1836 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1844 // show element info
1846 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1847 SMESH::Controls::NumericalFunctorPtr afunctor;
1850 // element ID && type
1852 switch( e->GetType() ) {
1853 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1854 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1855 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1856 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1857 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1860 if ( stype.isEmpty() ) return;
1861 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1862 elemItem->setText( 0, stype );
1863 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1866 switch( e->GetEntityType() ) {
1867 case SMDSEntity_Triangle:
1868 case SMDSEntity_Quad_Triangle:
1869 case SMDSEntity_BiQuad_Triangle:
1870 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1871 case SMDSEntity_Quadrangle:
1872 case SMDSEntity_Quad_Quadrangle:
1873 case SMDSEntity_BiQuad_Quadrangle:
1874 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1875 case SMDSEntity_Polygon:
1876 case SMDSEntity_Quad_Polygon:
1877 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1878 case SMDSEntity_Tetra:
1879 case SMDSEntity_Quad_Tetra:
1880 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1881 case SMDSEntity_Pyramid:
1882 case SMDSEntity_Quad_Pyramid:
1883 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1884 case SMDSEntity_Hexa:
1885 case SMDSEntity_Quad_Hexa:
1886 case SMDSEntity_TriQuad_Hexa:
1887 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1888 case SMDSEntity_Penta:
1889 case SMDSEntity_Quad_Penta:
1890 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1891 case SMDSEntity_Hexagonal_Prism:
1892 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1893 case SMDSEntity_Polyhedra:
1894 case SMDSEntity_Quad_Polyhedra:
1895 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1899 if ( !gtype.isEmpty() ) {
1900 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1901 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1902 typeItem->setText( 1, gtype );
1904 // quadratic flag (for edges, faces and volumes)
1905 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1907 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1908 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1909 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1911 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1913 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1914 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1915 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1918 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1919 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1922 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1923 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1924 for ( int idx = 1; nodeIt->more(); idx++ ) {
1925 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1926 nodeInfo( node, idx, e->NbNodes(), conItem );
1930 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1931 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1932 QList<const SMDS_MeshElement*> uniqueNodes;
1933 while ( nodeIt->more() )
1934 uniqueNodes.append( nodeIt->next() );
1936 SMDS_VolumeTool vtool( e );
1937 const int nbFaces = vtool.NbFaces();
1938 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1939 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1940 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1941 faceItem->setExpanded( true );
1943 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1944 const int nbNodes = vtool.NbFaceNodes( face_id );
1945 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1946 const SMDS_MeshNode* node = aNodeIds[node_id];
1947 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1952 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1953 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1955 if( e->GetType()==SMDSAbs_Edge){
1956 afunctor.reset( new SMESH::Controls::Length() );
1957 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1958 afunctor->SetPrecision( cprecision );
1959 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1960 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1961 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1963 if( e->GetType() == SMDSAbs_Face ) {
1965 afunctor.reset( new SMESH::Controls::Area() );
1966 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1967 afunctor->SetPrecision( cprecision );
1968 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1969 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1970 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1972 afunctor.reset( new SMESH::Controls::Taper() );
1973 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1974 afunctor->SetPrecision( cprecision );
1975 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1976 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1977 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1979 afunctor.reset( new SMESH::Controls::AspectRatio() );
1980 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1981 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1982 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1983 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1985 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1986 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1987 afunctor->SetPrecision( cprecision );
1988 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
1989 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
1990 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1992 afunctor.reset( new SMESH::Controls::Warping() );
1993 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1994 afunctor->SetPrecision( cprecision );
1995 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1996 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1997 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1999 afunctor.reset( new SMESH::Controls::Skew() );
2000 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2001 afunctor->SetPrecision( cprecision );
2002 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2003 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
2004 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2006 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2007 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2008 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2009 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2010 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2012 if( e->GetType() == SMDSAbs_Volume ) {
2014 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2015 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2016 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2017 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
2018 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2020 afunctor.reset( new SMESH::Controls::Volume() );
2021 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2022 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2023 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
2024 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2026 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2027 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2028 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2029 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
2030 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2034 XYZ gc = gravityCenter( e );
2035 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2036 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
2037 QTreeWidgetItem* xItem = createItem( gcItem );
2038 xItem->setText( 0, "X" );
2039 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2040 QTreeWidgetItem* yItem = createItem( gcItem );
2041 yItem->setText( 0, "Y" );
2042 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2043 QTreeWidgetItem* zItem = createItem( gcItem );
2044 zItem->setText( 0, "Z" );
2045 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2048 if( e->GetType() == SMDSAbs_Face ) {
2049 XYZ gc = normal( e );
2050 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2051 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2052 QTreeWidgetItem* xItem = createItem( nItem );
2053 xItem->setText( 0, "X" );
2054 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2055 QTreeWidgetItem* yItem = createItem( nItem );
2056 yItem->setText( 0, "Y" );
2057 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2058 QTreeWidgetItem* zItem = createItem( nItem );
2059 zItem->setText( 0, "Z" );
2060 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2064 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2065 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2066 if ( !CORBA::is_nil( aMesh ) ) {
2067 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2068 int shapeID = pos.shapeID;
2069 if ( shapeID > 0 ) {
2070 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2072 switch ( pos.shapeType ) {
2073 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2074 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2075 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2076 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2077 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2078 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2080 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2081 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2085 // groups element belongs to
2086 if ( !CORBA::is_nil( aMesh ) ) {
2087 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2088 QTreeWidgetItem* groupsItem = 0;
2089 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2090 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2091 if ( CORBA::is_nil( aGrp ) ) continue;
2092 QString aName = aGrp->GetName();
2093 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2094 if ( !groupsItem ) {
2095 groupsItem = createItem( elemItem, Bold );
2096 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2098 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2099 it->setText( 0, aName.trimmed() );
2100 if ( grp_details ) {
2101 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2102 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2103 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2105 // type : group on geometry, standalone group, group on filter
2106 QTreeWidgetItem* typeItem = createItem( it );
2107 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2108 if ( !CORBA::is_nil( aStdGroup ) ) {
2109 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2111 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2112 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2113 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2114 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2116 QTreeWidgetItem* gobjItem = createItem( typeItem );
2117 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2118 gobjItem->setText( 1, sobj->GetName().c_str() );
2121 else if ( !CORBA::is_nil( aFltGroup ) ) {
2122 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2126 QTreeWidgetItem* sizeItem = createItem( it );
2127 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2128 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2131 SALOMEDS::Color color = aGrp->GetColor();
2132 QTreeWidgetItem* colorItem = createItem( it );
2133 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2134 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2145 \brief Show node information
2146 \param node mesh node for showing
2147 \param index index of current node
2148 \param nbNodes number of unique nodes in element
2149 \param parentItem parent item of tree
2151 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2152 int nbNodes, QTreeWidgetItem* parentItem )
2154 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2155 // node number and ID
2156 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2157 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2158 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2159 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2160 nodeItem->setData( 1, IdRole, node->GetID() );
2161 nodeItem->setExpanded( false );
2163 QTreeWidgetItem* coordItem = createItem( nodeItem );
2164 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2165 QTreeWidgetItem* xItem = createItem( coordItem );
2166 xItem->setText( 0, "X" );
2167 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2168 QTreeWidgetItem* yItem = createItem( coordItem );
2169 yItem->setText( 0, "Y" );
2170 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2171 QTreeWidgetItem* zItem = createItem( coordItem );
2172 zItem->setText( 0, "Z" );
2173 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2174 // node connectivity
2175 QTreeWidgetItem* nconItem = createItem( nodeItem );
2176 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2177 Connectivity connectivity = nodeConnectivity( node );
2178 if ( !connectivity.isEmpty() ) {
2179 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2180 if ( !con.isEmpty() ) {
2181 QTreeWidgetItem* i = createItem( nconItem );
2182 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2183 i->setText( 1, con );
2185 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2186 if ( !con.isEmpty() ) {
2187 QTreeWidgetItem* i = createItem( nconItem );
2188 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2189 i->setText( 1, con );
2190 i->setData( 1, TypeRole, NodeConnectivity );
2192 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2193 if ( !con.isEmpty() ) {
2194 QTreeWidgetItem* i = createItem( nconItem );
2195 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2196 i->setText( 1, con );
2197 i->setData( 1, TypeRole, NodeConnectivity );
2199 con = formatConnectivity( connectivity, SMDSAbs_Face );
2200 if ( !con.isEmpty() ) {
2201 QTreeWidgetItem* i = createItem( nconItem );
2202 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2203 i->setText( 1, con );
2204 i->setData( 1, TypeRole, NodeConnectivity );
2206 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2207 if ( !con.isEmpty() ) {
2208 QTreeWidgetItem* i = createItem( nconItem );
2209 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2210 i->setText( 1, con );
2211 i->setData( 1, TypeRole, NodeConnectivity );
2216 \brief Internal clean-up (reset widget)
2218 void SMESHGUI_TreeElemInfo::clearInternal()
2225 \brief Create new tree item.
2226 \param parent parent tree widget item
2227 \param flags item flag
2228 \return new tree widget item
2230 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2232 QTreeWidgetItem* item;
2234 item = new QTreeWidgetItem( parent );
2236 item = new QTreeWidgetItem( myInfo );
2238 item->setFlags( item->flags() | Qt::ItemIsEditable );
2240 QFont f = item->font( 0 );
2242 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2243 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2244 item->setFont( i, f );
2247 item->setExpanded( true );
2251 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2253 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2254 if ( widgets.isEmpty() ) return;
2255 QTreeWidgetItem* aTreeItem = widgets.first();
2256 int type = aTreeItem->data( 1, TypeRole ).toInt();
2257 int id = aTreeItem->data( 1, IdRole ).toInt();
2259 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2260 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2261 emit( itemInfo( id ) );
2262 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2263 emit( itemInfo( aTreeItem->text( 1 ) ) );
2266 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2269 int type = theItem->data( 1, TypeRole ).toInt();
2270 int id = theItem->data( 1, IdRole ).toInt();
2271 if ( type == ElemConnectivity && id > 0 )
2272 emit( itemInfo( id ) );
2273 else if ( type == NodeConnectivity )
2274 emit( itemInfo( theItem->text( 1 ) ) );
2278 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2280 out << QString( 12, '-' ) << "\n";
2281 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2282 out << QString( 12, '-' ) << "\n";
2284 QTreeWidgetItemIterator it( myInfo );
2286 if ( !( *it )->text(0).isEmpty() ) {
2287 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2288 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2298 \brief Mesh information computer
2301 The class is created for different computation operation. Currently it is used
2302 to compute number of underlying nodes for the groups.
2308 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2309 QTreeWidgetItem* item,
2312 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2314 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2318 \brief Compute function
2320 void GrpComputor::compute()
2322 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2323 QTreeWidgetItem* item = myItem;
2325 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2326 item->treeWidget()->removeItemWidget( item, 1 );
2327 item->setText( 1, QString::number( nb ));
2332 \class SMESHGUI_AddInfo
2333 \brief The wigdet shows additional information on the mesh object.
2338 \param parent parent widget
2340 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2341 : QTreeWidget( parent )
2343 setColumnCount( 2 );
2344 header()->setStretchLastSection( true );
2345 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2352 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2357 \brief Show additional information on the selected object
2358 \param obj object being processed (mesh, sub-mesh, group, ID source)
2360 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2362 setProperty( "group_index", 0 );
2363 setProperty( "submesh_index", 0 );
2364 myComputors.clear();
2367 if ( CORBA::is_nil( obj ) ) return;
2369 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2370 if ( !sobj ) return;
2373 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2374 nameItem->setText( 0, tr( "NAME" ) );
2375 nameItem->setText( 1, sobj->GetName().c_str() );
2377 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2378 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2379 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2381 if ( !aMesh->_is_nil() )
2382 meshInfo( aMesh, nameItem );
2383 else if ( !aSubMesh->_is_nil() )
2384 subMeshInfo( aSubMesh, nameItem );
2385 else if ( !aGroup->_is_nil() )
2386 groupInfo( aGroup.in(), nameItem );
2390 \brief Create new tree item.
2391 \param parent parent tree widget item
2392 \param flags item flag
2393 \return new tree widget item
2395 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2397 QTreeWidgetItem* item;
2400 item = new QTreeWidgetItem( parent );
2402 item = new QTreeWidgetItem( this );
2404 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2406 QFont f = item->font( 0 );
2408 for ( int i = 0; i < columnCount(); i++ ) {
2409 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2410 item->setFont( i, f );
2413 item->setExpanded( true );
2418 \brief Show mesh info
2419 \param mesh mesh object
2420 \param parent parent tree item
2422 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2425 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2426 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2427 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2428 typeItem->setText( 0, tr( "TYPE" ) );
2429 if ( !CORBA::is_nil( shape ) ) {
2430 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2431 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2433 QTreeWidgetItem* gobjItem = createItem( typeItem );
2434 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2435 gobjItem->setText( 1, sobj->GetName().c_str() );
2438 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2439 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2440 QTreeWidgetItem* fileItem = createItem( typeItem );
2441 fileItem->setText( 0, tr( "FILE_NAME" ) );
2442 fileItem->setText( 1, (char*)inf->fileName );
2445 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2449 myGroups = mesh->GetGroups();
2453 mySubMeshes = mesh->GetSubMeshes();
2458 \brief Show sub-mesh info
2459 \param subMesh sub-mesh object
2460 \param parent parent tree item
2462 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2464 bool isShort = parent->parent() != 0;
2468 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2470 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2471 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2472 nameItem->setText( 1, sobj->GetName().c_str() );
2477 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2478 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2480 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2481 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2482 gobjItem->setText( 1, sobj->GetName().c_str() );
2487 \brief Show group info
2488 \param grp mesh group object
2489 \param parent parent tree item
2491 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2493 bool isShort = parent->parent() != 0;
2495 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2496 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2497 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2501 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2503 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2504 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2505 nameItem->setText( 1, sobj->GetName().c_str() );
2509 // type : group on geometry, standalone group, group on filter
2510 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2511 typeItem->setText( 0, tr( "TYPE" ) );
2512 if ( !CORBA::is_nil( aStdGroup ) ) {
2513 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2515 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2516 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2517 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2518 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2520 QTreeWidgetItem* gobjItem = createItem( typeItem );
2521 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2522 gobjItem->setText( 1, sobj->GetName().c_str() );
2525 else if ( !CORBA::is_nil( aFltGroup ) ) {
2526 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2531 QString etype = tr( "UNKNOWN" );
2532 switch( grp->GetType() ) {
2534 etype = tr( "NODE" );
2537 etype = tr( "EDGE" );
2540 etype = tr( "FACE" );
2543 etype = tr( "VOLUME" );
2546 etype = tr( "0DELEM" );
2549 etype = tr( "BALL" );
2554 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2555 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2556 etypeItem->setText( 1, etype );
2559 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2560 bool meshLoaded = mesh->IsLoaded();
2562 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2564 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2565 groupSize = grp->Size();
2567 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2568 sizeItem->setText( 0, tr( "SIZE" ) );
2569 if ( groupSize > -1 ) {
2570 sizeItem->setText( 1, QString::number( groupSize ) );
2573 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2574 setItemWidget( sizeItem, 1, btn );
2575 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2576 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2577 myComputors.append( comp );
2579 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2583 SALOMEDS::Color color = grp->GetColor();
2584 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2585 colorItem->setText( 0, tr( "COLOR" ) );
2586 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2588 // nb of underlying nodes
2589 if ( grp->GetType() != SMESH::NODE) {
2590 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2591 nodesItem->setText( 0, tr( "NB_NODES" ) );
2592 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2593 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2594 if ( toShowNodes && meshLoaded ) {
2595 // already calculated and up-to-date
2596 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2599 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2600 setItemWidget( nodesItem, 1, btn );
2601 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2602 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2603 myComputors.append( comp );
2605 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2610 void SMESHGUI_AddInfo::showGroups()
2612 myComputors.clear();
2614 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2615 if ( !parent ) return;
2617 int idx = property( "group_index" ).toInt();
2619 QTreeWidgetItem* itemGroups = 0;
2620 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2621 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2622 itemGroups = parent->child( i );
2623 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2625 extra->updateControls( myGroups->length(), idx );
2626 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2630 QMap<int, QTreeWidgetItem*> grpItems;
2631 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2632 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2633 if ( CORBA::is_nil( grp ) ) continue;
2634 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2635 if ( !grpSObj ) continue;
2637 int grpType = grp->GetType();
2639 if ( !itemGroups ) {
2640 // create top-level groups container item
2641 itemGroups = createItem( parent, Bold | All );
2642 itemGroups->setText( 0, tr( "GROUPS" ) );
2643 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2645 // total number of groups > 10, show extra widgets for info browsing
2646 if ((int) myGroups->length() > MAXITEMS ) {
2647 ExtraWidget* extra = new ExtraWidget( this, true );
2648 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2649 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2650 setItemWidget( itemGroups, 1, extra );
2651 extra->updateControls( myGroups->length(), idx );
2655 if ( grpItems.find( grpType ) == grpItems.end() ) {
2656 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2657 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2658 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2662 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2663 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2666 groupInfo( grp.in(), grpNameItem );
2670 void SMESHGUI_AddInfo::showSubMeshes()
2672 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2673 if ( !parent ) return;
2675 int idx = property( "submesh_index" ).toInt();
2677 QTreeWidgetItem* itemSubMeshes = 0;
2678 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2679 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2680 itemSubMeshes = parent->child( i );
2681 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2683 extra->updateControls( mySubMeshes->length(), idx );
2684 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2688 QMap<int, QTreeWidgetItem*> smItems;
2689 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2690 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2691 if ( CORBA::is_nil( sm ) ) continue;
2692 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2693 if ( !smSObj ) continue;
2695 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2696 if ( CORBA::is_nil(gobj ) ) continue;
2698 int smType = gobj->GetShapeType();
2699 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2701 if ( !itemSubMeshes ) {
2702 itemSubMeshes = createItem( parent, Bold | All );
2703 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2704 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2706 // total number of sub-meshes > 10, show extra widgets for info browsing
2707 if ((int) mySubMeshes->length() > MAXITEMS ) {
2708 ExtraWidget* extra = new ExtraWidget( this, true );
2709 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2710 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2711 setItemWidget( itemSubMeshes, 1, extra );
2712 extra->updateControls( mySubMeshes->length(), idx );
2716 if ( smItems.find( smType ) == smItems.end() ) {
2717 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2718 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2719 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2723 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2724 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2727 subMeshInfo( sm.in(), smNameItem );
2732 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2734 void SMESHGUI_AddInfo::changeLoadToCompute()
2736 for ( int i = 0; i < myComputors.count(); ++i )
2738 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2740 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2741 btn->setText( tr("COMPUTE") );
2746 void SMESHGUI_AddInfo::showPreviousGroups()
2748 int idx = property( "group_index" ).toInt();
2749 setProperty( "group_index", idx-1 );
2753 void SMESHGUI_AddInfo::showNextGroups()
2755 int idx = property( "group_index" ).toInt();
2756 setProperty( "group_index", idx+1 );
2760 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2762 int idx = property( "submesh_index" ).toInt();
2763 setProperty( "submesh_index", idx-1 );
2767 void SMESHGUI_AddInfo::showNextSubMeshes()
2769 int idx = property( "submesh_index" ).toInt();
2770 setProperty( "submesh_index", idx+1 );
2774 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2776 out << QString( 15, '-') << "\n";
2777 out << tr( "ADDITIONAL_INFO" ) << "\n";
2778 out << QString( 15, '-' ) << "\n";
2779 QTreeWidgetItemIterator it( this );
2781 if ( !( ( *it )->text(0) ).isEmpty() ) {
2782 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2783 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2784 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2786 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2795 \class SMESHGUI_MeshInfoDlg
2796 \brief Mesh information dialog box
2801 \param parent parent widget
2802 \param page specifies the dialog page to be shown at the start-up
2804 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2805 : QDialog( parent ), myActor( 0 )
2808 setAttribute( Qt::WA_DeleteOnClose, true );
2809 setWindowTitle( tr( "MESH_INFO" ) );
2810 setSizeGripEnabled( true );
2812 myTabWidget = new QTabWidget( this );
2816 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2817 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2821 QWidget* w = new QWidget( myTabWidget );
2823 myMode = new QButtonGroup( this );
2824 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2825 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2826 myMode->button( NodeMode )->setChecked( true );
2827 myID = new QLineEdit( w );
2828 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2830 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2831 mode = qMin( 1, qMax( 0, mode ) );
2834 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2836 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2838 QGridLayout* elemLayout = new QGridLayout( w );
2839 elemLayout->setMargin( MARGIN );
2840 elemLayout->setSpacing( SPACING );
2841 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2842 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2843 elemLayout->addWidget( myID, 0, 2 );
2844 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2846 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2850 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2851 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2855 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2856 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2860 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2861 okBtn->setAutoDefault( true );
2862 okBtn->setDefault( true );
2864 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2865 dumpBtn->setAutoDefault( true );
2866 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2867 helpBtn->setAutoDefault( true );
2869 QHBoxLayout* btnLayout = new QHBoxLayout;
2870 btnLayout->setSpacing( SPACING );
2871 btnLayout->setMargin( 0 );
2873 btnLayout->addWidget( okBtn );
2874 btnLayout->addWidget( dumpBtn );
2875 btnLayout->addStretch( 10 );
2876 btnLayout->addWidget( helpBtn );
2878 QVBoxLayout* l = new QVBoxLayout ( this );
2879 l->setMargin( MARGIN );
2880 l->setSpacing( SPACING );
2881 l->addWidget( myTabWidget );
2882 l->addLayout( btnLayout );
2884 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2886 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2887 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2888 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2889 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2890 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2891 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2892 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2893 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2894 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2895 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2903 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2908 \brief Show mesh information
2909 \param IO interactive object
2911 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2913 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2914 if ( !CORBA::is_nil( obj ) ) {
2915 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2916 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2917 myCtrlInfo->showInfo( obj );
2919 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2920 SVTK_Selector* selector = SMESH::GetSelector();
2923 if ( myActor && selector ) {
2924 nb = myMode->checkedId() == NodeMode ?
2925 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2926 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2928 myElemInfo->setSource( myActor ) ;
2930 myID->setText( ID.trimmed() );
2932 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2933 foreach ( ID, idTxt )
2934 ids << ID.trimmed().toLong();
2935 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2939 myElemInfo->clear();
2945 \brief Perform clean-up actions on the dialog box closing.
2947 void SMESHGUI_MeshInfoDlg::reject()
2949 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2950 selMgr->clearFilters();
2951 SMESH::SetPointRepresentation( false );
2952 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2953 aViewWindow->SetSelectionMode( ActorSelection );
2958 \brief Process keyboard event
2959 \param e key press event
2961 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2963 QDialog::keyPressEvent( e );
2964 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2971 \brief Reactivate dialog box, when mouse pointer goes into it.
2973 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2979 \brief Setup selection mode depending on the current dialog box state.
2981 void SMESHGUI_MeshInfoDlg::updateSelection()
2983 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2985 disconnect( selMgr, 0, this, 0 );
2986 selMgr->clearFilters();
2988 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2989 SMESH::SetPointRepresentation( false );
2990 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2991 aViewWindow->SetSelectionMode( ActorSelection );
2994 if ( myMode->checkedId() == NodeMode ) {
2995 SMESH::SetPointRepresentation( true );
2996 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2997 aViewWindow->SetSelectionMode( NodeSelection );
3000 SMESH::SetPointRepresentation( false );
3001 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3002 aViewWindow->SetSelectionMode( CellSelection );
3006 QString oldID = myID->text().trimmed();
3007 SMESH_Actor* oldActor = myActor;
3010 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3013 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3014 myID->setText( oldID );
3020 \brief Show help page
3022 void SMESHGUI_MeshInfoDlg::help()
3024 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3025 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3026 "mesh_infos_page.html#mesh_element_info_anchor" );
3030 \brief Show mesh information
3032 void SMESHGUI_MeshInfoDlg::updateInfo()
3034 SUIT_OverrideCursor wc;
3036 SALOME_ListIO selected;
3037 SMESHGUI::selectionMgr()->selectedObjects( selected );
3039 if ( selected.Extent() == 1 ) {
3040 Handle(SALOME_InteractiveObject) IO = selected.First();
3044 // myBaseInfo->clear();
3045 // myElemInfo->clear();
3046 // myAddInfo->clear();
3051 \brief Activate dialog box
3053 void SMESHGUI_MeshInfoDlg::activate()
3055 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3056 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3057 myTabWidget->setEnabled( true );
3062 \brief Deactivate dialog box
3064 void SMESHGUI_MeshInfoDlg::deactivate()
3066 myTabWidget->setEnabled( false );
3067 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3071 \brief Called when users switches between node / element modes.
3073 void SMESHGUI_MeshInfoDlg::modeChanged()
3080 \brief Caled when users prints mesh element ID in the corresponding field.
3082 void SMESHGUI_MeshInfoDlg::idChanged()
3084 SVTK_Selector* selector = SMESH::GetSelector();
3085 if ( myActor && selector ) {
3086 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3087 TColStd_MapOfInteger ID;
3089 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3090 foreach ( QString tid, idTxt ) {
3091 long id = tid.trimmed().toLong();
3092 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3093 myActor->GetObject()->GetMesh()->FindElement( id ) :
3094 myActor->GetObject()->GetMesh()->FindNode( id );
3100 selector->AddOrRemoveIndex( IO, ID, false );
3101 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3102 aViewWindow->highlight( IO, true, true );
3103 aViewWindow->Repaint();
3105 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3109 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3111 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3112 myMode->button( NodeMode )->click();
3113 myID->setText( QString::number( id ) );
3117 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3119 if ( !theStr.isEmpty() ) {
3120 myMode->button( ElemMode )->click();
3121 myID->setText( theStr );
3125 void SMESHGUI_MeshInfoDlg::dump()
3127 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3129 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3130 if ( !appStudy ) return;
3131 _PTR( Study ) aStudy = appStudy->studyDS();
3133 QStringList aFilters;
3134 aFilters.append( tr( "TEXT_FILES" ) );
3136 bool anIsBase = true;
3137 bool anIsElem = true;
3138 bool anIsAdd = true;
3139 bool anIsCtrl = true;
3141 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3142 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3143 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3144 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3145 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3148 DumpFileDlg fd( this );
3149 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3150 fd.setNameFilters( aFilters );
3151 fd.myBaseChk->setChecked( anIsBase );
3152 fd.myElemChk->setChecked( anIsElem );
3153 fd.myAddChk ->setChecked( anIsAdd );
3154 fd.myCtrlChk->setChecked( anIsCtrl );
3155 if ( fd.exec() == QDialog::Accepted )
3157 QString aFileName = fd.selectedFile();
3159 bool toBase = fd.myBaseChk->isChecked();
3160 bool toElem = fd.myElemChk->isChecked();
3161 bool toAdd = fd.myAddChk->isChecked();
3162 bool toCtrl = fd.myCtrlChk->isChecked();
3164 if ( !aFileName.isEmpty() ) {
3165 QFileInfo aFileInfo( aFileName );
3166 if ( aFileInfo.isDir() )
3169 QFile aFile( aFileName );
3170 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3173 QTextStream out( &aFile );
3175 if ( toBase ) myBaseInfo->saveInfo( out );
3176 if ( toElem ) myElemInfo->saveInfo( out );
3177 if ( toAdd ) myAddInfo ->saveInfo( out );
3178 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3184 \class SMESHGUI_CtrlInfo
3185 \brief Class for the mesh controls information widget.
3190 \param parent parent widget
3192 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3193 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3195 setFrameStyle( StyledPanel | Sunken );
3197 myMainLayout = new QGridLayout( this );
3198 myMainLayout->setMargin( MARGIN );
3199 myMainLayout->setSpacing( SPACING );
3202 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3203 QLabel* aName = createField();
3204 aName->setMinimumWidth( 150 );
3207 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3208 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3210 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3213 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3214 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3215 QLabel* aNodesFree = createField();
3216 myWidgets << aNodesFree;
3217 myPredicates << aFilterMgr->CreateFreeNodes();
3219 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3220 QLabel* aNodesDouble = createField();
3221 myWidgets << aNodesDouble;
3222 myPredicates << aFilterMgr->CreateEqualNodes();
3223 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3224 myToleranceWidget = new SMESHGUI_SpinBox( this );
3225 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3226 myToleranceWidget->setAcceptNames( false );
3227 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3230 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3231 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3232 QLabel* anEdgesDouble = createField();
3233 myWidgets << anEdgesDouble;
3234 myPredicates << aFilterMgr->CreateEqualEdges();
3237 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3238 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3239 QLabel* aFacesDouble = createField();
3240 myWidgets << aFacesDouble;
3241 myPredicates << aFilterMgr->CreateEqualFaces();
3242 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3243 QLabel* aFacesOver = createField();
3244 myWidgets << aFacesOver;
3245 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3246 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3247 myPlot = createPlot( this );
3248 myAspectRatio = aFilterMgr->CreateAspectRatio();
3251 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3252 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3253 QLabel* aVolumesDouble = createField();
3254 myWidgets << aVolumesDouble;
3255 myPredicates << aFilterMgr->CreateEqualVolumes();
3256 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3257 QLabel* aVolumesOver = createField();
3258 myWidgets << aVolumesOver;
3259 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3260 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3261 myPlot3D = createPlot( this );
3262 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3264 QToolButton* aFreeNodesBtn = new QToolButton( this );
3265 aFreeNodesBtn->setIcon(aComputeIcon);
3266 myButtons << aFreeNodesBtn; //0
3268 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3269 aDoubleNodesBtn->setIcon(aComputeIcon);
3270 myButtons << aDoubleNodesBtn; //1
3272 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3273 aDoubleEdgesBtn->setIcon(aComputeIcon);
3274 myButtons << aDoubleEdgesBtn; //2
3276 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3277 aDoubleFacesBtn->setIcon(aComputeIcon);
3278 myButtons << aDoubleFacesBtn; //3
3280 QToolButton* aOverContFacesBtn = new QToolButton( this );
3281 aOverContFacesBtn->setIcon(aComputeIcon);
3282 myButtons << aOverContFacesBtn; //4
3284 QToolButton* aComputeFaceBtn = new QToolButton( this );
3285 aComputeFaceBtn->setIcon(aComputeIcon);
3286 myButtons << aComputeFaceBtn; //5
3288 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3289 aDoubleVolumesBtn->setIcon(aComputeIcon);
3290 myButtons << aDoubleVolumesBtn; //6
3292 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3293 aOverContVolumesBtn->setIcon(aComputeIcon);
3294 myButtons << aOverContVolumesBtn; //7
3296 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3297 aComputeVolumeBtn->setIcon(aComputeIcon);
3298 myButtons << aComputeVolumeBtn; //8
3300 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3301 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3302 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3303 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3304 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3305 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3306 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3307 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3308 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3309 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3311 setFontAttributes( aNameLab );
3312 setFontAttributes( aNodesLab );
3313 setFontAttributes( anEdgesLab );
3314 setFontAttributes( aFacesLab );
3315 setFontAttributes( aVolumesLab );
3317 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3318 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3319 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3320 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3321 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3322 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3323 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3324 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3325 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3326 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3327 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3328 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3329 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3330 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3331 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3332 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3333 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3334 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3335 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3336 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3337 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3338 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3339 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3340 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3341 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3342 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3343 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3344 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3345 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3346 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3347 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3348 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3349 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3350 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3351 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3353 myMainLayout->setColumnStretch( 0, 0 );
3354 myMainLayout->setColumnStretch( 1, 5 );
3355 myMainLayout->setRowStretch ( 11, 5 );
3356 myMainLayout->setRowStretch ( 16, 5 );
3357 myMainLayout->setRowStretch ( 17, 1 );
3365 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3369 \brief Change widget font attributes (bold, ...).
3371 \param attr font attributes (XORed flags)
3373 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3376 QFont f = w->font();
3383 \brief Create info field
3384 \return new info field
3386 QLabel* SMESHGUI_CtrlInfo::createField()
3388 QLabel* lab = new QLabel( this );
3389 lab->setFrameStyle( StyledPanel | Sunken );
3390 lab->setAlignment( Qt::AlignCenter );
3391 lab->setAutoFillBackground( true );
3392 QPalette pal = lab->palette();
3393 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3394 lab->setPalette( pal );
3395 lab->setMinimumWidth( 60 );
3400 \brief Create QwtPlot
3403 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3405 QwtPlot* aPlot = new QwtPlot( parent );
3406 aPlot->setMinimumSize( 100, 100 );
3407 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3408 xFont.setPointSize( 5 );
3409 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3410 yFont.setPointSize( 5 );
3411 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3412 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3418 \brief Show controls information on the selected object
3420 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3424 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3425 if ( myObject->_is_nil() ) return;
3427 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3428 myWidgets[0]->setText( aSO->GetName().c_str() );
3430 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3431 if ( mesh->_is_nil() ) return;
3433 const bool meshLoaded = mesh->IsLoaded();
3434 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3435 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3436 for ( int i = 0; i < myButtons.count(); ++i )
3437 myButtons[i]->setEnabled( true );
3439 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3440 if ( ! &nbElemsByType.in() ) return;
3442 const CORBA::Long ctrlLimit =
3443 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3446 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3447 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3448 nbElemsByType[ SMESH::FACE ] +
3449 nbElemsByType[ SMESH::VOLUME ] );
3450 if ( nbNodes + nbElems > 0 ) {
3451 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3453 computeFreeNodesInfo();
3455 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3456 computeDoubleNodesInfo();
3459 myButtons[0]->setEnabled( true );
3460 myButtons[1]->setEnabled( true );
3464 for( int i=2; i<=10; i++)
3465 myMainLayout->itemAt(i)->widget()->setVisible( false );
3469 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3471 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3472 computeDoubleEdgesInfo();
3474 myButtons[2]->setEnabled( true );
3477 for( int i=11; i<=14; i++)
3478 myMainLayout->itemAt(i)->widget()->setVisible( false );
3482 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3483 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3485 computeDoubleFacesInfo();
3486 // over constrained faces
3487 computeOverConstrainedFacesInfo();
3488 // aspect Ratio histogram
3489 computeAspectRatio();
3492 myButtons[3]->setEnabled( true );
3493 myButtons[4]->setEnabled( true );
3494 myButtons[5]->setEnabled( true );
3496 #ifdef DISABLE_PLOT2DVIEWER
3497 myMainLayout->setRowStretch(11,0);
3498 for( int i=22; i<=24; i++)
3499 myMainLayout->itemAt(i)->widget()->setVisible( false );
3503 myMainLayout->setRowStretch(11,0);
3504 for( int i=15; i<=24; i++)
3505 myMainLayout->itemAt(i)->widget()->setVisible( false );
3509 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3510 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3512 computeDoubleVolumesInfo();
3513 // over constrained volumes
3514 computeOverConstrainedVolumesInfo();
3515 // aspect Ratio 3D histogram
3516 computeAspectRatio3D();
3519 myButtons[6]->setEnabled( true );
3520 myButtons[7]->setEnabled( true );
3521 myButtons[8]->setEnabled( true );
3523 #ifdef DISABLE_PLOT2DVIEWER
3524 myMainLayout->setRowStretch(16,0);
3525 for( int i=32; i<=34; i++)
3526 myMainLayout->itemAt(i)->widget()->setVisible( false );
3530 myMainLayout->setRowStretch(16,0);
3531 for( int i=25; i<=34; i++)
3532 myMainLayout->itemAt(i)->widget()->setVisible( false );
3536 //================================================================================
3538 * \brief Computes and shows nb of elements satisfying a given predicate
3539 * \param [in] ft - a predicate type (SMESH::FunctorType)
3540 * \param [in] iBut - index of one of myButtons to disable
3541 * \param [in] iWdg - index of one of myWidgets to show the computed number
3543 //================================================================================
3545 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3547 myButtons[ iBut ]->setEnabled( false );
3548 myWidgets[ iWdg ]->setText( "" );
3549 if ( myObject->_is_nil() ) return;
3551 SUIT_OverrideCursor wc;
3553 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3554 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3557 this->showInfo( myObject ); // try to show all values
3558 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3559 return; // <ft> predicate already computed
3561 // look for a predicate of type <ft>
3562 for ( int i = 0; i < myPredicates.count(); ++i )
3563 if ( myPredicates[i]->GetFunctorType() == ft )
3565 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3566 myWidgets[ iWdg ]->setText( QString::number( nb ));
3570 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3572 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3575 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3577 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3580 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3582 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3585 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3587 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3590 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3592 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3595 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3597 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3600 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3602 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3605 void SMESHGUI_CtrlInfo::computeAspectRatio()
3607 #ifndef DISABLE_PLOT2DVIEWER
3608 myButtons[5]->setEnabled( false );
3610 if ( myObject->_is_nil() ) return;
3612 SUIT_OverrideCursor wc;
3614 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3615 if ( aHistogram && !aHistogram->isEmpty() ) {
3616 QwtPlotItem* anItem = aHistogram->createPlotItem();
3617 anItem->attach( myPlot );
3624 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3626 #ifndef DISABLE_PLOT2DVIEWER
3627 myButtons[8]->setEnabled( false );
3629 if ( myObject->_is_nil() ) return;
3631 SUIT_OverrideCursor wc;
3633 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3634 if ( aHistogram && !aHistogram->isEmpty() ) {
3635 QwtPlotItem* anItem = aHistogram->createPlotItem();
3636 anItem->attach( myPlot3D );
3644 \brief Internal clean-up (reset widget)
3646 void SMESHGUI_CtrlInfo::clearInternal()
3648 for( int i=0; i<=34; i++)
3649 myMainLayout->itemAt(i)->widget()->setVisible( true );
3650 for( int i=0; i<=8; i++)
3651 myButtons[i]->setEnabled( false );
3652 myPlot->detachItems();
3653 myPlot3D->detachItems();
3656 myWidgets[0]->setText( QString() );
3657 for ( int i = 1; i < myWidgets.count(); i++ )
3658 myWidgets[i]->setText( "" );
3659 myMainLayout->setRowStretch(11,5);
3660 myMainLayout->setRowStretch(16,5);
3663 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3665 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3666 myButtons[1]->setEnabled( true );
3667 myWidgets[2]->setText("");
3670 #ifndef DISABLE_PLOT2DVIEWER
3671 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3673 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3674 if ( mesh->_is_nil() ) return 0;
3675 if ( !mesh->IsLoaded() )
3677 aNumFun->SetMesh( mesh );
3679 CORBA::Long cprecision = 6;
3680 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3681 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3682 aNumFun->SetPrecision( cprecision );
3684 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3686 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3687 /*isLogarithmic=*/false,
3689 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3690 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3691 if ( &histogramVar.in() )
3693 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3694 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3695 if ( histogramVar->length() >= 2 )
3696 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3702 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3703 out << QString( 20, '-' ) << "\n";
3704 out << tr( "CTRL_INFO" ) << "\n";
3705 out << QString( 20, '-' ) << "\n";
3706 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3707 out << tr( "NODES_INFO" ) << "\n";
3708 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3709 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3710 out << tr( "EDGES_INFO" ) << "\n";
3711 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3712 out << tr( "FACES_INFO" ) << "\n";
3713 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3714 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3715 out << tr( "VOLUMES_INFO" ) << "\n";
3716 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3717 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3721 \class SMESHGUI_CtrlInfoDlg
3722 \brief Controls information dialog box
3727 \param parent parent widget
3728 \param page specifies the dialog page to be shown at the start-up
3730 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3733 setAttribute( Qt::WA_DeleteOnClose, true );
3734 setWindowTitle( tr( "CTRL_INFO" ) );
3735 setMinimumSize( 400, 600 );
3737 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3740 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3741 okBtn->setAutoDefault( true );
3742 okBtn->setDefault( true );
3744 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3745 dumpBtn->setAutoDefault( true );
3746 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3747 helpBtn->setAutoDefault( true );
3749 QHBoxLayout* btnLayout = new QHBoxLayout;
3750 btnLayout->setSpacing( SPACING );
3751 btnLayout->setMargin( 0 );
3753 btnLayout->addWidget( okBtn );
3754 btnLayout->addWidget( dumpBtn );
3755 btnLayout->addStretch( 10 );
3756 btnLayout->addWidget( helpBtn );
3758 QVBoxLayout* l = new QVBoxLayout ( this );
3759 l->setMargin( MARGIN );
3760 l->setSpacing( SPACING );
3761 l->addWidget( myCtrlInfo );
3762 l->addLayout( btnLayout );
3764 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3765 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3766 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3767 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3768 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3776 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3781 \brief Show controls information
3782 \param IO interactive object
3784 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3786 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3787 myCtrlInfo->showInfo( obj );
3791 \brief Perform clean-up actions on the dialog box closing.
3793 void SMESHGUI_CtrlInfoDlg::reject()
3795 SMESH::SetPointRepresentation( false );
3800 \brief Setup selection mode depending on the current dialog box state.
3802 void SMESHGUI_CtrlInfoDlg::updateSelection()
3804 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3805 disconnect( selMgr, 0, this, 0 );
3806 SMESH::SetPointRepresentation( false );
3807 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3812 \brief Show mesh information
3814 void SMESHGUI_CtrlInfoDlg::updateInfo()
3816 SUIT_OverrideCursor wc;
3818 SALOME_ListIO selected;
3819 SMESHGUI::selectionMgr()->selectedObjects( selected );
3821 if ( selected.Extent() == 1 ) {
3822 Handle(SALOME_InteractiveObject) IO = selected.First();
3828 \brief Activate dialog box
3830 void SMESHGUI_CtrlInfoDlg::activate()
3832 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3833 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3838 \brief Deactivate dialog box
3840 void SMESHGUI_CtrlInfoDlg::deactivate()
3842 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3846 * \brief Dump contents into a file
3848 void SMESHGUI_CtrlInfoDlg::dump()
3850 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3852 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3853 if ( !appStudy ) return;
3854 _PTR( Study ) aStudy = appStudy->studyDS();
3856 QStringList aFilters;
3857 aFilters.append( tr( "TEXT_FILES" ) );
3859 DumpFileDlg fd( this );
3860 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3861 fd.setNameFilters( aFilters );
3862 fd.myBaseChk->hide();
3863 fd.myElemChk->hide();
3864 fd.myAddChk ->hide();
3865 fd.myCtrlChk->hide();
3866 if ( fd.exec() == QDialog::Accepted )
3868 QString aFileName = fd.selectedFile();
3869 if ( !aFileName.isEmpty() ) {
3870 QFileInfo aFileInfo( aFileName );
3871 if ( aFileInfo.isDir() )
3874 QFile aFile( aFileName );
3875 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3878 QTextStream out( &aFile );
3879 myCtrlInfo->saveInfo( out );
3887 void SMESHGUI_CtrlInfoDlg::help()
3889 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");