1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESHGUI_MeshInfo.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_MeshInfo.h"
27 #include "SMDSAbs_ElementType.hxx"
28 #include "SMDS_BallElement.hxx"
29 #include "SMDS_EdgePosition.hxx"
30 #include "SMDS_FacePosition.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_VolumeTool.hxx"
33 #include "SMESHDS_Mesh.hxx"
35 #include "SMESHGUI_FilterUtils.h"
36 #include "SMESHGUI_IdValidator.h"
37 #include "SMESHGUI_SpinBox.h"
38 #include "SMESHGUI_Utils.h"
39 #include "SMESHGUI_VTKUtils.h"
40 #include "SMESH_Actor.h"
42 #include <LightApp_SelectionMgr.h>
43 #include <SUIT_FileDlg.h>
44 #include <SUIT_OverrideCursor.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SVTK_ViewWindow.h>
49 #include <SALOMEDSClient_Study.hxx>
50 #include <SalomeApp_Study.h>
52 #include <QApplication>
53 #include <QButtonGroup>
55 #include <QContextMenuEvent>
56 #include <QGridLayout>
57 #include <QHBoxLayout>
58 #include <QHeaderView>
59 #include <QItemDelegate>
64 #include <QPushButton>
65 #include <QToolButton>
66 #include <QRadioButton>
67 #include <QTextStream>
69 #include <QTextBrowser>
70 #include <QVBoxLayout>
72 #include "utilities.h"
74 #include <SALOMEconfig.h>
75 #include CORBA_SERVER_HEADER(GEOM_Gen)
79 const int SPACING = 6;
81 const int MAXITEMS = 10;
82 const int GROUPS_ID = 100;
83 const int SUBMESHES_ID = 200;
84 const int SPACING_INFO = 2;
87 TypeRole = Qt::UserRole + 10,
92 NodeConnectivity = 100,
101 class ExtraWidget : public QWidget
104 ExtraWidget( QWidget*, bool = false );
107 void updateControls( int, int, int = MAXITEMS );
116 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
118 current = new QLabel( this );
119 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
120 prev = new QPushButton( tr( "<<" ), this );
121 next = new QPushButton( tr( ">>" ), this );
122 QHBoxLayout* hbl = new QHBoxLayout( this );
123 hbl->setContentsMargins( 0, SPACING, 0, 0 );
124 hbl->setSpacing( SPACING );
126 hbl->addWidget( current );
127 hbl->addWidget( prev );
128 hbl->addWidget( next );
131 ExtraWidget::~ExtraWidget()
135 void ExtraWidget::updateControls( int total, int index, int blockSize )
137 setVisible( total > blockSize );
138 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
139 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) );
140 prev->setEnabled( index > 0 );
141 next->setEnabled( (index+1)*blockSize < total );
146 \brief Customization of standard "Save file" dialog box for dump info operation
150 class DumpFileDlg : public SUIT_FileDlg
153 DumpFileDlg( QWidget* parent );
155 QCheckBox* myBaseChk;
156 QCheckBox* myElemChk;
158 QCheckBox* myCtrlChk;
165 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
167 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
169 QWidget* hB = new QWidget( this );
170 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
171 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
172 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
173 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
175 QGridLayout* layout = new QGridLayout( hB );
176 layout->addWidget( myBaseChk, 0, 0 );
177 layout->addWidget( myElemChk, 0, 1 );
178 layout->addWidget( myAddChk, 1, 0 );
179 layout->addWidget( myCtrlChk, 1, 1 );
181 QPushButton* pb = new QPushButton( this );
183 int row = grid->rowCount();
184 grid->addWidget( new QLabel( "", this ), row, 0 );
185 grid->addWidget( hB, row, 1, 1, 3 );
186 grid->addWidget( pb, row, 5 );
193 \brief Get depth of the tree item
195 \param theItem tree widget item
196 \return item's depth in tree widget (where top-level items have zero depth)
198 static int itemDepth( QTreeWidgetItem* item )
201 QTreeWidgetItem* p = item->parent();
210 \class SMESHGUI_MeshInfo
211 \brief Base mesh information widget
213 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
218 \param parent parent widget
220 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
221 : QFrame( parent ), myWidgets( iElementsEnd )
223 setFrameStyle( StyledPanel | Sunken );
225 QGridLayout* l = new QGridLayout( this );
226 l->setMargin( MARGIN );
227 l->setSpacing( SPACING );
232 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
233 QLabel* aName = createField();
234 aName->setObjectName("meshName");
235 aName->setMinimumWidth( 150 );
236 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
237 QLabel* aObj = createField();
238 aObj->setObjectName("meshType");
239 aObj->setMinimumWidth( 150 );
240 myWidgets[ index++ ] << aNameLab << aName;
241 myWidgets[ index++ ] << aObjLab << aObj;
244 QWidget* aNodesLine = createLine();
245 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
246 QLabel* aNodes = createField();
247 aNodes->setObjectName("nbNodes");
248 myWidgets[ index++ ] << aNodesLine;
249 myWidgets[ index++ ] << aNodesLab << aNodes;
252 QWidget* aElemLine = createLine();
253 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
254 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
255 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
256 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
257 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
258 myWidgets[ index++ ] << aElemLine;
259 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
261 // ... Number elements
262 QWidget* aNbLine = createLine();
263 QLabel* aNbTotal = createField();
264 aNbTotal->setObjectName("totalNbElems");
265 QLabel* aNbLin = createField();
266 aNbLin->setObjectName("totalNbLinearElems");
267 QLabel* aNbQuad = createField();
268 aNbQuad->setObjectName("totalNbQuadraticElems");
269 QLabel* aNbBiQuad = createField();
270 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
271 myWidgets[ index++ ] << aNbLine;
272 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
275 QWidget* a0DLine = createLine();
276 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
277 QLabel* a0DTotal = createField();
278 a0DTotal->setObjectName("nb0D");
280 myWidgets[ index++ ] << a0DLine;
281 myWidgets[ index++ ] << a0DLab << a0DTotal;
284 QWidget* aBallLine = createLine();
285 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
286 QLabel* aBallTotal = createField();
287 aBallTotal->setObjectName("nbBall");
288 myWidgets[ index++ ] << aBallLine;
289 myWidgets[ index++ ] << aBallLab << aBallTotal;
292 QWidget* a1DLine = createLine();
293 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
294 QLabel* a1DTotal = createField();
295 a1DTotal->setObjectName("nb1D");
296 QLabel* a1DLin = createField();
297 a1DLin->setObjectName("nbLinear1D");
298 QLabel* a1DQuad = createField();
299 a1DQuad->setObjectName("nbQuadratic1D");
300 myWidgets[ index++ ] << a1DLine;
301 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
304 QWidget* a2DLine = createLine();
305 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
306 QLabel* a2DTotal = createField();
307 a2DTotal->setObjectName("nb2D");
308 QLabel* a2DLin = createField();
309 a2DLin->setObjectName("nbLinear2D");
310 QLabel* a2DQuad = createField();
311 a2DQuad->setObjectName("nbQuadratic2D");
312 QLabel* a2DBiQuad = createField();
313 a2DBiQuad->setObjectName("nbBiQuadratic2D");
314 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
315 QLabel* a2DTriTotal = createField();
316 a2DTriTotal->setObjectName("nbTriangle");
317 QLabel* a2DTriLin = createField();
318 a2DTriLin->setObjectName("nbLinearTriangle");
319 QLabel* a2DTriQuad = createField();
320 a2DTriQuad->setObjectName("nbQuadraticTriangle");
321 QLabel* a2DTriBiQuad = createField();
322 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
323 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
324 QLabel* a2DQuaTotal = createField();
325 a2DQuaTotal->setObjectName("nbQuadrangle");
326 QLabel* a2DQuaLin = createField();
327 a2DQuaLin->setObjectName("nbLinearQuadrangle");
328 QLabel* a2DQuaQuad = createField();
329 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
330 QLabel* a2DQuaBiQuad = createField();
331 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
332 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
333 QLabel* a2DPolTotal = createField();
334 a2DPolTotal->setObjectName("nbPolygon");
335 QLabel* a2DPolLin = createField();
336 a2DPolLin->setObjectName("nbLinearPolygon");
337 QLabel* a2DPolQuad = createField();
338 a2DPolQuad->setObjectName("nbQuadraticPolygon");
339 myWidgets[ index++ ] << a2DLine;
340 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
341 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
342 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
343 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
346 QWidget* a3DLine = createLine();
347 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
348 QLabel* a3DTotal = createField();
349 a3DTotal->setObjectName("nb3D");
350 QLabel* a3DLin = createField();
351 a3DLin->setObjectName("nbLinear3D");
352 QLabel* a3DQuad = createField();
353 a3DQuad->setObjectName("nbQuadratic3D");
354 QLabel* a3DBiQuad = createField();
355 a3DBiQuad->setObjectName("nbBiQuadratic3D");
356 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
357 QLabel* a3DTetTotal = createField();
358 a3DTetTotal->setObjectName("nbTetrahedron");
359 QLabel* a3DTetLin = createField();
360 a3DTetLin->setObjectName("nbLinearTetrahedron");
361 QLabel* a3DTetQuad = createField();
362 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
363 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
364 QLabel* a3DHexTotal = createField();
365 a3DHexTotal->setObjectName("nbHexahedron");
366 QLabel* a3DHexLin = createField();
367 a3DHexLin->setObjectName("nbLinearHexahedron");
368 QLabel* a3DHexQuad = createField();
369 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
370 QLabel* a3DHexBiQuad = createField();
371 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
372 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
373 QLabel* a3DPyrTotal = createField();
374 a3DPyrTotal->setObjectName("nbPyramid");
375 QLabel* a3DPyrLin = createField();
376 a3DPyrLin->setObjectName("nbLinearPyramid");
377 QLabel* a3DPyrQuad = createField();
378 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
379 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
380 QLabel* a3DPriTotal = createField();
381 a3DPriTotal->setObjectName("nbPrism");
382 QLabel* a3DPriLin = createField();
383 a3DPriLin->setObjectName("nbLinearPrism");
384 QLabel* a3DPriQuad = createField();
385 a3DPriQuad->setObjectName("nbQuadraticPrism");
386 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
387 QLabel* a3DHexPriTotal = createField();
388 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
389 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
390 QLabel* a3DPolTotal = createField();
391 a3DPolTotal->setObjectName("nbPolyhedron");
392 myWidgets[ index++ ] << a3DLine;
393 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
394 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
395 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
396 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
397 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
398 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
399 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
401 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
402 myLoadBtn->setAutoDefault( true );
403 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
405 setFontAttributes( aNameLab, Bold );
406 setFontAttributes( aObjLab, Bold );
407 setFontAttributes( aNodesLab, Bold );
408 setFontAttributes( aElemLab, Bold );
409 setFontAttributes( aElemTotal, Italic );
410 setFontAttributes( aElemLin, Italic );
411 setFontAttributes( aElemQuad, Italic );
412 setFontAttributes( aElemBiQuad, Italic );
413 setFontAttributes( a0DLab, Bold );
414 setFontAttributes( aBallLab, Bold );
415 setFontAttributes( a1DLab, Bold );
416 setFontAttributes( a2DLab, Bold );
417 setFontAttributes( a3DLab, Bold );
419 l->addWidget( aNameLab, 0, 0 );
420 l->addWidget( aName, 0, 1, 1, 4 );
421 l->addWidget( aObjLab, 1, 0 );
422 l->addWidget( aObj, 1, 1, 1, 4 );
423 l->addWidget( aNodesLine, 2, 0, 1, 5 );
424 l->addWidget( aNodesLab, 3, 0 );
425 l->addWidget( aNodes, 3, 1 );
426 l->addWidget( aElemLine, 4, 0, 1, 5 );
427 l->addWidget( aElemLab, 5, 0 );
428 l->addWidget( aElemTotal, 5, 1 );
429 l->addWidget( aElemLin, 5, 2 );
430 l->addWidget( aElemQuad, 5, 3 );
431 l->addWidget( aElemBiQuad, 5, 4 );
432 l->addWidget( aNbLine, 6, 1, 1, 4 );
433 l->addWidget( aNbTotal, 7, 1 );
434 l->addWidget( aNbLin, 7, 2 );
435 l->addWidget( aNbQuad, 7, 3 );
436 l->addWidget( aNbBiQuad, 7, 4 );
437 l->addWidget( a0DLine, 8, 1, 1, 4 );
438 l->addWidget( a0DLab, 9, 0 );
439 l->addWidget( a0DTotal, 9, 1 );
440 l->addWidget( aBallLine, 10, 1, 1, 4 );
441 l->addWidget( aBallLab, 11, 0 );
442 l->addWidget( aBallTotal, 11, 1 );
443 l->addWidget( a1DLine, 12, 1, 1, 4 );
444 l->addWidget( a1DLab, 13, 0 );
445 l->addWidget( a1DTotal, 13, 1 );
446 l->addWidget( a1DLin, 13, 2 );
447 l->addWidget( a1DQuad, 13, 3 );
448 l->addWidget( a2DLine, 14, 1, 1, 4 );
449 l->addWidget( a2DLab, 15, 0 );
450 l->addWidget( a2DTotal, 15, 1 );
451 l->addWidget( a2DLin, 15, 2 );
452 l->addWidget( a2DQuad, 15, 3 );
453 l->addWidget( a2DBiQuad, 15, 4 );
454 l->addWidget( a2DTriLab, 16, 0 );
455 l->addWidget( a2DTriTotal, 16, 1 );
456 l->addWidget( a2DTriLin, 16, 2 );
457 l->addWidget( a2DTriQuad, 16, 3 );
458 l->addWidget( a2DTriBiQuad, 16, 4 );
459 l->addWidget( a2DQuaLab, 17, 0 );
460 l->addWidget( a2DQuaTotal, 17, 1 );
461 l->addWidget( a2DQuaLin, 17, 2 );
462 l->addWidget( a2DQuaQuad, 17, 3 );
463 l->addWidget( a2DQuaBiQuad, 17, 4 );
464 l->addWidget( a2DPolLab, 18, 0 );
465 l->addWidget( a2DPolTotal, 18, 1 );
466 l->addWidget( a2DPolLin, 18, 2 );
467 l->addWidget( a2DPolQuad, 18, 3 );
468 l->addWidget( a3DLine, 19, 1, 1, 4 );
469 l->addWidget( a3DLab, 20, 0 );
470 l->addWidget( a3DTotal, 20, 1 );
471 l->addWidget( a3DLin, 20, 2 );
472 l->addWidget( a3DQuad, 20, 3 );
473 l->addWidget( a3DBiQuad, 20, 4 );
474 l->addWidget( a3DTetLab, 21, 0 );
475 l->addWidget( a3DTetTotal, 21, 1 );
476 l->addWidget( a3DTetLin, 21, 2 );
477 l->addWidget( a3DTetQuad, 21, 3 );
478 l->addWidget( a3DHexLab, 22, 0 );
479 l->addWidget( a3DHexTotal, 22, 1 );
480 l->addWidget( a3DHexLin, 22, 2 );
481 l->addWidget( a3DHexQuad, 22, 3 );
482 l->addWidget( a3DHexBiQuad, 22, 4 );
483 l->addWidget( a3DPyrLab, 23, 0 );
484 l->addWidget( a3DPyrTotal, 23, 1 );
485 l->addWidget( a3DPyrLin, 23, 2 );
486 l->addWidget( a3DPyrQuad, 23, 3 );
487 l->addWidget( a3DPriLab, 24, 0 );
488 l->addWidget( a3DPriTotal, 24, 1 );
489 l->addWidget( a3DPriLin, 24, 2 );
490 l->addWidget( a3DPriQuad, 24, 3 );
491 l->addWidget( a3DHexPriLab, 25, 0 );
492 l->addWidget( a3DHexPriTotal, 25, 1 );
493 l->addWidget( a3DPolLab, 26, 0 );
494 l->addWidget( a3DPolTotal, 26, 1 );
495 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
497 l->setColumnStretch( 0, 0 );
498 l->setColumnStretch( 1, 5 );
499 l->setColumnStretch( 2, 5 );
500 l->setColumnStretch( 3, 5 );
501 l->setColumnStretch( 4, 5 );
502 l->setRowStretch( 27, 5 );
510 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
515 \brief Show information on the mesh object.
516 \param obj object being processed (mesh, sub-mesh, group, ID source)
518 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
521 if ( !CORBA::is_nil( obj ) ) {
522 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
524 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
525 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
526 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
527 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
528 if ( !aMesh->_is_nil() ) {
529 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
531 else if ( !aSubMesh->_is_nil() ) {
532 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
534 else if ( !aGroup->_is_nil() ) {
536 switch( aGroup->GetType() ) {
537 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
538 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
539 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
540 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
541 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
542 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
543 default: objType = tr( "OBJECT_GROUP" );break;
545 myWidgets[iObject][iSingle]->setProperty( "text", objType );
547 SMESH::long_array_var info = obj->GetMeshInfo();
548 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
549 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
550 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
551 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
552 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
553 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
554 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
555 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
556 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
557 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
558 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
559 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
560 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
561 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
563 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
564 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
565 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
566 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
567 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
568 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
569 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
570 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
571 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
572 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
573 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
574 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
575 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
576 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
577 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
578 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
579 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
580 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
581 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
582 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
583 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
584 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
585 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
586 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
587 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
588 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
589 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
590 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
591 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
592 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
593 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
594 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
595 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
596 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
597 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
598 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
599 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
600 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
601 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
602 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
603 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
604 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
605 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
606 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
607 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
608 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
609 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
610 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
611 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
612 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
613 // before full loading from study file, type of elements in a sub-mesh can't be defined
615 bool infoOK = obj->IsMeshInfoCorrect();
616 myLoadBtn->setVisible( !infoOK );
620 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
621 // 2. No info at all (for a group on geom or filter)
622 bool hasAnyInfo = false;
623 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
624 hasAnyInfo = info[i];
625 if ( hasAnyInfo ) // believe it is a sub-mesh
627 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
629 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
630 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
631 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
632 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
633 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
634 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
635 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
636 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
637 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
638 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
640 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
643 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
644 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
645 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
648 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
650 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
651 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
652 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
653 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
654 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
655 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
656 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
661 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
662 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
667 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
668 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
669 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
670 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
671 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
676 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
677 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
678 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
679 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
681 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
682 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
683 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
684 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
685 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
686 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
687 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
688 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
690 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
691 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
692 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
694 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
695 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
696 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
697 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
698 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
699 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
700 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
703 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
704 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
706 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
707 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
712 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
713 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
714 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
715 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
716 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
723 \brief Load mesh from a study file
725 void SMESHGUI_MeshInfo::loadMesh()
727 SUIT_OverrideCursor wc;
729 SALOME_ListIO selected;
730 SMESHGUI::selectionMgr()->selectedObjects( selected );
732 if ( selected.Extent() == 1 ) {
733 Handle(SALOME_InteractiveObject) IO = selected.First();
734 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
735 if ( !CORBA::is_nil( obj ) ) {
736 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
737 if ( !mesh->_is_nil() )
747 \brief Reset the widget to the initial state (nullify all fields).
749 void SMESHGUI_MeshInfo::clear()
751 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
752 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
753 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
754 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
755 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
756 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
757 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
758 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
759 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
760 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
761 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
762 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
763 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
764 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
765 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
766 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
767 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
768 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
769 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
770 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
771 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ) );
772 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
773 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
774 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
775 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
776 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
777 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
778 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
779 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
780 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
781 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
782 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
783 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
784 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
785 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
786 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
787 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
788 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
789 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
790 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
791 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
792 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
793 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
794 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
795 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
796 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
800 \brief Create info field
801 \return new info field
803 QLabel* SMESHGUI_MeshInfo::createField()
805 QLabel* lab = new QLabel( this );
806 lab->setFrameStyle( StyledPanel | Sunken );
807 lab->setAlignment( Qt::AlignCenter );
808 lab->setAutoFillBackground( true );
809 QPalette pal = lab->palette();
810 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
811 lab->setPalette( pal );
812 lab->setMinimumWidth( 70 );
817 \brief Create horizontal rule.
818 \return new line object
820 QWidget* SMESHGUI_MeshInfo::createLine()
822 QFrame* line = new QFrame( this );
823 line->setFrameStyle( HLine | Sunken );
828 \brief Change widget font attributes (bold, italic, ...).
830 \param attr font attributes (XORed flags)
831 \param val value to be set to attributes
833 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
837 if ( attr & Bold ) f.setBold( val );
838 if ( attr & Italic ) f.setItalic( val );
844 \brief Show/hide group(s) of fields.
845 \param start beginning of the block
846 \param end end of the block
847 \param on visibility flag
849 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
851 start = qMax( 0, start );
852 end = qMin( end, (int)iElementsEnd );
853 for ( int i = start; i < end; i++ ) {
854 wlist wl = myWidgets[i];
855 foreach ( QWidget* w, wl ) w->setVisible( on );
859 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
861 out << QString( 9, '-' ) << "\n";
862 out << tr( "BASE_INFO" ) << "\n";
863 out << QString( 9, '-' ) << "\n";
864 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
865 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
866 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
867 out << tr( "ELEMENTS_LAB" ) << "\n";
868 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
869 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
870 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
871 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
872 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
873 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
874 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
875 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
876 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
877 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
878 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
879 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
880 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
881 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
883 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
886 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
887 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
888 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
889 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
890 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
891 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
895 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
899 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
900 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
901 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
903 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
904 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
906 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
907 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
909 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
910 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
911 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
913 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
915 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
917 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
920 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
921 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
923 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
924 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
928 \class SMESHGUI_ElemInfo
929 \brief Base class for the mesh element information widget.
934 \param parent parent widget
936 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
937 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
939 myFrame = new QWidget( this );
940 myExtra = new ExtraWidget( this );
941 QVBoxLayout* vbl = new QVBoxLayout( this );
943 vbl->setSpacing( 0 );
944 vbl->addWidget( myFrame );
945 vbl->addWidget( myExtra );
946 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
947 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
954 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
959 \brief Set mesh data source (actor)
960 \param actor mesh object actor
962 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
964 if ( myActor != actor ) {
972 \brief Show mesh element information
973 \param id mesh node / element ID
974 \param isElem show mesh element information if \c true or mesh node information if \c false
976 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
980 showInfo( ids, isElem );
984 \brief Show mesh element information
985 \param ids mesh nodes / elements identifiers
986 \param isElem show mesh element information if \c true or mesh node information if \c false
988 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
990 QList<long> newIds = ids.toList();
992 if ( myIDs == newIds && myIsElement == isElem ) return;
995 myIsElement = isElem;
998 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1002 \brief Clear mesh element information widget
1004 void SMESHGUI_ElemInfo::clear()
1013 \brief Get central area widget
1014 \return central widget
1016 QWidget* SMESHGUI_ElemInfo::frame() const
1023 \return actor being used
1025 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1031 \brief Get current info mode.
1032 \return \c true if mesh element information is shown or \c false if node information is shown
1034 bool SMESHGUI_ElemInfo::isElements() const
1040 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1041 \brief Show information on the specified nodes / elements
1043 This function is to be redefined in sub-classes.
1045 \param ids nodes / elements identifiers information is to be shown on
1049 \brief Internal clean-up (reset widget)
1051 void SMESHGUI_ElemInfo::clearInternal()
1056 \brief Get node connectivity
1057 \param node mesh node
1058 \return node connectivity map
1060 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1064 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1065 while ( it && it->more() ) {
1066 const SMDS_MeshElement* ne = it->next();
1067 elmap[ ne->GetType() ] << ne->GetID();
1074 \brief Format connectivity data to string representation
1075 \param connectivity connetivity map
1076 \param type element type
1077 \return string representation of the connectivity
1079 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1082 if ( connectivity.contains( type ) ) {
1083 QList<int> elements = connectivity[ type ];
1085 foreach( int id, elements )
1086 str << QString::number( id );
1088 return str.join( " " );
1092 \brief Calculate gravity center of the mesh element
1093 \param element mesh element
1095 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1099 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1100 while ( nodeIt->more() ) {
1101 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1102 xyz.add( node->X(), node->Y(), node->Z() );
1104 xyz.divide( element->NbNodes() );
1110 \brief Calculate normal vector to the mesh face
1111 \param element mesh face
1113 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1115 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1116 return XYZ(n.X(), n.Y(), n.Z());
1120 \brief This slot is called from "Show Previous" button click.
1121 Shows information on the previous group of the items.
1123 void SMESHGUI_ElemInfo::showPrevious()
1125 myIndex = qMax( 0, myIndex-1 );
1127 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1131 \brief This slot is called from "Show Next" button click.
1132 Shows information on the next group of the items.
1134 void SMESHGUI_ElemInfo::showNext()
1136 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1138 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1142 \brief Update widgets state
1144 void SMESHGUI_ElemInfo::updateControls()
1146 myExtra->updateControls( myIDs.count(), myIndex );
1150 \class SMESHGUI_SimpleElemInfo
1151 \brief Represents mesh element information in the simple text area.
1156 \param parent parent widget
1158 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1159 : SMESHGUI_ElemInfo( parent )
1161 myInfo = new QTextBrowser( frame() );
1162 QVBoxLayout* l = new QVBoxLayout( frame() );
1164 l->addWidget( myInfo );
1168 \brief Show mesh element information
1169 \param ids mesh nodes / elements identifiers
1171 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1176 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1177 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1178 int cprecision = -1;
1179 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1180 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1181 foreach ( long id, ids ) {
1182 if ( !isElements() ) {
1186 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1187 if ( !node ) return;
1190 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1192 myInfo->append( "" );
1194 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1195 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1196 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1197 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1199 myInfo->append( "" );
1201 Connectivity connectivity = nodeConnectivity( node );
1202 if ( !connectivity.isEmpty() ) {
1203 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1204 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1205 if ( !con.isEmpty() )
1206 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1207 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1208 if ( !con.isEmpty() )
1209 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1210 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1211 if ( !con.isEmpty() )
1212 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1213 con = formatConnectivity( connectivity, SMDSAbs_Face );
1214 if ( !con.isEmpty() )
1215 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1216 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1217 if ( !con.isEmpty() )
1218 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1221 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1224 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1225 if ( !CORBA::is_nil( aMeshPtr ) ) {
1226 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1227 int shapeID = pos->shapeID;
1228 if ( shapeID > 0 ) {
1230 double u = 0, v = 0;
1231 switch ( pos->shapeType ) {
1233 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1234 if ( pos->params.length() == 1 )
1238 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1239 if ( pos->params.length() == 2 ) {
1245 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1248 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1252 myInfo->append( "" );
1253 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1254 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1255 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1256 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1257 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1258 if ( pos->shapeType == GEOM::FACE ) {
1259 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1260 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1265 // groups node belongs to
1266 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1267 if ( !CORBA::is_nil( aMesh ) ) {
1268 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1269 myInfo->append( "" ); // separator
1270 bool top_created = false;
1271 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1272 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1273 if ( CORBA::is_nil( aGrp ) ) continue;
1274 QString aName = aGrp->GetName();
1275 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1276 if ( !top_created ) {
1277 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1280 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1281 if ( grp_details ) {
1282 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1283 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1284 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1286 // type : group on geometry, standalone group, group on filter
1287 if ( !CORBA::is_nil( aStdGroup ) ) {
1288 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1289 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1291 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1292 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1293 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1294 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1295 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1297 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1298 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1301 else if ( !CORBA::is_nil( aFltGroup ) ) {
1302 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1303 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1307 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1308 arg( QString::number( aGrp->Size() ) ) );
1311 SALOMEDS::Color color = aGrp->GetColor();
1312 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1313 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1321 // show element info
1323 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1324 SMESH::Controls::NumericalFunctorPtr afunctor;
1327 // Element ID && Type
1329 switch( e->GetType() ) {
1330 case SMDSAbs_0DElement:
1331 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1333 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1335 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1337 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1338 case SMDSAbs_Volume:
1339 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1343 if ( stype.isEmpty() ) return;
1344 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1346 myInfo->append( "" );
1350 switch( e->GetEntityType() ) {
1351 case SMDSEntity_Triangle:
1352 case SMDSEntity_Quad_Triangle:
1353 case SMDSEntity_BiQuad_Triangle:
1354 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1355 case SMDSEntity_Quadrangle:
1356 case SMDSEntity_Quad_Quadrangle:
1357 case SMDSEntity_BiQuad_Quadrangle:
1358 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1359 case SMDSEntity_Polygon:
1360 case SMDSEntity_Quad_Polygon:
1361 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1362 case SMDSEntity_Tetra:
1363 case SMDSEntity_Quad_Tetra:
1364 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1365 case SMDSEntity_Pyramid:
1366 case SMDSEntity_Quad_Pyramid:
1367 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1368 case SMDSEntity_Hexa:
1369 case SMDSEntity_Quad_Hexa:
1370 case SMDSEntity_TriQuad_Hexa:
1371 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1372 case SMDSEntity_Penta:
1373 case SMDSEntity_Quad_Penta:
1374 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1375 case SMDSEntity_Hexagonal_Prism:
1376 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1377 case SMDSEntity_Polyhedra:
1378 case SMDSEntity_Quad_Polyhedra:
1379 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1383 if ( !gtype.isEmpty() )
1384 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1386 // Quadratic flag (any element except 0D)
1387 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1388 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1390 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1392 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1395 myInfo->append( "" );
1398 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1399 for ( int idx = 1; nodeIt->more(); idx++ ) {
1400 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1401 // node number and ID
1402 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1404 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1405 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1406 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1407 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1408 // node connectivity
1409 Connectivity connectivity = nodeConnectivity( node );
1410 if ( !connectivity.isEmpty() ) {
1411 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1412 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1413 if ( !con.isEmpty() )
1414 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1415 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1416 if ( !con.isEmpty() )
1417 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1418 con = formatConnectivity( connectivity, SMDSAbs_Face );
1419 if ( !con.isEmpty() )
1420 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1421 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1422 if ( !con.isEmpty() )
1423 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1426 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1430 myInfo->append( "" );
1433 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1435 if ( e->GetType() == SMDSAbs_Edge ) {
1436 afunctor.reset( new SMESH::Controls::Length() );
1437 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1438 afunctor->SetPrecision( cprecision );
1439 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1441 if( e->GetType() == SMDSAbs_Face ) {
1443 afunctor.reset( new SMESH::Controls::Area() );
1444 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1445 afunctor->SetPrecision( cprecision );
1446 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1448 afunctor.reset( new SMESH::Controls::Taper() );
1449 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1450 afunctor->SetPrecision( cprecision );
1451 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1453 afunctor.reset( new SMESH::Controls::AspectRatio() );
1454 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1455 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1457 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1458 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1459 afunctor->SetPrecision( cprecision );
1460 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1462 afunctor.reset( new SMESH::Controls::Warping() );
1463 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1464 afunctor->SetPrecision( cprecision );
1465 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1467 afunctor.reset( new SMESH::Controls::Skew() );
1468 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1469 afunctor->SetPrecision( cprecision );
1470 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1472 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1473 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1474 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1476 if( e->GetType() == SMDSAbs_Volume ) {
1478 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1479 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1480 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1482 afunctor.reset( new SMESH::Controls::Volume() );
1483 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1484 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1486 afunctor.reset( new SMESH::Controls::Volume() );
1487 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1488 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1491 myInfo->append( "" );
1494 XYZ gc = gravityCenter( e );
1495 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1498 if( e->GetType() == SMDSAbs_Face ) {
1499 XYZ gc = normal( e );
1500 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1504 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1505 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1506 if ( !CORBA::is_nil( aMesh ) ) {
1507 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1508 int shapeID = pos.shapeID;
1509 if ( shapeID > 0 ) {
1510 myInfo->append( "" ); // separator
1512 switch ( pos.shapeType ) {
1513 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1514 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1515 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1516 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1517 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1518 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1520 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1525 // Groups the element belongs to
1526 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1527 if ( !CORBA::is_nil( aMesh ) ) {
1528 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1529 myInfo->append( "" ); // separator
1530 bool top_created = false;
1531 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1532 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1533 if ( CORBA::is_nil( aGrp ) ) continue;
1534 QString aName = aGrp->GetName();
1535 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1536 if ( !top_created ) {
1537 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1540 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1541 if ( grp_details ) {
1542 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1543 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1544 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1546 // type : group on geometry, standalone group, group on filter
1547 if ( !CORBA::is_nil( aStdGroup ) ) {
1548 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1549 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1551 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1552 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1553 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1554 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1555 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1557 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1558 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1561 else if ( !CORBA::is_nil( aFltGroup ) ) {
1562 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1563 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1566 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1567 arg( QString::number( aGrp->Size() ) ) );
1570 SALOMEDS::Color color = aGrp->GetColor();
1571 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1572 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1579 if ( ids.count() > 1 ) {
1580 myInfo->append( "" );
1581 myInfo->append( "------" );
1582 myInfo->append( "" );
1589 \brief Internal clean-up (reset widget)
1591 void SMESHGUI_SimpleElemInfo::clearInternal()
1596 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1598 out << QString( 12, '-' ) << "\n";
1599 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1600 out << QString( 12, '-' ) << "\n";
1601 out << myInfo->toPlainText();
1607 \class SMESHGUI_TreeElemInfo::ItemDelegate
1608 \brief Item delegate for tree mesh info widget
1611 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1614 ItemDelegate( QObject* );
1615 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1622 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1627 \brief Create item editor widget
1630 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1632 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1633 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1638 \class SMESHGUI_TreeElemInfo
1639 \brief Represents mesh element information in the tree-like form.
1644 \param parent parent widget
1646 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1647 : SMESHGUI_ElemInfo( parent )
1649 myInfo = new QTreeWidget( frame() );
1650 myInfo->setColumnCount( 2 );
1651 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1652 myInfo->header()->setStretchLastSection( true );
1653 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 ) {
1750 double u = 0, v = 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 SUIT_OverrideCursor wc;
2324 QTreeWidgetItem* item = myItem;
2326 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2327 item->treeWidget()->removeItemWidget( item, 1 );
2328 item->setText( 1, QString::number( nb ));
2333 \class SMESHGUI_AddInfo
2334 \brief The wigdet shows additional information on the mesh object.
2339 \param parent parent widget
2341 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2342 : QTreeWidget( parent )
2344 setColumnCount( 2 );
2345 header()->setStretchLastSection( true );
2346 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2353 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2358 \brief Show additional information on the selected object
2359 \param obj object being processed (mesh, sub-mesh, group, ID source)
2361 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2363 setProperty( "group_index", 0 );
2364 setProperty( "submesh_index", 0 );
2365 myComputors.clear();
2368 if ( CORBA::is_nil( obj ) ) return;
2370 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2371 if ( !sobj ) return;
2374 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2375 nameItem->setText( 0, tr( "NAME" ) );
2376 nameItem->setText( 1, sobj->GetName().c_str() );
2378 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2379 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2380 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2382 if ( !aMesh->_is_nil() )
2383 meshInfo( aMesh, nameItem );
2384 else if ( !aSubMesh->_is_nil() )
2385 subMeshInfo( aSubMesh, nameItem );
2386 else if ( !aGroup->_is_nil() )
2387 groupInfo( aGroup.in(), nameItem );
2391 \brief Create new tree item.
2392 \param parent parent tree widget item
2393 \param flags item flag
2394 \return new tree widget item
2396 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2398 QTreeWidgetItem* item;
2401 item = new QTreeWidgetItem( parent );
2403 item = new QTreeWidgetItem( this );
2405 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2407 QFont f = item->font( 0 );
2409 for ( int i = 0; i < columnCount(); i++ ) {
2410 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2411 item->setFont( i, f );
2414 item->setExpanded( true );
2419 \brief Show mesh info
2420 \param mesh mesh object
2421 \param parent parent tree item
2423 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2426 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2427 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2428 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2429 typeItem->setText( 0, tr( "TYPE" ) );
2430 if ( !CORBA::is_nil( shape ) ) {
2431 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2432 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2434 QTreeWidgetItem* gobjItem = createItem( typeItem );
2435 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2436 gobjItem->setText( 1, sobj->GetName().c_str() );
2439 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2440 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2441 QTreeWidgetItem* fileItem = createItem( typeItem );
2442 fileItem->setText( 0, tr( "FILE_NAME" ) );
2443 fileItem->setText( 1, (char*)inf->fileName );
2446 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2450 myGroups = mesh->GetGroups();
2454 mySubMeshes = mesh->GetSubMeshes();
2459 \brief Show sub-mesh info
2460 \param subMesh sub-mesh object
2461 \param parent parent tree item
2463 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2465 bool isShort = parent->parent() != 0;
2469 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2471 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2472 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2473 nameItem->setText( 1, sobj->GetName().c_str() );
2478 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2479 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2481 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2482 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2483 gobjItem->setText( 1, sobj->GetName().c_str() );
2488 \brief Show group info
2489 \param grp mesh group object
2490 \param parent parent tree item
2492 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2494 bool isShort = parent->parent() != 0;
2496 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2497 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2498 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2502 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2504 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2505 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2506 nameItem->setText( 1, sobj->GetName().c_str() );
2510 // type : group on geometry, standalone group, group on filter
2511 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2512 typeItem->setText( 0, tr( "TYPE" ) );
2513 if ( !CORBA::is_nil( aStdGroup ) ) {
2514 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2516 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2517 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2518 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2519 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2521 QTreeWidgetItem* gobjItem = createItem( typeItem );
2522 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2523 gobjItem->setText( 1, sobj->GetName().c_str() );
2526 else if ( !CORBA::is_nil( aFltGroup ) ) {
2527 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2532 QString etype = tr( "UNKNOWN" );
2533 switch( grp->GetType() ) {
2535 etype = tr( "NODE" );
2538 etype = tr( "EDGE" );
2541 etype = tr( "FACE" );
2544 etype = tr( "VOLUME" );
2547 etype = tr( "0DELEM" );
2550 etype = tr( "BALL" );
2555 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2556 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2557 etypeItem->setText( 1, etype );
2560 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2561 bool meshLoaded = mesh->IsLoaded();
2563 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2565 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2566 groupSize = grp->Size();
2568 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2569 sizeItem->setText( 0, tr( "SIZE" ) );
2570 if ( groupSize > -1 ) {
2571 sizeItem->setText( 1, QString::number( groupSize ) );
2574 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2575 setItemWidget( sizeItem, 1, btn );
2576 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2577 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2578 myComputors.append( comp );
2580 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2584 SALOMEDS::Color color = grp->GetColor();
2585 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2586 colorItem->setText( 0, tr( "COLOR" ) );
2587 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2589 // nb of underlying nodes
2590 if ( grp->GetType() != SMESH::NODE) {
2591 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2592 nodesItem->setText( 0, tr( "NB_NODES" ) );
2593 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2594 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2595 if ( toShowNodes && meshLoaded ) {
2596 // already calculated and up-to-date
2597 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2600 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2601 setItemWidget( nodesItem, 1, btn );
2602 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2603 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2604 myComputors.append( comp );
2606 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2611 void SMESHGUI_AddInfo::showGroups()
2613 myComputors.clear();
2615 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2616 if ( !parent ) return;
2618 int idx = property( "group_index" ).toInt();
2620 QTreeWidgetItem* itemGroups = 0;
2621 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2622 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2623 itemGroups = parent->child( i );
2624 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2626 extra->updateControls( myGroups->length(), idx );
2627 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2631 QMap<int, QTreeWidgetItem*> grpItems;
2632 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2633 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2634 if ( CORBA::is_nil( grp ) ) continue;
2635 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2636 if ( !grpSObj ) continue;
2638 int grpType = grp->GetType();
2640 if ( !itemGroups ) {
2641 // create top-level groups container item
2642 itemGroups = createItem( parent, Bold | All );
2643 itemGroups->setText( 0, tr( "GROUPS" ) );
2644 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2646 // total number of groups > 10, show extra widgets for info browsing
2647 if ((int) myGroups->length() > MAXITEMS ) {
2648 ExtraWidget* extra = new ExtraWidget( this, true );
2649 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2650 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2651 setItemWidget( itemGroups, 1, extra );
2652 extra->updateControls( myGroups->length(), idx );
2656 if ( grpItems.find( grpType ) == grpItems.end() ) {
2657 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2658 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2659 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2663 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2664 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2667 groupInfo( grp.in(), grpNameItem );
2671 void SMESHGUI_AddInfo::showSubMeshes()
2673 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2674 if ( !parent ) return;
2676 int idx = property( "submesh_index" ).toInt();
2678 QTreeWidgetItem* itemSubMeshes = 0;
2679 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2680 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2681 itemSubMeshes = parent->child( i );
2682 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2684 extra->updateControls( mySubMeshes->length(), idx );
2685 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2689 QMap<int, QTreeWidgetItem*> smItems;
2690 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2691 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2692 if ( CORBA::is_nil( sm ) ) continue;
2693 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2694 if ( !smSObj ) continue;
2696 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2697 if ( CORBA::is_nil(gobj ) ) continue;
2699 int smType = gobj->GetShapeType();
2700 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2702 if ( !itemSubMeshes ) {
2703 itemSubMeshes = createItem( parent, Bold | All );
2704 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2705 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2707 // total number of sub-meshes > 10, show extra widgets for info browsing
2708 if ((int) mySubMeshes->length() > MAXITEMS ) {
2709 ExtraWidget* extra = new ExtraWidget( this, true );
2710 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2711 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2712 setItemWidget( itemSubMeshes, 1, extra );
2713 extra->updateControls( mySubMeshes->length(), idx );
2717 if ( smItems.find( smType ) == smItems.end() ) {
2718 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2719 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2720 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2724 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2725 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2728 subMeshInfo( sm.in(), smNameItem );
2733 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2735 void SMESHGUI_AddInfo::changeLoadToCompute()
2737 for ( int i = 0; i < myComputors.count(); ++i )
2739 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2741 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2742 btn->setText( tr("COMPUTE") );
2747 void SMESHGUI_AddInfo::showPreviousGroups()
2749 int idx = property( "group_index" ).toInt();
2750 setProperty( "group_index", idx-1 );
2754 void SMESHGUI_AddInfo::showNextGroups()
2756 int idx = property( "group_index" ).toInt();
2757 setProperty( "group_index", idx+1 );
2761 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2763 int idx = property( "submesh_index" ).toInt();
2764 setProperty( "submesh_index", idx-1 );
2768 void SMESHGUI_AddInfo::showNextSubMeshes()
2770 int idx = property( "submesh_index" ).toInt();
2771 setProperty( "submesh_index", idx+1 );
2775 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2777 out << QString( 15, '-') << "\n";
2778 out << tr( "ADDITIONAL_INFO" ) << "\n";
2779 out << QString( 15, '-' ) << "\n";
2780 QTreeWidgetItemIterator it( this );
2782 if ( !( ( *it )->text(0) ).isEmpty() ) {
2783 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2784 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2785 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2787 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2796 \class SMESHGUI_MeshInfoDlg
2797 \brief Mesh information dialog box
2802 \param parent parent widget
2803 \param page specifies the dialog page to be shown at the start-up
2805 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2806 : QDialog( parent ), myActor( 0 )
2809 setAttribute( Qt::WA_DeleteOnClose, true );
2810 setWindowTitle( tr( "MESH_INFO" ) );
2811 setSizeGripEnabled( true );
2813 myTabWidget = new QTabWidget( this );
2817 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2818 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2822 QWidget* w = new QWidget( myTabWidget );
2824 myMode = new QButtonGroup( this );
2825 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2826 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2827 myMode->button( NodeMode )->setChecked( true );
2828 myID = new QLineEdit( w );
2829 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2831 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2832 mode = qMin( 1, qMax( 0, mode ) );
2835 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2837 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2839 QGridLayout* elemLayout = new QGridLayout( w );
2840 elemLayout->setMargin( MARGIN );
2841 elemLayout->setSpacing( SPACING );
2842 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2843 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2844 elemLayout->addWidget( myID, 0, 2 );
2845 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2847 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2851 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2852 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2856 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2857 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2861 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2862 okBtn->setAutoDefault( true );
2863 okBtn->setDefault( true );
2865 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2866 dumpBtn->setAutoDefault( true );
2867 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2868 helpBtn->setAutoDefault( true );
2870 QHBoxLayout* btnLayout = new QHBoxLayout;
2871 btnLayout->setSpacing( SPACING );
2872 btnLayout->setMargin( 0 );
2874 btnLayout->addWidget( okBtn );
2875 btnLayout->addWidget( dumpBtn );
2876 btnLayout->addStretch( 10 );
2877 btnLayout->addWidget( helpBtn );
2879 QVBoxLayout* l = new QVBoxLayout ( this );
2880 l->setMargin( MARGIN );
2881 l->setSpacing( SPACING );
2882 l->addWidget( myTabWidget );
2883 l->addLayout( btnLayout );
2885 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2887 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2888 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2889 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2890 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2891 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2892 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2893 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2894 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2895 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2896 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2904 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2909 \brief Show mesh information
2910 \param IO interactive object
2912 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2914 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2915 if ( !CORBA::is_nil( obj ) ) {
2916 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2917 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2918 myCtrlInfo->showInfo( obj );
2920 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2921 SVTK_Selector* selector = SMESH::GetSelector();
2924 if ( myActor && selector ) {
2925 nb = myMode->checkedId() == NodeMode ?
2926 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2927 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2929 myElemInfo->setSource( myActor ) ;
2931 myID->setText( ID.trimmed() );
2933 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2934 foreach ( ID, idTxt )
2935 ids << ID.trimmed().toLong();
2936 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2940 myElemInfo->clear();
2946 \brief Perform clean-up actions on the dialog box closing.
2948 void SMESHGUI_MeshInfoDlg::reject()
2950 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2951 selMgr->clearFilters();
2952 SMESH::SetPointRepresentation( false );
2953 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2954 aViewWindow->SetSelectionMode( ActorSelection );
2959 \brief Process keyboard event
2960 \param e key press event
2962 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2964 QDialog::keyPressEvent( e );
2965 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2972 \brief Reactivate dialog box, when mouse pointer goes into it.
2974 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2980 \brief Setup selection mode depending on the current dialog box state.
2982 void SMESHGUI_MeshInfoDlg::updateSelection()
2984 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2986 disconnect( selMgr, 0, this, 0 );
2987 selMgr->clearFilters();
2989 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2990 SMESH::SetPointRepresentation( false );
2991 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2992 aViewWindow->SetSelectionMode( ActorSelection );
2995 if ( myMode->checkedId() == NodeMode ) {
2996 SMESH::SetPointRepresentation( true );
2997 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2998 aViewWindow->SetSelectionMode( NodeSelection );
3001 SMESH::SetPointRepresentation( false );
3002 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3003 aViewWindow->SetSelectionMode( CellSelection );
3007 QString oldID = myID->text().trimmed();
3008 SMESH_Actor* oldActor = myActor;
3011 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3014 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3015 myID->setText( oldID );
3021 \brief Show help page
3023 void SMESHGUI_MeshInfoDlg::help()
3025 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3026 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3027 "mesh_infos_page.html#mesh_element_info_anchor" );
3031 \brief Show mesh information
3033 void SMESHGUI_MeshInfoDlg::updateInfo()
3035 SUIT_OverrideCursor wc;
3037 SALOME_ListIO selected;
3038 SMESHGUI::selectionMgr()->selectedObjects( selected );
3040 if ( selected.Extent() == 1 ) {
3041 Handle(SALOME_InteractiveObject) IO = selected.First();
3045 // myBaseInfo->clear();
3046 // myElemInfo->clear();
3047 // myAddInfo->clear();
3052 \brief Activate dialog box
3054 void SMESHGUI_MeshInfoDlg::activate()
3056 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3057 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3058 myTabWidget->setEnabled( true );
3063 \brief Deactivate dialog box
3065 void SMESHGUI_MeshInfoDlg::deactivate()
3067 myTabWidget->setEnabled( false );
3068 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3072 \brief Called when users switches between node / element modes.
3074 void SMESHGUI_MeshInfoDlg::modeChanged()
3081 \brief Caled when users prints mesh element ID in the corresponding field.
3083 void SMESHGUI_MeshInfoDlg::idChanged()
3085 SVTK_Selector* selector = SMESH::GetSelector();
3086 if ( myActor && selector ) {
3087 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3088 TColStd_MapOfInteger ID;
3090 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3091 foreach ( QString tid, idTxt ) {
3092 long id = tid.trimmed().toLong();
3093 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3094 myActor->GetObject()->GetMesh()->FindElement( id ) :
3095 myActor->GetObject()->GetMesh()->FindNode( id );
3101 selector->AddOrRemoveIndex( IO, ID, false );
3102 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3103 aViewWindow->highlight( IO, true, true );
3104 aViewWindow->Repaint();
3106 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3110 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3112 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3113 myMode->button( NodeMode )->click();
3114 myID->setText( QString::number( id ) );
3118 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3120 if ( !theStr.isEmpty() ) {
3121 myMode->button( ElemMode )->click();
3122 myID->setText( theStr );
3126 void SMESHGUI_MeshInfoDlg::dump()
3128 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3130 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3131 if ( !appStudy ) return;
3132 _PTR( Study ) aStudy = appStudy->studyDS();
3134 QStringList aFilters;
3135 aFilters.append( tr( "TEXT_FILES" ) );
3137 bool anIsBase = true;
3138 bool anIsElem = true;
3139 bool anIsAdd = true;
3140 bool anIsCtrl = true;
3142 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3143 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3144 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3145 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3146 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3149 DumpFileDlg fd( this );
3150 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3151 fd.setNameFilters( aFilters );
3152 fd.myBaseChk->setChecked( anIsBase );
3153 fd.myElemChk->setChecked( anIsElem );
3154 fd.myAddChk ->setChecked( anIsAdd );
3155 fd.myCtrlChk->setChecked( anIsCtrl );
3156 if ( fd.exec() == QDialog::Accepted )
3158 QString aFileName = fd.selectedFile();
3160 bool toBase = fd.myBaseChk->isChecked();
3161 bool toElem = fd.myElemChk->isChecked();
3162 bool toAdd = fd.myAddChk->isChecked();
3163 bool toCtrl = fd.myCtrlChk->isChecked();
3165 if ( !aFileName.isEmpty() ) {
3166 QFileInfo aFileInfo( aFileName );
3167 if ( aFileInfo.isDir() )
3170 QFile aFile( aFileName );
3171 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3174 QTextStream out( &aFile );
3176 if ( toBase ) myBaseInfo->saveInfo( out );
3177 if ( toElem ) myElemInfo->saveInfo( out );
3178 if ( toAdd ) myAddInfo ->saveInfo( out );
3179 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3185 \class SMESHGUI_CtrlInfo
3186 \brief Class for the mesh controls information widget.
3191 \param parent parent widget
3193 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3194 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3196 setFrameStyle( StyledPanel | Sunken );
3198 myMainLayout = new QGridLayout( this );
3199 myMainLayout->setMargin( MARGIN );
3200 myMainLayout->setSpacing( SPACING );
3203 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3204 QLabel* aName = createField();
3205 aName->setMinimumWidth( 150 );
3208 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3209 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3211 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3214 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3215 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3216 QLabel* aNodesFree = createField();
3217 myWidgets << aNodesFree;
3218 myPredicates << aFilterMgr->CreateFreeNodes();
3220 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3221 QLabel* aNodesDouble = createField();
3222 myWidgets << aNodesDouble;
3223 myPredicates << aFilterMgr->CreateEqualNodes();
3224 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3225 myToleranceWidget = new SMESHGUI_SpinBox( this );
3226 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3227 myToleranceWidget->setAcceptNames( false );
3228 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3231 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3232 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3233 QLabel* anEdgesDouble = createField();
3234 myWidgets << anEdgesDouble;
3235 myPredicates << aFilterMgr->CreateEqualEdges();
3238 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3239 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3240 QLabel* aFacesDouble = createField();
3241 myWidgets << aFacesDouble;
3242 myPredicates << aFilterMgr->CreateEqualFaces();
3243 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3244 QLabel* aFacesOver = createField();
3245 myWidgets << aFacesOver;
3246 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3247 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3248 myPlot = createPlot( this );
3249 myAspectRatio = aFilterMgr->CreateAspectRatio();
3252 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3253 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3254 QLabel* aVolumesDouble = createField();
3255 myWidgets << aVolumesDouble;
3256 myPredicates << aFilterMgr->CreateEqualVolumes();
3257 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3258 QLabel* aVolumesOver = createField();
3259 myWidgets << aVolumesOver;
3260 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3261 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3262 myPlot3D = createPlot( this );
3263 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3265 QToolButton* aFreeNodesBtn = new QToolButton( this );
3266 aFreeNodesBtn->setIcon(aComputeIcon);
3267 myButtons << aFreeNodesBtn; //0
3269 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3270 aDoubleNodesBtn->setIcon(aComputeIcon);
3271 myButtons << aDoubleNodesBtn; //1
3273 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3274 aDoubleEdgesBtn->setIcon(aComputeIcon);
3275 myButtons << aDoubleEdgesBtn; //2
3277 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3278 aDoubleFacesBtn->setIcon(aComputeIcon);
3279 myButtons << aDoubleFacesBtn; //3
3281 QToolButton* aOverContFacesBtn = new QToolButton( this );
3282 aOverContFacesBtn->setIcon(aComputeIcon);
3283 myButtons << aOverContFacesBtn; //4
3285 QToolButton* aComputeFaceBtn = new QToolButton( this );
3286 aComputeFaceBtn->setIcon(aComputeIcon);
3287 myButtons << aComputeFaceBtn; //5
3289 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3290 aDoubleVolumesBtn->setIcon(aComputeIcon);
3291 myButtons << aDoubleVolumesBtn; //6
3293 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3294 aOverContVolumesBtn->setIcon(aComputeIcon);
3295 myButtons << aOverContVolumesBtn; //7
3297 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3298 aComputeVolumeBtn->setIcon(aComputeIcon);
3299 myButtons << aComputeVolumeBtn; //8
3301 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3302 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3303 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3304 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3305 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3306 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3307 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3308 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3309 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3310 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3312 setFontAttributes( aNameLab );
3313 setFontAttributes( aNodesLab );
3314 setFontAttributes( anEdgesLab );
3315 setFontAttributes( aFacesLab );
3316 setFontAttributes( aVolumesLab );
3318 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3319 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3320 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3321 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3322 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3323 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3324 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3325 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3326 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3327 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3328 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3329 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3330 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3331 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3332 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3333 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3334 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3335 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3336 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3337 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3338 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3339 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3340 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3341 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3342 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3343 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3344 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3345 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3346 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3347 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3348 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3349 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3350 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3351 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3352 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3354 myMainLayout->setColumnStretch( 0, 0 );
3355 myMainLayout->setColumnStretch( 1, 5 );
3356 myMainLayout->setRowStretch ( 11, 5 );
3357 myMainLayout->setRowStretch ( 16, 5 );
3358 myMainLayout->setRowStretch ( 17, 1 );
3366 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3370 \brief Change widget font attributes (bold, ...).
3372 \param attr font attributes (XORed flags)
3374 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3377 QFont f = w->font();
3384 \brief Create info field
3385 \return new info field
3387 QLabel* SMESHGUI_CtrlInfo::createField()
3389 QLabel* lab = new QLabel( this );
3390 lab->setFrameStyle( StyledPanel | Sunken );
3391 lab->setAlignment( Qt::AlignCenter );
3392 lab->setAutoFillBackground( true );
3393 QPalette pal = lab->palette();
3394 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3395 lab->setPalette( pal );
3396 lab->setMinimumWidth( 60 );
3401 \brief Create QwtPlot
3404 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3406 QwtPlot* aPlot = new QwtPlot( parent );
3407 aPlot->setMinimumSize( 100, 100 );
3408 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3409 xFont.setPointSize( 5 );
3410 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3411 yFont.setPointSize( 5 );
3412 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3413 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3419 \brief Show controls information on the selected object
3421 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3425 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3426 if ( myObject->_is_nil() ) return;
3428 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3429 myWidgets[0]->setText( aSO->GetName().c_str() );
3431 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3432 if ( mesh->_is_nil() ) return;
3434 const bool meshLoaded = mesh->IsLoaded();
3435 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3436 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3437 for ( int i = 0; i < myButtons.count(); ++i )
3438 myButtons[i]->setEnabled( true );
3440 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3441 if ( ! &nbElemsByType.in() ) return;
3443 const CORBA::Long ctrlLimit =
3444 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3447 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3448 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3449 nbElemsByType[ SMESH::FACE ] +
3450 nbElemsByType[ SMESH::VOLUME ] );
3451 if ( nbNodes + nbElems > 0 ) {
3452 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3454 computeFreeNodesInfo();
3456 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3457 computeDoubleNodesInfo();
3460 myButtons[0]->setEnabled( true );
3461 myButtons[1]->setEnabled( true );
3465 for( int i=2; i<=10; i++)
3466 myMainLayout->itemAt(i)->widget()->setVisible( false );
3470 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3472 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3473 computeDoubleEdgesInfo();
3475 myButtons[2]->setEnabled( true );
3478 for( int i=11; i<=14; i++)
3479 myMainLayout->itemAt(i)->widget()->setVisible( false );
3483 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3484 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3486 computeDoubleFacesInfo();
3487 // over constrained faces
3488 computeOverConstrainedFacesInfo();
3489 // aspect Ratio histogram
3490 computeAspectRatio();
3493 myButtons[3]->setEnabled( true );
3494 myButtons[4]->setEnabled( true );
3495 myButtons[5]->setEnabled( true );
3497 #ifdef DISABLE_PLOT2DVIEWER
3498 myMainLayout->setRowStretch(11,0);
3499 for( int i=22; i<=24; i++)
3500 myMainLayout->itemAt(i)->widget()->setVisible( false );
3504 myMainLayout->setRowStretch(11,0);
3505 for( int i=15; i<=24; i++)
3506 myMainLayout->itemAt(i)->widget()->setVisible( false );
3510 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3511 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3513 computeDoubleVolumesInfo();
3514 // over constrained volumes
3515 computeOverConstrainedVolumesInfo();
3516 // aspect Ratio 3D histogram
3517 computeAspectRatio3D();
3520 myButtons[6]->setEnabled( true );
3521 myButtons[7]->setEnabled( true );
3522 myButtons[8]->setEnabled( true );
3524 #ifdef DISABLE_PLOT2DVIEWER
3525 myMainLayout->setRowStretch(16,0);
3526 for( int i=32; i<=34; i++)
3527 myMainLayout->itemAt(i)->widget()->setVisible( false );
3531 myMainLayout->setRowStretch(16,0);
3532 for( int i=25; i<=34; i++)
3533 myMainLayout->itemAt(i)->widget()->setVisible( false );
3537 //================================================================================
3539 * \brief Computes and shows nb of elements satisfying a given predicate
3540 * \param [in] ft - a predicate type (SMESH::FunctorType)
3541 * \param [in] iBut - index of one of myButtons to disable
3542 * \param [in] iWdg - index of one of myWidgets to show the computed number
3544 //================================================================================
3546 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3548 myButtons[ iBut ]->setEnabled( false );
3549 myWidgets[ iWdg ]->setText( "" );
3550 if ( myObject->_is_nil() ) return;
3552 SUIT_OverrideCursor wc;
3554 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3555 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3558 this->showInfo( myObject ); // try to show all values
3559 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3560 return; // <ft> predicate already computed
3562 // look for a predicate of type <ft>
3563 for ( int i = 0; i < myPredicates.count(); ++i )
3564 if ( myPredicates[i]->GetFunctorType() == ft )
3566 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3567 myWidgets[ iWdg ]->setText( QString::number( nb ));
3571 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3573 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3576 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3578 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3581 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3583 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3586 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3588 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3591 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3593 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3596 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3598 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3601 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3603 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3606 void SMESHGUI_CtrlInfo::computeAspectRatio()
3608 #ifndef DISABLE_PLOT2DVIEWER
3609 myButtons[5]->setEnabled( false );
3611 if ( myObject->_is_nil() ) return;
3613 SUIT_OverrideCursor wc;
3615 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3616 if ( aHistogram && !aHistogram->isEmpty() ) {
3617 QwtPlotItem* anItem = aHistogram->createPlotItem();
3618 anItem->attach( myPlot );
3625 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3627 #ifndef DISABLE_PLOT2DVIEWER
3628 myButtons[8]->setEnabled( false );
3630 if ( myObject->_is_nil() ) return;
3632 SUIT_OverrideCursor wc;
3634 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3635 if ( aHistogram && !aHistogram->isEmpty() ) {
3636 QwtPlotItem* anItem = aHistogram->createPlotItem();
3637 anItem->attach( myPlot3D );
3645 \brief Internal clean-up (reset widget)
3647 void SMESHGUI_CtrlInfo::clearInternal()
3649 for( int i=0; i<=34; i++)
3650 myMainLayout->itemAt(i)->widget()->setVisible( true );
3651 for( int i=0; i<=8; i++)
3652 myButtons[i]->setEnabled( false );
3653 myPlot->detachItems();
3654 myPlot3D->detachItems();
3657 myWidgets[0]->setText( QString() );
3658 for ( int i = 1; i < myWidgets.count(); i++ )
3659 myWidgets[i]->setText( "" );
3660 myMainLayout->setRowStretch(11,5);
3661 myMainLayout->setRowStretch(16,5);
3664 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3666 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3667 myButtons[1]->setEnabled( true );
3668 myWidgets[2]->setText("");
3671 #ifndef DISABLE_PLOT2DVIEWER
3672 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3674 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3675 if ( mesh->_is_nil() ) return 0;
3676 if ( !mesh->IsLoaded() )
3678 aNumFun->SetMesh( mesh );
3680 CORBA::Long cprecision = 6;
3681 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3682 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3683 aNumFun->SetPrecision( cprecision );
3685 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3687 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3688 /*isLogarithmic=*/false,
3690 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3691 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3692 if ( &histogramVar.in() )
3694 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3695 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3696 if ( histogramVar->length() >= 2 )
3697 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3703 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3704 out << QString( 20, '-' ) << "\n";
3705 out << tr( "CTRL_INFO" ) << "\n";
3706 out << QString( 20, '-' ) << "\n";
3707 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3708 out << tr( "NODES_INFO" ) << "\n";
3709 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3710 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3711 out << tr( "EDGES_INFO" ) << "\n";
3712 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3713 out << tr( "FACES_INFO" ) << "\n";
3714 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3715 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3716 out << tr( "VOLUMES_INFO" ) << "\n";
3717 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3718 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3722 \class SMESHGUI_CtrlInfoDlg
3723 \brief Controls information dialog box
3728 \param parent parent widget
3729 \param page specifies the dialog page to be shown at the start-up
3731 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3734 setAttribute( Qt::WA_DeleteOnClose, true );
3735 setWindowTitle( tr( "CTRL_INFO" ) );
3736 setMinimumSize( 400, 600 );
3738 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3741 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3742 okBtn->setAutoDefault( true );
3743 okBtn->setDefault( true );
3745 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3746 dumpBtn->setAutoDefault( true );
3747 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3748 helpBtn->setAutoDefault( true );
3750 QHBoxLayout* btnLayout = new QHBoxLayout;
3751 btnLayout->setSpacing( SPACING );
3752 btnLayout->setMargin( 0 );
3754 btnLayout->addWidget( okBtn );
3755 btnLayout->addWidget( dumpBtn );
3756 btnLayout->addStretch( 10 );
3757 btnLayout->addWidget( helpBtn );
3759 QVBoxLayout* l = new QVBoxLayout ( this );
3760 l->setMargin( MARGIN );
3761 l->setSpacing( SPACING );
3762 l->addWidget( myCtrlInfo );
3763 l->addLayout( btnLayout );
3765 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3766 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3767 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3768 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3769 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3777 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3782 \brief Show controls information
3783 \param IO interactive object
3785 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3787 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3788 myCtrlInfo->showInfo( obj );
3792 \brief Perform clean-up actions on the dialog box closing.
3794 void SMESHGUI_CtrlInfoDlg::reject()
3796 SMESH::SetPointRepresentation( false );
3801 \brief Setup selection mode depending on the current dialog box state.
3803 void SMESHGUI_CtrlInfoDlg::updateSelection()
3805 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3806 disconnect( selMgr, 0, this, 0 );
3807 SMESH::SetPointRepresentation( false );
3808 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3813 \brief Show mesh information
3815 void SMESHGUI_CtrlInfoDlg::updateInfo()
3817 SUIT_OverrideCursor wc;
3819 SALOME_ListIO selected;
3820 SMESHGUI::selectionMgr()->selectedObjects( selected );
3822 if ( selected.Extent() == 1 ) {
3823 Handle(SALOME_InteractiveObject) IO = selected.First();
3829 \brief Activate dialog box
3831 void SMESHGUI_CtrlInfoDlg::activate()
3833 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3834 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3839 \brief Deactivate dialog box
3841 void SMESHGUI_CtrlInfoDlg::deactivate()
3843 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3847 * \brief Dump contents into a file
3849 void SMESHGUI_CtrlInfoDlg::dump()
3851 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3853 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3854 if ( !appStudy ) return;
3855 _PTR( Study ) aStudy = appStudy->studyDS();
3857 QStringList aFilters;
3858 aFilters.append( tr( "TEXT_FILES" ) );
3860 DumpFileDlg fd( this );
3861 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3862 fd.setNameFilters( aFilters );
3863 fd.myBaseChk->hide();
3864 fd.myElemChk->hide();
3865 fd.myAddChk ->hide();
3866 fd.myCtrlChk->hide();
3867 if ( fd.exec() == QDialog::Accepted )
3869 QString aFileName = fd.selectedFile();
3870 if ( !aFileName.isEmpty() ) {
3871 QFileInfo aFileInfo( aFileName );
3872 if ( aFileInfo.isDir() )
3875 QFile aFile( aFileName );
3876 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3879 QTextStream out( &aFile );
3880 myCtrlInfo->saveInfo( out );
3888 void SMESHGUI_CtrlInfoDlg::help()
3890 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");