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, SMESH::SMESH_IDSource_var obj )
964 if ( myActor != actor ) {
967 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
968 myMeshHasShape = ( !mesh->_is_nil() && mesh->HasShapeToMesh() );
974 \brief Show mesh element information
975 \param id mesh node / element ID
976 \param isElem show mesh element information if \c true or mesh node information if \c false
978 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
982 showInfo( ids, isElem );
986 \brief Show mesh element information
987 \param ids mesh nodes / elements identifiers
988 \param isElem show mesh element information if \c true or mesh node information if \c false
990 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
992 QList<long> newIds = ids.toList();
994 if ( myIDs == newIds && myIsElement == isElem ) return;
997 myIsElement = isElem;
1000 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1004 \brief Clear mesh element information widget
1006 void SMESHGUI_ElemInfo::clear()
1015 \brief Get central area widget
1016 \return central widget
1018 QWidget* SMESHGUI_ElemInfo::frame() const
1025 \return actor being used
1027 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1033 \brief Get current info mode.
1034 \return \c true if mesh element information is shown or \c false if node information is shown
1036 bool SMESHGUI_ElemInfo::isElements() const
1042 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1043 \brief Show information on the specified nodes / elements
1045 This function is to be redefined in sub-classes.
1047 \param ids nodes / elements identifiers information is to be shown on
1051 \brief Internal clean-up (reset widget)
1053 void SMESHGUI_ElemInfo::clearInternal()
1058 \brief Get node connectivity
1059 \param node mesh node
1060 \return node connectivity map
1062 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1066 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1067 while ( it && it->more() ) {
1068 const SMDS_MeshElement* ne = it->next();
1069 elmap[ ne->GetType() ] << ne->GetID();
1076 \brief Format connectivity data to string representation
1077 \param connectivity connetivity map
1078 \param type element type
1079 \return string representation of the connectivity
1081 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1084 if ( connectivity.contains( type ) ) {
1085 QList<int> elements = connectivity[ type ];
1087 foreach( int id, elements )
1088 str << QString::number( id );
1090 return str.join( " " );
1094 \brief Calculate gravity center of the mesh element
1095 \param element mesh element
1097 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1101 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1102 while ( nodeIt->more() ) {
1103 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1104 xyz.add( node->X(), node->Y(), node->Z() );
1106 xyz.divide( element->NbNodes() );
1112 \brief Calculate normal vector to the mesh face
1113 \param element mesh face
1115 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1117 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1118 return XYZ(n.X(), n.Y(), n.Z());
1122 \brief This slot is called from "Show Previous" button click.
1123 Shows information on the previous group of the items.
1125 void SMESHGUI_ElemInfo::showPrevious()
1127 myIndex = qMax( 0, myIndex-1 );
1129 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1133 \brief This slot is called from "Show Next" button click.
1134 Shows information on the next group of the items.
1136 void SMESHGUI_ElemInfo::showNext()
1138 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1140 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1144 \brief Update widgets state
1146 void SMESHGUI_ElemInfo::updateControls()
1148 myExtra->updateControls( myIDs.count(), myIndex );
1152 \class SMESHGUI_SimpleElemInfo
1153 \brief Represents mesh element information in the simple text area.
1158 \param parent parent widget
1160 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1161 : SMESHGUI_ElemInfo( parent )
1163 myInfo = new QTextBrowser( frame() );
1164 QVBoxLayout* l = new QVBoxLayout( frame() );
1166 l->addWidget( myInfo );
1170 \brief Show mesh element information
1171 \param ids mesh nodes / elements identifiers
1173 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1178 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1179 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1180 int cprecision = -1;
1181 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1182 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1183 foreach ( long id, ids ) {
1184 if ( !isElements() ) {
1188 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1189 if ( !node ) return;
1192 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1194 myInfo->append( "" );
1196 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1197 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1198 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1199 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1201 myInfo->append( "" );
1203 Connectivity connectivity = nodeConnectivity( node );
1204 if ( !connectivity.isEmpty() ) {
1205 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1206 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1207 if ( !con.isEmpty() )
1208 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1209 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1210 if ( !con.isEmpty() )
1211 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1212 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1213 if ( !con.isEmpty() )
1214 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1215 con = formatConnectivity( connectivity, SMDSAbs_Face );
1216 if ( !con.isEmpty() )
1217 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1218 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1219 if ( !con.isEmpty() )
1220 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1223 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1226 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1227 if ( !CORBA::is_nil( aMeshPtr ) ) {
1228 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1229 int shapeID = pos->shapeID;
1230 if ( shapeID > 0 ) {
1232 double u = 0, v = 0;
1233 switch ( pos->shapeType ) {
1235 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1236 if ( pos->params.length() == 1 )
1240 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1241 if ( pos->params.length() == 2 ) {
1247 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1250 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1254 myInfo->append( "" );
1255 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1256 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1257 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1258 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1259 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1260 if ( pos->shapeType == GEOM::FACE ) {
1261 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1262 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1267 // groups node belongs to
1268 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1269 if ( !CORBA::is_nil( aMesh ) ) {
1270 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1271 myInfo->append( "" ); // separator
1272 bool top_created = false;
1273 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1274 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1275 if ( CORBA::is_nil( aGrp ) ) continue;
1276 QString aName = aGrp->GetName();
1277 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1278 if ( !top_created ) {
1279 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1282 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1283 if ( grp_details ) {
1284 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1285 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1286 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1288 // type : group on geometry, standalone group, group on filter
1289 if ( !CORBA::is_nil( aStdGroup ) ) {
1290 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1291 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1293 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1294 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1295 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1296 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1297 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1299 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1300 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1303 else if ( !CORBA::is_nil( aFltGroup ) ) {
1304 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1305 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1309 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1310 arg( QString::number( aGrp->Size() ) ) );
1313 SALOMEDS::Color color = aGrp->GetColor();
1314 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1315 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1323 // show element info
1325 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1326 SMESH::Controls::NumericalFunctorPtr afunctor;
1329 // Element ID && Type
1331 switch( e->GetType() ) {
1332 case SMDSAbs_0DElement:
1333 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1335 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1337 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1339 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1340 case SMDSAbs_Volume:
1341 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1345 if ( stype.isEmpty() ) return;
1346 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1348 myInfo->append( "" );
1352 switch( e->GetEntityType() ) {
1353 case SMDSEntity_Triangle:
1354 case SMDSEntity_Quad_Triangle:
1355 case SMDSEntity_BiQuad_Triangle:
1356 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1357 case SMDSEntity_Quadrangle:
1358 case SMDSEntity_Quad_Quadrangle:
1359 case SMDSEntity_BiQuad_Quadrangle:
1360 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1361 case SMDSEntity_Polygon:
1362 case SMDSEntity_Quad_Polygon:
1363 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1364 case SMDSEntity_Tetra:
1365 case SMDSEntity_Quad_Tetra:
1366 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1367 case SMDSEntity_Pyramid:
1368 case SMDSEntity_Quad_Pyramid:
1369 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1370 case SMDSEntity_Hexa:
1371 case SMDSEntity_Quad_Hexa:
1372 case SMDSEntity_TriQuad_Hexa:
1373 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1374 case SMDSEntity_Penta:
1375 case SMDSEntity_Quad_Penta:
1376 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1377 case SMDSEntity_Hexagonal_Prism:
1378 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1379 case SMDSEntity_Polyhedra:
1380 case SMDSEntity_Quad_Polyhedra:
1381 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1385 if ( !gtype.isEmpty() )
1386 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1388 // Quadratic flag (any element except 0D)
1389 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1390 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1392 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1394 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1397 myInfo->append( "" );
1400 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1401 for ( int idx = 1; nodeIt->more(); idx++ ) {
1402 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1403 // node number and ID
1404 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1406 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1407 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1408 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1409 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1410 // node connectivity
1411 Connectivity connectivity = nodeConnectivity( node );
1412 if ( !connectivity.isEmpty() ) {
1413 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1414 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1415 if ( !con.isEmpty() )
1416 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1417 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1418 if ( !con.isEmpty() )
1419 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1420 con = formatConnectivity( connectivity, SMDSAbs_Face );
1421 if ( !con.isEmpty() )
1422 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1423 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1424 if ( !con.isEmpty() )
1425 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1428 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1432 myInfo->append( "" );
1435 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1437 if ( e->GetType() == SMDSAbs_Edge ) {
1438 afunctor.reset( new SMESH::Controls::Length() );
1439 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1440 afunctor->SetPrecision( cprecision );
1441 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1443 if( e->GetType() == SMDSAbs_Face ) {
1445 afunctor.reset( new SMESH::Controls::Area() );
1446 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1447 afunctor->SetPrecision( cprecision );
1448 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1450 afunctor.reset( new SMESH::Controls::Taper() );
1451 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1452 afunctor->SetPrecision( cprecision );
1453 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1455 afunctor.reset( new SMESH::Controls::AspectRatio() );
1456 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1457 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1459 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1460 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1461 afunctor->SetPrecision( cprecision );
1462 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1464 afunctor.reset( new SMESH::Controls::Warping() );
1465 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1466 afunctor->SetPrecision( cprecision );
1467 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1469 afunctor.reset( new SMESH::Controls::Skew() );
1470 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1471 afunctor->SetPrecision( cprecision );
1472 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1474 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1475 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1476 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1478 afunctor.reset( new SMESH::Controls::Length2D() );
1479 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1480 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MIN_ELEM_EDGE" )).arg( afunctor->GetValue( id )) );
1482 if( e->GetType() == SMDSAbs_Volume ) {
1484 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1485 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1486 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1488 afunctor.reset( new SMESH::Controls::Volume() );
1489 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1490 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1492 afunctor.reset( new SMESH::Controls::Volume() );
1493 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1494 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1497 myInfo->append( "" );
1500 XYZ gc = gravityCenter( e );
1501 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1504 if( e->GetType() == SMDSAbs_Face ) {
1505 XYZ gc = normal( e );
1506 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1510 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1511 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1512 if ( !CORBA::is_nil( aMesh ) ) {
1513 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1514 int shapeID = pos.shapeID;
1515 if ( shapeID > 0 ) {
1516 myInfo->append( "" ); // separator
1518 switch ( pos.shapeType ) {
1519 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1520 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1521 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1522 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1523 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1524 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1526 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1531 // Groups the element belongs to
1532 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1533 if ( !CORBA::is_nil( aMesh ) ) {
1534 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1535 myInfo->append( "" ); // separator
1536 bool top_created = false;
1537 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1538 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1539 if ( CORBA::is_nil( aGrp ) ) continue;
1540 QString aName = aGrp->GetName();
1541 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1542 if ( !top_created ) {
1543 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1546 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1547 if ( grp_details ) {
1548 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1549 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1550 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1552 // type : group on geometry, standalone group, group on filter
1553 if ( !CORBA::is_nil( aStdGroup ) ) {
1554 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1555 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1557 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1558 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1559 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1560 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1561 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1563 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1564 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1567 else if ( !CORBA::is_nil( aFltGroup ) ) {
1568 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1569 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1572 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1573 arg( QString::number( aGrp->Size() ) ) );
1576 SALOMEDS::Color color = aGrp->GetColor();
1577 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1578 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1585 if ( ids.count() > 1 ) {
1586 myInfo->append( "" );
1587 myInfo->append( "------" );
1588 myInfo->append( "" );
1595 \brief Internal clean-up (reset widget)
1597 void SMESHGUI_SimpleElemInfo::clearInternal()
1602 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1604 out << QString( 12, '-' ) << "\n";
1605 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1606 out << QString( 12, '-' ) << "\n";
1607 out << myInfo->toPlainText();
1613 \class SMESHGUI_TreeElemInfo::ItemDelegate
1614 \brief Item delegate for tree mesh info widget
1617 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1620 ItemDelegate( QObject* );
1621 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1628 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1633 \brief Create item editor widget
1636 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1638 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1639 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1644 \class SMESHGUI_TreeElemInfo
1645 \brief Represents mesh element information in the tree-like form.
1650 \param parent parent widget
1652 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1653 : SMESHGUI_ElemInfo( parent )
1655 myInfo = new QTreeWidget( frame() );
1656 myInfo->setColumnCount( 2 );
1657 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1658 myInfo->header()->setStretchLastSection( true );
1659 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1660 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1662 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1664 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1665 QVBoxLayout* l = new QVBoxLayout( frame() );
1667 l->addWidget( myInfo );
1668 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1672 \brief Show mesh element information
1673 \param ids mesh nodes / elements identifiers
1675 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1680 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1681 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1682 int cprecision = -1;
1683 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1684 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1685 foreach ( long id, ids ) {
1686 if ( !isElements() ) {
1690 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1692 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1695 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1696 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1697 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1699 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1700 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1701 QTreeWidgetItem* xItem = createItem( coordItem );
1702 xItem->setText( 0, "X" );
1703 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1704 QTreeWidgetItem* yItem = createItem( coordItem );
1705 yItem->setText( 0, "Y" );
1706 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1707 QTreeWidgetItem* zItem = createItem( coordItem );
1708 zItem->setText( 0, "Z" );
1709 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1711 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1712 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1713 Connectivity connectivity = nodeConnectivity( node );
1714 if ( !connectivity.isEmpty() ) {
1715 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1716 if ( !con.isEmpty() ) {
1717 QTreeWidgetItem* i = createItem( conItem );
1718 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1719 i->setText( 1, con );
1721 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1722 if ( !con.isEmpty() ) {
1723 QTreeWidgetItem* i = createItem( conItem );
1724 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1725 i->setText( 1, con );
1726 i->setData( 1, TypeRole, NodeConnectivity );
1728 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1729 if ( !con.isEmpty() ) {
1730 QTreeWidgetItem* i = createItem( conItem );
1731 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1732 i->setText( 1, con );
1733 i->setData( 1, TypeRole, NodeConnectivity );
1735 con = formatConnectivity( connectivity, SMDSAbs_Face );
1736 if ( !con.isEmpty() ) {
1737 QTreeWidgetItem* i = createItem( conItem );
1738 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1739 i->setText( 1, con );
1740 i->setData( 1, TypeRole, NodeConnectivity );
1742 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1743 if ( !con.isEmpty() ) {
1744 QTreeWidgetItem* i = createItem( conItem );
1745 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1746 i->setText( 1, con );
1747 i->setData( 1, TypeRole, NodeConnectivity );
1751 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1754 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1755 if ( !CORBA::is_nil( aMeshPtr ) ) {
1756 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1757 int shapeID = pos->shapeID;
1758 if ( shapeID > 0 ) {
1760 double u = 0, v = 0;
1761 switch ( pos->shapeType ) {
1763 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1764 if ( pos->params.length() == 1 )
1768 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1769 if ( pos->params.length() == 2 ) {
1775 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1778 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1781 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1782 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1783 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1784 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1785 QTreeWidgetItem* uItem = createItem( posItem );
1786 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1787 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1788 if ( pos->shapeType == GEOM::FACE ) {
1789 QTreeWidgetItem* vItem = createItem( posItem );
1790 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1791 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1796 // groups node belongs to
1797 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1798 if ( !CORBA::is_nil( aMesh ) ) {
1799 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1800 QTreeWidgetItem* groupsItem = 0;
1801 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1802 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1803 if ( CORBA::is_nil( aGrp ) ) continue;
1804 QString aName = aGrp->GetName();
1805 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1806 if ( !groupsItem ) {
1807 groupsItem = createItem( nodeItem, Bold );
1808 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1810 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1811 it->setText( 0, aName.trimmed() );
1812 if ( grp_details ) {
1813 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1814 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1815 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1817 // type : group on geometry, standalone group, group on filter
1818 QTreeWidgetItem* typeItem = createItem( it );
1819 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1820 if ( !CORBA::is_nil( aStdGroup ) ) {
1821 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1823 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1824 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1825 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1826 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1828 QTreeWidgetItem* gobjItem = createItem( typeItem );
1829 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1830 gobjItem->setText( 1, sobj->GetName().c_str() );
1833 else if ( !CORBA::is_nil( aFltGroup ) ) {
1834 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1838 QTreeWidgetItem* sizeItem = createItem( it );
1839 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1840 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1843 SALOMEDS::Color color = aGrp->GetColor();
1844 QTreeWidgetItem* colorItem = createItem( it );
1845 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1846 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1854 // show element info
1856 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1857 SMESH::Controls::NumericalFunctorPtr afunctor;
1860 // element ID && type
1862 switch( e->GetType() ) {
1863 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1864 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1865 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1866 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1867 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1870 if ( stype.isEmpty() ) return;
1871 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1872 elemItem->setText( 0, stype );
1873 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1876 switch( e->GetEntityType() ) {
1877 case SMDSEntity_Triangle:
1878 case SMDSEntity_Quad_Triangle:
1879 case SMDSEntity_BiQuad_Triangle:
1880 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1881 case SMDSEntity_Quadrangle:
1882 case SMDSEntity_Quad_Quadrangle:
1883 case SMDSEntity_BiQuad_Quadrangle:
1884 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1885 case SMDSEntity_Polygon:
1886 case SMDSEntity_Quad_Polygon:
1887 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1888 case SMDSEntity_Tetra:
1889 case SMDSEntity_Quad_Tetra:
1890 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1891 case SMDSEntity_Pyramid:
1892 case SMDSEntity_Quad_Pyramid:
1893 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1894 case SMDSEntity_Hexa:
1895 case SMDSEntity_Quad_Hexa:
1896 case SMDSEntity_TriQuad_Hexa:
1897 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1898 case SMDSEntity_Penta:
1899 case SMDSEntity_Quad_Penta:
1900 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1901 case SMDSEntity_Hexagonal_Prism:
1902 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1903 case SMDSEntity_Polyhedra:
1904 case SMDSEntity_Quad_Polyhedra:
1905 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1909 if ( !gtype.isEmpty() ) {
1910 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1911 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1912 typeItem->setText( 1, gtype );
1914 // quadratic flag (for edges, faces and volumes)
1915 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1917 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1918 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1919 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1921 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1923 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1924 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1925 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1928 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1929 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1932 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1933 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1934 for ( int idx = 1; nodeIt->more(); idx++ ) {
1935 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1936 nodeInfo( node, idx, e->NbNodes(), conItem );
1940 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1941 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1942 QList<const SMDS_MeshElement*> uniqueNodes;
1943 while ( nodeIt->more() )
1944 uniqueNodes.append( nodeIt->next() );
1946 SMDS_VolumeTool vtool( e );
1947 const int nbFaces = vtool.NbFaces();
1948 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1949 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1950 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1951 faceItem->setExpanded( true );
1953 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1954 const int nbNodes = vtool.NbFaceNodes( face_id );
1955 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1956 const SMDS_MeshNode* node = aNodeIds[node_id];
1957 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1962 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1963 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1965 if( e->GetType()==SMDSAbs_Edge){
1966 afunctor.reset( new SMESH::Controls::Length() );
1967 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1968 afunctor->SetPrecision( cprecision );
1969 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1970 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1971 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1973 if( e->GetType() == SMDSAbs_Face ) {
1975 afunctor.reset( new SMESH::Controls::Area() );
1976 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1977 afunctor->SetPrecision( cprecision );
1978 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1979 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1980 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1982 afunctor.reset( new SMESH::Controls::Taper() );
1983 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1984 afunctor->SetPrecision( cprecision );
1985 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1986 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1987 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1989 afunctor.reset( new SMESH::Controls::AspectRatio() );
1990 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1991 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1992 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1993 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1995 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1996 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1997 afunctor->SetPrecision( cprecision );
1998 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
1999 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
2000 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2002 afunctor.reset( new SMESH::Controls::Warping() );
2003 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2004 afunctor->SetPrecision( cprecision );
2005 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
2006 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
2007 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2009 afunctor.reset( new SMESH::Controls::Skew() );
2010 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2011 afunctor->SetPrecision( cprecision );
2012 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2013 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
2014 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2016 if ( hasShapeToMesh() )
2018 afunctor.reset( new SMESH::Controls::Deflection2D() );
2019 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2020 QTreeWidgetItem* deflItem = createItem( cntrItem, Bold );
2021 deflItem->setText( 0, tr( "DEFLECTION_2D" ));
2022 deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2025 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2026 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2027 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2028 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2029 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2031 if( e->GetType() == SMDSAbs_Volume ) {
2033 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2034 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2035 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2036 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
2037 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2039 afunctor.reset( new SMESH::Controls::Volume() );
2040 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2041 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2042 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
2043 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2045 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2046 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2047 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2048 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
2049 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2053 afunctor.reset( new SMESH::Controls::Length2D() );
2054 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2055 QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold );
2056 minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" ));
2057 minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2060 XYZ gc = gravityCenter( e );
2061 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2062 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
2063 QTreeWidgetItem* xItem = createItem( gcItem );
2064 xItem->setText( 0, "X" );
2065 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2066 QTreeWidgetItem* yItem = createItem( gcItem );
2067 yItem->setText( 0, "Y" );
2068 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2069 QTreeWidgetItem* zItem = createItem( gcItem );
2070 zItem->setText( 0, "Z" );
2071 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2074 if( e->GetType() == SMDSAbs_Face ) {
2075 XYZ gc = normal( e );
2076 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2077 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2078 QTreeWidgetItem* xItem = createItem( nItem );
2079 xItem->setText( 0, "X" );
2080 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2081 QTreeWidgetItem* yItem = createItem( nItem );
2082 yItem->setText( 0, "Y" );
2083 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2084 QTreeWidgetItem* zItem = createItem( nItem );
2085 zItem->setText( 0, "Z" );
2086 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2090 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2091 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2092 if ( !CORBA::is_nil( aMesh ) ) {
2093 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2094 int shapeID = pos.shapeID;
2095 if ( shapeID > 0 ) {
2096 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2098 switch ( pos.shapeType ) {
2099 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2100 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2101 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2102 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2103 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2104 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2106 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2107 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2111 // groups element belongs to
2112 if ( !CORBA::is_nil( aMesh ) ) {
2113 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2114 QTreeWidgetItem* groupsItem = 0;
2115 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2116 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2117 if ( CORBA::is_nil( aGrp ) ) continue;
2118 QString aName = aGrp->GetName();
2119 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2120 if ( !groupsItem ) {
2121 groupsItem = createItem( elemItem, Bold );
2122 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2124 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2125 it->setText( 0, aName.trimmed() );
2126 if ( grp_details ) {
2127 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2128 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2129 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2131 // type : group on geometry, standalone group, group on filter
2132 QTreeWidgetItem* typeItem = createItem( it );
2133 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2134 if ( !CORBA::is_nil( aStdGroup ) ) {
2135 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2137 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2138 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2139 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2140 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2142 QTreeWidgetItem* gobjItem = createItem( typeItem );
2143 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2144 gobjItem->setText( 1, sobj->GetName().c_str() );
2147 else if ( !CORBA::is_nil( aFltGroup ) ) {
2148 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2152 QTreeWidgetItem* sizeItem = createItem( it );
2153 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2154 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2157 SALOMEDS::Color color = aGrp->GetColor();
2158 QTreeWidgetItem* colorItem = createItem( it );
2159 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2160 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2171 \brief Show node information
2172 \param node mesh node for showing
2173 \param index index of current node
2174 \param nbNodes number of unique nodes in element
2175 \param parentItem parent item of tree
2177 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2178 int nbNodes, QTreeWidgetItem* parentItem )
2180 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2181 // node number and ID
2182 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2183 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2184 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2185 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2186 nodeItem->setData( 1, IdRole, node->GetID() );
2187 nodeItem->setExpanded( false );
2189 QTreeWidgetItem* coordItem = createItem( nodeItem );
2190 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2191 QTreeWidgetItem* xItem = createItem( coordItem );
2192 xItem->setText( 0, "X" );
2193 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2194 QTreeWidgetItem* yItem = createItem( coordItem );
2195 yItem->setText( 0, "Y" );
2196 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2197 QTreeWidgetItem* zItem = createItem( coordItem );
2198 zItem->setText( 0, "Z" );
2199 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2200 // node connectivity
2201 QTreeWidgetItem* nconItem = createItem( nodeItem );
2202 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2203 Connectivity connectivity = nodeConnectivity( node );
2204 if ( !connectivity.isEmpty() ) {
2205 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2206 if ( !con.isEmpty() ) {
2207 QTreeWidgetItem* i = createItem( nconItem );
2208 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2209 i->setText( 1, con );
2211 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2212 if ( !con.isEmpty() ) {
2213 QTreeWidgetItem* i = createItem( nconItem );
2214 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2215 i->setText( 1, con );
2216 i->setData( 1, TypeRole, NodeConnectivity );
2218 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2219 if ( !con.isEmpty() ) {
2220 QTreeWidgetItem* i = createItem( nconItem );
2221 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2222 i->setText( 1, con );
2223 i->setData( 1, TypeRole, NodeConnectivity );
2225 con = formatConnectivity( connectivity, SMDSAbs_Face );
2226 if ( !con.isEmpty() ) {
2227 QTreeWidgetItem* i = createItem( nconItem );
2228 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2229 i->setText( 1, con );
2230 i->setData( 1, TypeRole, NodeConnectivity );
2232 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2233 if ( !con.isEmpty() ) {
2234 QTreeWidgetItem* i = createItem( nconItem );
2235 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2236 i->setText( 1, con );
2237 i->setData( 1, TypeRole, NodeConnectivity );
2242 \brief Internal clean-up (reset widget)
2244 void SMESHGUI_TreeElemInfo::clearInternal()
2251 \brief Create new tree item.
2252 \param parent parent tree widget item
2253 \param flags item flag
2254 \return new tree widget item
2256 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2258 QTreeWidgetItem* item;
2260 item = new QTreeWidgetItem( parent );
2262 item = new QTreeWidgetItem( myInfo );
2264 item->setFlags( item->flags() | Qt::ItemIsEditable );
2266 QFont f = item->font( 0 );
2268 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2269 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2270 item->setFont( i, f );
2273 item->setExpanded( true );
2277 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2279 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2280 if ( widgets.isEmpty() ) return;
2281 QTreeWidgetItem* aTreeItem = widgets.first();
2282 int type = aTreeItem->data( 1, TypeRole ).toInt();
2283 int id = aTreeItem->data( 1, IdRole ).toInt();
2285 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2286 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2287 emit( itemInfo( id ) );
2288 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2289 emit( itemInfo( aTreeItem->text( 1 ) ) );
2292 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2295 int type = theItem->data( 1, TypeRole ).toInt();
2296 int id = theItem->data( 1, IdRole ).toInt();
2297 if ( type == ElemConnectivity && id > 0 )
2298 emit( itemInfo( id ) );
2299 else if ( type == NodeConnectivity )
2300 emit( itemInfo( theItem->text( 1 ) ) );
2304 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2306 out << QString( 12, '-' ) << "\n";
2307 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2308 out << QString( 12, '-' ) << "\n";
2310 QTreeWidgetItemIterator it( myInfo );
2312 if ( !( *it )->text(0).isEmpty() ) {
2313 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2314 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2324 \brief Mesh information computer
2327 The class is created for different computation operation. Currently it is used
2328 to compute number of underlying nodes for the groups.
2334 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2335 QTreeWidgetItem* item,
2338 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2340 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2344 \brief Compute function
2346 void GrpComputor::compute()
2348 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2349 SUIT_OverrideCursor wc;
2350 QTreeWidgetItem* item = myItem;
2352 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2353 item->treeWidget()->removeItemWidget( item, 1 );
2354 item->setText( 1, QString::number( nb ));
2359 \class SMESHGUI_AddInfo
2360 \brief The wigdet shows additional information on the mesh object.
2365 \param parent parent widget
2367 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2368 : QTreeWidget( parent )
2370 setColumnCount( 2 );
2371 header()->setStretchLastSection( true );
2372 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2373 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2375 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2383 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2388 \brief Show additional information on the selected object
2389 \param obj object being processed (mesh, sub-mesh, group, ID source)
2391 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2393 setProperty( "group_index", 0 );
2394 setProperty( "submesh_index", 0 );
2395 myComputors.clear();
2398 if ( CORBA::is_nil( obj ) ) return;
2400 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2401 if ( !sobj ) return;
2404 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2405 nameItem->setText( 0, tr( "NAME" ) );
2406 nameItem->setText( 1, sobj->GetName().c_str() );
2408 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2409 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2410 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2412 if ( !aMesh->_is_nil() )
2413 meshInfo( aMesh, nameItem );
2414 else if ( !aSubMesh->_is_nil() )
2415 subMeshInfo( aSubMesh, nameItem );
2416 else if ( !aGroup->_is_nil() )
2417 groupInfo( aGroup.in(), nameItem );
2421 \brief Create new tree item.
2422 \param parent parent tree widget item
2423 \param flags item flag
2424 \return new tree widget item
2426 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2428 QTreeWidgetItem* item;
2431 item = new QTreeWidgetItem( parent );
2433 item = new QTreeWidgetItem( this );
2435 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2437 QFont f = item->font( 0 );
2439 for ( int i = 0; i < columnCount(); i++ ) {
2440 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2441 item->setFont( i, f );
2444 item->setExpanded( true );
2449 \brief Show mesh info
2450 \param mesh mesh object
2451 \param parent parent tree item
2453 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2456 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2457 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2458 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2459 typeItem->setText( 0, tr( "TYPE" ) );
2460 if ( !CORBA::is_nil( shape ) ) {
2461 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2462 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2464 QTreeWidgetItem* gobjItem = createItem( typeItem );
2465 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2466 gobjItem->setText( 1, sobj->GetName().c_str() );
2469 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2470 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2471 QTreeWidgetItem* fileItem = createItem( typeItem );
2472 fileItem->setText( 0, tr( "FILE_NAME" ) );
2473 fileItem->setText( 1, (char*)inf->fileName );
2476 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2480 myGroups = mesh->GetGroups();
2484 mySubMeshes = mesh->GetSubMeshes();
2489 \brief Show sub-mesh info
2490 \param subMesh sub-mesh object
2491 \param parent parent tree item
2493 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2495 bool isShort = parent->parent() != 0;
2499 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2501 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2502 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2503 nameItem->setText( 1, sobj->GetName().c_str() );
2508 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2509 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2511 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2512 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2513 gobjItem->setText( 1, sobj->GetName().c_str() );
2518 \brief Show group info
2519 \param grp mesh group object
2520 \param parent parent tree item
2522 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2524 bool isShort = parent->parent() != 0;
2526 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2527 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2528 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2532 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2534 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2535 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2536 nameItem->setText( 1, sobj->GetName().c_str() );
2540 // type : group on geometry, standalone group, group on filter
2541 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2542 typeItem->setText( 0, tr( "TYPE" ) );
2543 if ( !CORBA::is_nil( aStdGroup ) ) {
2544 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2546 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2547 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2548 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2549 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2551 QTreeWidgetItem* gobjItem = createItem( typeItem );
2552 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2553 gobjItem->setText( 1, sobj->GetName().c_str() );
2556 else if ( !CORBA::is_nil( aFltGroup ) ) {
2557 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2562 QString etype = tr( "UNKNOWN" );
2563 switch( grp->GetType() ) {
2565 etype = tr( "NODE" );
2568 etype = tr( "EDGE" );
2571 etype = tr( "FACE" );
2574 etype = tr( "VOLUME" );
2577 etype = tr( "0DELEM" );
2580 etype = tr( "BALL" );
2585 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2586 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2587 etypeItem->setText( 1, etype );
2590 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2591 bool meshLoaded = mesh->IsLoaded();
2593 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2595 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2596 groupSize = grp->Size();
2598 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2599 sizeItem->setText( 0, tr( "SIZE" ) );
2600 if ( groupSize > -1 ) {
2601 sizeItem->setText( 1, QString::number( groupSize ) );
2604 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2605 setItemWidget( sizeItem, 1, btn );
2606 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2607 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2608 myComputors.append( comp );
2610 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2614 SALOMEDS::Color color = grp->GetColor();
2615 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2616 colorItem->setText( 0, tr( "COLOR" ) );
2617 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2619 // nb of underlying nodes
2620 if ( grp->GetType() != SMESH::NODE) {
2621 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2622 nodesItem->setText( 0, tr( "NB_NODES" ) );
2623 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2624 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2625 if ( toShowNodes && meshLoaded ) {
2626 // already calculated and up-to-date
2627 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2630 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2631 setItemWidget( nodesItem, 1, btn );
2632 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2633 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2634 myComputors.append( comp );
2636 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2641 void SMESHGUI_AddInfo::showGroups()
2643 myComputors.clear();
2645 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2646 if ( !parent ) return;
2648 int idx = property( "group_index" ).toInt();
2650 QTreeWidgetItem* itemGroups = 0;
2651 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2652 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2653 itemGroups = parent->child( i );
2654 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2656 extra->updateControls( myGroups->length(), idx );
2657 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2661 QMap<int, QTreeWidgetItem*> grpItems;
2662 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2663 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2664 if ( CORBA::is_nil( grp ) ) continue;
2665 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2666 if ( !grpSObj ) continue;
2668 int grpType = grp->GetType();
2670 if ( !itemGroups ) {
2671 // create top-level groups container item
2672 itemGroups = createItem( parent, Bold | All );
2673 itemGroups->setText( 0, tr( "GROUPS" ) );
2674 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2676 // total number of groups > 10, show extra widgets for info browsing
2677 if ((int) myGroups->length() > MAXITEMS ) {
2678 ExtraWidget* extra = new ExtraWidget( this, true );
2679 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2680 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2681 setItemWidget( itemGroups, 1, extra );
2682 extra->updateControls( myGroups->length(), idx );
2686 if ( grpItems.find( grpType ) == grpItems.end() ) {
2687 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2688 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2689 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2693 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2694 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2697 groupInfo( grp.in(), grpNameItem );
2701 void SMESHGUI_AddInfo::showSubMeshes()
2703 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2704 if ( !parent ) return;
2706 int idx = property( "submesh_index" ).toInt();
2708 QTreeWidgetItem* itemSubMeshes = 0;
2709 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2710 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2711 itemSubMeshes = parent->child( i );
2712 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2714 extra->updateControls( mySubMeshes->length(), idx );
2715 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2719 QMap<int, QTreeWidgetItem*> smItems;
2720 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2721 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2722 if ( CORBA::is_nil( sm ) ) continue;
2723 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2724 if ( !smSObj ) continue;
2726 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2727 if ( CORBA::is_nil(gobj ) ) continue;
2729 int smType = gobj->GetShapeType();
2730 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2732 if ( !itemSubMeshes ) {
2733 itemSubMeshes = createItem( parent, Bold | All );
2734 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2735 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2737 // total number of sub-meshes > 10, show extra widgets for info browsing
2738 if ((int) mySubMeshes->length() > MAXITEMS ) {
2739 ExtraWidget* extra = new ExtraWidget( this, true );
2740 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2741 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2742 setItemWidget( itemSubMeshes, 1, extra );
2743 extra->updateControls( mySubMeshes->length(), idx );
2747 if ( smItems.find( smType ) == smItems.end() ) {
2748 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2749 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2750 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2754 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2755 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2758 subMeshInfo( sm.in(), smNameItem );
2763 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2765 void SMESHGUI_AddInfo::changeLoadToCompute()
2767 for ( int i = 0; i < myComputors.count(); ++i )
2769 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2771 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2772 btn->setText( tr("COMPUTE") );
2777 void SMESHGUI_AddInfo::showPreviousGroups()
2779 int idx = property( "group_index" ).toInt();
2780 setProperty( "group_index", idx-1 );
2784 void SMESHGUI_AddInfo::showNextGroups()
2786 int idx = property( "group_index" ).toInt();
2787 setProperty( "group_index", idx+1 );
2791 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2793 int idx = property( "submesh_index" ).toInt();
2794 setProperty( "submesh_index", idx-1 );
2798 void SMESHGUI_AddInfo::showNextSubMeshes()
2800 int idx = property( "submesh_index" ).toInt();
2801 setProperty( "submesh_index", idx+1 );
2805 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2807 out << QString( 15, '-') << "\n";
2808 out << tr( "ADDITIONAL_INFO" ) << "\n";
2809 out << QString( 15, '-' ) << "\n";
2810 QTreeWidgetItemIterator it( this );
2812 if ( !( ( *it )->text(0) ).isEmpty() ) {
2813 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2814 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2815 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2817 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2826 \class SMESHGUI_MeshInfoDlg
2827 \brief Mesh information dialog box
2832 \param parent parent widget
2833 \param page specifies the dialog page to be shown at the start-up
2835 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2836 : QDialog( parent ), myActor( 0 )
2839 setAttribute( Qt::WA_DeleteOnClose, true );
2840 setWindowTitle( tr( "MESH_INFO" ) );
2841 setSizeGripEnabled( true );
2843 myTabWidget = new QTabWidget( this );
2847 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2848 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2852 QWidget* w = new QWidget( myTabWidget );
2854 myMode = new QButtonGroup( this );
2855 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2856 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2857 myMode->button( NodeMode )->setChecked( true );
2858 myID = new QLineEdit( w );
2859 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2861 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2862 mode = qMin( 1, qMax( 0, mode ) );
2865 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2867 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2869 QGridLayout* elemLayout = new QGridLayout( w );
2870 elemLayout->setMargin( MARGIN );
2871 elemLayout->setSpacing( SPACING );
2872 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2873 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2874 elemLayout->addWidget( myID, 0, 2 );
2875 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2877 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2881 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2882 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2886 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2887 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2891 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2892 okBtn->setAutoDefault( true );
2893 okBtn->setDefault( true );
2895 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2896 dumpBtn->setAutoDefault( true );
2897 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2898 helpBtn->setAutoDefault( true );
2900 QHBoxLayout* btnLayout = new QHBoxLayout;
2901 btnLayout->setSpacing( SPACING );
2902 btnLayout->setMargin( 0 );
2904 btnLayout->addWidget( okBtn );
2905 btnLayout->addWidget( dumpBtn );
2906 btnLayout->addStretch( 10 );
2907 btnLayout->addWidget( helpBtn );
2909 QVBoxLayout* l = new QVBoxLayout ( this );
2910 l->setMargin( MARGIN );
2911 l->setSpacing( SPACING );
2912 l->addWidget( myTabWidget );
2913 l->addLayout( btnLayout );
2915 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2917 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2918 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2919 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2920 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2921 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2922 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2923 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2924 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2925 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2926 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2934 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2939 \brief Show mesh information
2940 \param IO interactive object
2942 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2947 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2948 if ( !CORBA::is_nil( obj ) )
2950 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2951 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2952 if ( myTabWidget->currentIndex() == CtrlInfo )
2953 myCtrlInfo->showInfo( obj );
2956 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2957 SVTK_Selector* selector = SMESH::GetSelector();
2960 if ( myActor && selector ) {
2961 nb = myMode->checkedId() == NodeMode ?
2962 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2963 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2965 myElemInfo->setSource( myActor, obj ) ;
2967 myID->setText( ID.trimmed() );
2969 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2970 foreach ( ID, idTxt )
2971 ids << ID.trimmed().toLong();
2972 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2976 myElemInfo->clear();
2983 \brief Perform clean-up actions on the dialog box closing.
2985 void SMESHGUI_MeshInfoDlg::reject()
2987 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2988 selMgr->clearFilters();
2989 SMESH::SetPointRepresentation( false );
2990 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2991 aViewWindow->SetSelectionMode( ActorSelection );
2996 \brief Process keyboard event
2997 \param e key press event
2999 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3001 QDialog::keyPressEvent( e );
3002 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3009 \brief Reactivate dialog box, when mouse pointer goes into it.
3011 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3017 \brief Setup selection mode depending on the current dialog box state.
3019 void SMESHGUI_MeshInfoDlg::updateSelection()
3021 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3023 disconnect( selMgr, 0, this, 0 );
3024 selMgr->clearFilters();
3026 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
3027 SMESH::SetPointRepresentation( false );
3028 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3029 aViewWindow->SetSelectionMode( ActorSelection );
3032 if ( myMode->checkedId() == NodeMode ) {
3033 SMESH::SetPointRepresentation( true );
3034 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3035 aViewWindow->SetSelectionMode( NodeSelection );
3038 SMESH::SetPointRepresentation( false );
3039 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3040 aViewWindow->SetSelectionMode( CellSelection );
3044 QString oldID = myID->text().trimmed();
3045 SMESH_Actor* oldActor = myActor;
3048 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3051 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3052 myID->setText( oldID );
3058 \brief Show help page
3060 void SMESHGUI_MeshInfoDlg::help()
3062 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3063 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3064 "mesh_infos_page.html#mesh_element_info_anchor" );
3068 \brief Show mesh information
3070 void SMESHGUI_MeshInfoDlg::updateInfo()
3072 SUIT_OverrideCursor wc;
3074 SALOME_ListIO selected;
3075 SMESHGUI::selectionMgr()->selectedObjects( selected );
3077 if ( selected.Extent() == 1 ) {
3078 Handle(SALOME_InteractiveObject) IO = selected.First();
3087 \brief Activate dialog box
3089 void SMESHGUI_MeshInfoDlg::activate()
3091 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3092 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3093 myTabWidget->setEnabled( true );
3098 \brief Deactivate dialog box
3100 void SMESHGUI_MeshInfoDlg::deactivate()
3102 myTabWidget->setEnabled( false );
3103 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3107 \brief Called when users switches between node / element modes.
3109 void SMESHGUI_MeshInfoDlg::modeChanged()
3116 \brief Caled when users prints mesh element ID in the corresponding field.
3118 void SMESHGUI_MeshInfoDlg::idChanged()
3120 SVTK_Selector* selector = SMESH::GetSelector();
3121 if ( myActor && selector ) {
3122 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3123 TColStd_MapOfInteger ID;
3125 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3126 foreach ( QString tid, idTxt ) {
3127 long id = tid.trimmed().toLong();
3128 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3129 myActor->GetObject()->GetMesh()->FindElement( id ) :
3130 myActor->GetObject()->GetMesh()->FindNode( id );
3136 selector->AddOrRemoveIndex( IO, ID, false );
3137 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3138 aViewWindow->highlight( IO, true, true );
3139 aViewWindow->Repaint();
3141 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3145 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3147 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3148 myMode->button( NodeMode )->click();
3149 myID->setText( QString::number( id ) );
3153 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3155 if ( !theStr.isEmpty() ) {
3156 myMode->button( ElemMode )->click();
3157 myID->setText( theStr );
3161 void SMESHGUI_MeshInfoDlg::dump()
3163 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3165 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3166 if ( !appStudy ) return;
3167 _PTR( Study ) aStudy = appStudy->studyDS();
3169 QStringList aFilters;
3170 aFilters.append( tr( "TEXT_FILES" ) );
3172 bool anIsBase = true;
3173 bool anIsElem = true;
3174 bool anIsAdd = true;
3175 bool anIsCtrl = true;
3177 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3178 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3179 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3180 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3181 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3184 DumpFileDlg fd( this );
3185 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3186 fd.setNameFilters( aFilters );
3187 fd.myBaseChk->setChecked( anIsBase );
3188 fd.myElemChk->setChecked( anIsElem );
3189 fd.myAddChk ->setChecked( anIsAdd );
3190 fd.myCtrlChk->setChecked( anIsCtrl );
3191 if ( fd.exec() == QDialog::Accepted )
3193 QString aFileName = fd.selectedFile();
3195 bool toBase = fd.myBaseChk->isChecked();
3196 bool toElem = fd.myElemChk->isChecked();
3197 bool toAdd = fd.myAddChk->isChecked();
3198 bool toCtrl = fd.myCtrlChk->isChecked();
3200 if ( !aFileName.isEmpty() ) {
3201 QFileInfo aFileInfo( aFileName );
3202 if ( aFileInfo.isDir() )
3205 QFile aFile( aFileName );
3206 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3209 QTextStream out( &aFile );
3211 if ( toBase ) myBaseInfo->saveInfo( out );
3212 if ( toElem ) myElemInfo->saveInfo( out );
3213 if ( toAdd ) myAddInfo ->saveInfo( out );
3214 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3220 \class SMESHGUI_CtrlInfo
3221 \brief Class for the mesh controls information widget.
3226 \param parent parent widget
3228 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3229 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3231 setFrameStyle( StyledPanel | Sunken );
3233 myMainLayout = new QGridLayout( this );
3234 myMainLayout->setMargin( MARGIN );
3235 myMainLayout->setSpacing( SPACING );
3238 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3239 QLabel* aName = createField();
3240 aName->setMinimumWidth( 150 );
3243 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3244 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3246 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3249 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3250 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3251 QLabel* aNodesFree = createField();
3252 myWidgets << aNodesFree;
3253 myPredicates << aFilterMgr->CreateFreeNodes();
3255 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3256 QLabel* aNodesNbConn = createField();
3257 myWidgets << aNodesNbConn;
3258 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3260 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3261 QLabel* aNodesDouble = createField();
3262 myWidgets << aNodesDouble;
3263 myPredicates << aFilterMgr->CreateEqualNodes();
3264 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3265 myToleranceWidget = new SMESHGUI_SpinBox( this );
3266 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3267 myToleranceWidget->setAcceptNames( false );
3268 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3271 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3272 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3273 QLabel* anEdgesDouble = createField();
3274 myWidgets << anEdgesDouble;
3275 myPredicates << aFilterMgr->CreateEqualEdges();
3278 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3279 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3280 QLabel* aFacesDouble = createField();
3281 myWidgets << aFacesDouble;
3282 myPredicates << aFilterMgr->CreateEqualFaces();
3283 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3284 QLabel* aFacesOver = createField();
3285 myWidgets << aFacesOver;
3286 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3287 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3288 myPlot = createPlot( this );
3289 myAspectRatio = aFilterMgr->CreateAspectRatio();
3292 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3293 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3294 QLabel* aVolumesDouble = createField();
3295 myWidgets << aVolumesDouble;
3296 myPredicates << aFilterMgr->CreateEqualVolumes();
3297 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3298 QLabel* aVolumesOver = createField();
3299 myWidgets << aVolumesOver;
3300 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3301 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3302 myPlot3D = createPlot( this );
3303 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3305 QToolButton* aFreeNodesBtn = new QToolButton( this );
3306 aFreeNodesBtn->setIcon(aComputeIcon);
3307 myButtons << aFreeNodesBtn; //0
3309 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3310 aNodesNbConnBtn->setIcon(aComputeIcon);
3311 myButtons << aNodesNbConnBtn; //1
3313 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3314 aDoubleNodesBtn->setIcon(aComputeIcon);
3315 myButtons << aDoubleNodesBtn; //2
3317 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3318 aDoubleEdgesBtn->setIcon(aComputeIcon);
3319 myButtons << aDoubleEdgesBtn; //3
3321 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3322 aDoubleFacesBtn->setIcon(aComputeIcon);
3323 myButtons << aDoubleFacesBtn; //4
3325 QToolButton* aOverContFacesBtn = new QToolButton( this );
3326 aOverContFacesBtn->setIcon(aComputeIcon);
3327 myButtons << aOverContFacesBtn; //5
3329 QToolButton* aComputeFaceBtn = new QToolButton( this );
3330 aComputeFaceBtn->setIcon(aComputeIcon);
3331 myButtons << aComputeFaceBtn; //6
3333 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3334 aDoubleVolumesBtn->setIcon(aComputeIcon);
3335 myButtons << aDoubleVolumesBtn; //7
3337 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3338 aOverContVolumesBtn->setIcon(aComputeIcon);
3339 myButtons << aOverContVolumesBtn; //8
3341 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3342 aComputeVolumeBtn->setIcon(aComputeIcon);
3343 myButtons << aComputeVolumeBtn; //9
3345 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3346 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3347 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3348 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3349 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3350 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3351 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3352 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3353 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3354 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3355 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3357 setFontAttributes( aNameLab );
3358 setFontAttributes( aNodesLab );
3359 setFontAttributes( anEdgesLab );
3360 setFontAttributes( aFacesLab );
3361 setFontAttributes( aVolumesLab );
3363 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3364 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3365 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3366 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3367 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3368 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3369 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3370 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3371 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3372 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3373 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3374 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3375 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3376 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3377 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3378 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3379 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3380 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3381 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3382 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3383 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3384 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3385 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3386 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3387 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3388 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3389 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3390 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3391 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3392 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3393 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3394 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3395 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3396 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3397 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3398 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3399 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3400 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3402 myMainLayout->setColumnStretch( 0, 0 );
3403 myMainLayout->setColumnStretch( 1, 5 );
3404 myMainLayout->setRowStretch ( 11, 5 );
3405 myMainLayout->setRowStretch ( 16, 5 );
3406 myMainLayout->setRowStretch ( 17, 1 );
3414 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3418 \brief Change widget font attributes (bold, ...).
3420 \param attr font attributes (XORed flags)
3422 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3425 QFont f = w->font();
3432 \brief Create info field
3433 \return new info field
3435 QLabel* SMESHGUI_CtrlInfo::createField()
3437 QLabel* lab = new QLabel( this );
3438 lab->setFrameStyle( StyledPanel | Sunken );
3439 lab->setAlignment( Qt::AlignCenter );
3440 lab->setAutoFillBackground( true );
3441 QPalette pal = lab->palette();
3442 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3443 lab->setPalette( pal );
3444 lab->setMinimumWidth( 60 );
3449 \brief Create QwtPlot
3452 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3454 QwtPlot* aPlot = new QwtPlot( parent );
3455 aPlot->setMinimumSize( 100, 100 );
3456 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3457 xFont.setPointSize( 5 );
3458 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3459 yFont.setPointSize( 5 );
3460 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3461 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3467 \brief Show controls information on the selected object
3469 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3473 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3474 if ( myObject->_is_nil() ) return;
3476 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3477 myWidgets[0]->setText( aSO->GetName().c_str() );
3479 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3480 if ( mesh->_is_nil() ) return;
3482 const bool meshLoaded = mesh->IsLoaded();
3483 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3484 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3485 for ( int i = 0; i < myButtons.count(); ++i )
3486 myButtons[i]->setEnabled( true );
3488 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3489 if ( ! &nbElemsByType.in() ) return;
3491 const CORBA::Long ctrlLimit =
3492 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3495 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3496 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3497 nbElemsByType[ SMESH::FACE ] +
3498 nbElemsByType[ SMESH::VOLUME ] );
3499 if ( nbNodes + nbElems > 0 ) {
3500 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3502 computeFreeNodesInfo();
3503 computeNodesNbConnInfo();
3505 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3506 computeDoubleNodesInfo();
3509 myButtons[0]->setEnabled( true );
3510 myButtons[1]->setEnabled( true );
3511 myButtons[2]->setEnabled( true );
3515 for( int i=2; i<=11; i++)
3516 myMainLayout->itemAt(i)->widget()->setVisible( false );
3520 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3522 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3523 computeDoubleEdgesInfo();
3525 myButtons[3]->setEnabled( true );
3528 for( int i=11; i<=14; i++)
3529 myMainLayout->itemAt(i)->widget()->setVisible( false );
3533 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3534 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3536 computeDoubleFacesInfo();
3537 // over constrained faces
3538 computeOverConstrainedFacesInfo();
3539 // aspect Ratio histogram
3540 computeAspectRatio();
3543 myButtons[4]->setEnabled( true );
3544 myButtons[5]->setEnabled( true );
3545 myButtons[6]->setEnabled( true );
3547 #ifdef DISABLE_PLOT2DVIEWER
3548 myMainLayout->setRowStretch(12,0);
3549 for( int i=25; i<=27; i++)
3550 myMainLayout->itemAt(i)->widget()->setVisible( false );
3554 myMainLayout->setRowStretch(12,0);
3555 for( int i=18; i<=27; i++)
3556 myMainLayout->itemAt(i)->widget()->setVisible( false );
3560 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3561 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3563 computeDoubleVolumesInfo();
3564 // over constrained volumes
3565 computeOverConstrainedVolumesInfo();
3566 // aspect Ratio 3D histogram
3567 computeAspectRatio3D();
3570 myButtons[7]->setEnabled( true );
3571 myButtons[8]->setEnabled( true );
3572 myButtons[9]->setEnabled( true );
3574 #ifdef DISABLE_PLOT2DVIEWER
3575 myMainLayout->setRowStretch(17,0);
3576 for( int i=35; i<=37; i++)
3577 myMainLayout->itemAt(i)->widget()->setVisible( false );
3581 myMainLayout->setRowStretch(17,0);
3582 for( int i=28; i<=37; i++)
3583 myMainLayout->itemAt(i)->widget()->setVisible( false );
3587 //================================================================================
3589 * \brief Computes and shows nb of elements satisfying a given predicate
3590 * \param [in] ft - a predicate type (SMESH::FunctorType)
3591 * \param [in] iBut - index of one of myButtons to disable
3592 * \param [in] iWdg - index of one of myWidgets to show the computed number
3594 //================================================================================
3596 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3598 myButtons[ iBut ]->setEnabled( false );
3599 myWidgets[ iWdg ]->setText( "" );
3600 if ( myObject->_is_nil() ) return;
3602 SUIT_OverrideCursor wc;
3604 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3605 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3608 this->showInfo( myObject ); // try to show all values
3609 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3610 return; // <ft> predicate already computed
3612 // look for a predicate of type <ft>
3613 for ( int i = 0; i < myPredicates.count(); ++i )
3614 if ( myPredicates[i]->GetFunctorType() == ft )
3616 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3617 myWidgets[ iWdg ]->setText( QString::number( nb ));
3621 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3623 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3626 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3628 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3631 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3633 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3636 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3638 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3641 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3643 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3646 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3648 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3651 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3653 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3656 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3658 myButtons[ 1 ]->setEnabled( false );
3659 myWidgets[ 2 ]->setText( "" );
3660 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3661 if ( mesh->_is_nil() ) return;
3662 if ( !mesh->IsLoaded() )
3665 this->showInfo( myObject ); // try to show all values
3666 if ( !myWidgets[ 2 ]->text().isEmpty() )
3667 return; // already computed
3669 myNodeConnFunctor->SetMesh( mesh );
3670 SMESH::Histogram_var histogram =
3671 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3673 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3676 void SMESHGUI_CtrlInfo::computeAspectRatio()
3678 #ifndef DISABLE_PLOT2DVIEWER
3679 myButtons[6]->setEnabled( false );
3681 if ( myObject->_is_nil() ) return;
3683 SUIT_OverrideCursor wc;
3685 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3686 if ( aHistogram && !aHistogram->isEmpty() ) {
3687 QwtPlotItem* anItem = aHistogram->createPlotItem();
3688 anItem->attach( myPlot );
3695 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3697 #ifndef DISABLE_PLOT2DVIEWER
3698 myButtons[9]->setEnabled( false );
3700 if ( myObject->_is_nil() ) return;
3702 SUIT_OverrideCursor wc;
3704 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3705 if ( aHistogram && !aHistogram->isEmpty() ) {
3706 QwtPlotItem* anItem = aHistogram->createPlotItem();
3707 anItem->attach( myPlot3D );
3715 \brief Internal clean-up (reset widget)
3717 void SMESHGUI_CtrlInfo::clearInternal()
3719 for( int i=0; i<=35; i++)
3720 myMainLayout->itemAt(i)->widget()->setVisible( true );
3721 for( int i=0; i<=9; i++)
3722 myButtons[i]->setEnabled( false );
3723 myPlot->detachItems();
3724 myPlot3D->detachItems();
3727 myWidgets[0]->setText( QString() );
3728 for ( int i = 1; i < myWidgets.count(); i++ )
3729 myWidgets[i]->setText( "" );
3730 myMainLayout->setRowStretch(11,5);
3731 myMainLayout->setRowStretch(16,5);
3734 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3736 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3737 myButtons[1]->setEnabled( true );
3738 myWidgets[2]->setText("");
3741 #ifndef DISABLE_PLOT2DVIEWER
3742 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3744 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3745 if ( mesh->_is_nil() ) return 0;
3746 if ( !mesh->IsLoaded() )
3748 aNumFun->SetMesh( mesh );
3750 CORBA::Long cprecision = 6;
3751 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3752 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3753 aNumFun->SetPrecision( cprecision );
3755 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3757 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3758 /*isLogarithmic=*/false,
3760 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3761 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3762 if ( &histogramVar.in() )
3764 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3765 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3766 if ( histogramVar->length() >= 2 )
3767 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3773 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3774 out << QString( 20, '-' ) << "\n";
3775 out << tr( "CTRL_INFO" ) << "\n";
3776 out << QString( 20, '-' ) << "\n";
3777 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3778 out << tr( "NODES_INFO" ) << "\n";
3779 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3780 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3781 out << tr( "EDGES_INFO" ) << "\n";
3782 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3783 out << tr( "FACES_INFO" ) << "\n";
3784 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3785 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3786 out << tr( "VOLUMES_INFO" ) << "\n";
3787 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3788 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3792 \class SMESHGUI_CtrlInfoDlg
3793 \brief Controls information dialog box
3798 \param parent parent widget
3800 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3803 setAttribute( Qt::WA_DeleteOnClose, true );
3804 setWindowTitle( tr( "CTRL_INFO" ) );
3805 setMinimumSize( 400, 600 );
3807 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3810 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3811 okBtn->setAutoDefault( true );
3812 okBtn->setDefault( true );
3814 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3815 dumpBtn->setAutoDefault( true );
3816 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3817 helpBtn->setAutoDefault( true );
3819 QHBoxLayout* btnLayout = new QHBoxLayout;
3820 btnLayout->setSpacing( SPACING );
3821 btnLayout->setMargin( 0 );
3823 btnLayout->addWidget( okBtn );
3824 btnLayout->addWidget( dumpBtn );
3825 btnLayout->addStretch( 10 );
3826 btnLayout->addWidget( helpBtn );
3828 QVBoxLayout* l = new QVBoxLayout ( this );
3829 l->setMargin( MARGIN );
3830 l->setSpacing( SPACING );
3831 l->addWidget( myCtrlInfo );
3832 l->addLayout( btnLayout );
3834 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3835 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3836 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3837 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3838 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3846 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3851 \brief Show controls information
3852 \param IO interactive object
3854 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3856 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3857 myCtrlInfo->showInfo( obj );
3861 \brief Perform clean-up actions on the dialog box closing.
3863 void SMESHGUI_CtrlInfoDlg::reject()
3865 SMESH::SetPointRepresentation( false );
3870 \brief Setup selection mode depending on the current dialog box state.
3872 void SMESHGUI_CtrlInfoDlg::updateSelection()
3874 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3875 disconnect( selMgr, 0, this, 0 );
3876 SMESH::SetPointRepresentation( false );
3877 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3882 \brief Show mesh information
3884 void SMESHGUI_CtrlInfoDlg::updateInfo()
3886 SUIT_OverrideCursor wc;
3888 SALOME_ListIO selected;
3889 SMESHGUI::selectionMgr()->selectedObjects( selected );
3891 if ( selected.Extent() == 1 ) {
3892 Handle(SALOME_InteractiveObject) IO = selected.First();
3898 \brief Activate dialog box
3900 void SMESHGUI_CtrlInfoDlg::activate()
3902 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3903 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3908 \brief Deactivate dialog box
3910 void SMESHGUI_CtrlInfoDlg::deactivate()
3912 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3916 * \brief Dump contents into a file
3918 void SMESHGUI_CtrlInfoDlg::dump()
3920 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3922 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3923 if ( !appStudy ) return;
3924 _PTR( Study ) aStudy = appStudy->studyDS();
3926 QStringList aFilters;
3927 aFilters.append( tr( "TEXT_FILES" ) );
3929 DumpFileDlg fd( this );
3930 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3931 fd.setNameFilters( aFilters );
3932 fd.myBaseChk->hide();
3933 fd.myElemChk->hide();
3934 fd.myAddChk ->hide();
3935 fd.myCtrlChk->hide();
3936 if ( fd.exec() == QDialog::Accepted )
3938 QString aFileName = fd.selectedFile();
3939 if ( !aFileName.isEmpty() ) {
3940 QFileInfo aFileInfo( aFileName );
3941 if ( aFileInfo.isDir() )
3944 QFile aFile( aFileName );
3945 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3948 QTextStream out( &aFile );
3949 myCtrlInfo->saveInfo( out );
3957 void SMESHGUI_CtrlInfoDlg::help()
3959 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");