1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESHGUI_MeshInfo.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_MeshInfo.h"
27 #include "SMDSAbs_ElementType.hxx"
28 #include "SMDS_BallElement.hxx"
29 #include "SMDS_EdgePosition.hxx"
30 #include "SMDS_FacePosition.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_VolumeTool.hxx"
33 #include "SMESHDS_Mesh.hxx"
35 #include "SMESHGUI_FilterUtils.h"
36 #include "SMESHGUI_IdValidator.h"
37 #include "SMESHGUI_SpinBox.h"
38 #include "SMESHGUI_Utils.h"
39 #include "SMESHGUI_VTKUtils.h"
40 #include "SMESH_Actor.h"
42 #include <LightApp_SelectionMgr.h>
43 #include <SUIT_FileDlg.h>
44 #include <SUIT_OverrideCursor.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SVTK_ViewWindow.h>
49 #include <SALOMEDSClient_Study.hxx>
50 #include <SalomeApp_Study.h>
52 #include <QApplication>
53 #include <QButtonGroup>
55 #include <QContextMenuEvent>
56 #include <QGridLayout>
57 #include <QHBoxLayout>
58 #include <QHeaderView>
59 #include <QItemDelegate>
64 #include <QPushButton>
65 #include <QToolButton>
66 #include <QRadioButton>
67 #include <QTextStream>
69 #include <QTextBrowser>
70 #include <QVBoxLayout>
72 #include "utilities.h"
74 #include <SALOMEconfig.h>
75 #include CORBA_SERVER_HEADER(GEOM_Gen)
79 const int SPACING = 6;
81 const int MAXITEMS = 10;
82 const int GROUPS_ID = 100;
83 const int SUBMESHES_ID = 200;
84 const int SPACING_INFO = 2;
87 TypeRole = Qt::UserRole + 10,
92 NodeConnectivity = 100,
101 class ExtraWidget : public QWidget
104 ExtraWidget( QWidget*, bool = false );
107 void updateControls( int, int, int = MAXITEMS );
116 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
118 current = new QLabel( this );
119 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
120 prev = new QPushButton( tr( "<<" ), this );
121 next = new QPushButton( tr( ">>" ), this );
122 QHBoxLayout* hbl = new QHBoxLayout( this );
123 hbl->setContentsMargins( 0, SPACING, 0, 0 );
124 hbl->setSpacing( SPACING );
126 hbl->addWidget( current );
127 hbl->addWidget( prev );
128 hbl->addWidget( next );
131 ExtraWidget::~ExtraWidget()
135 void ExtraWidget::updateControls( int total, int index, int blockSize )
137 setVisible( total > blockSize );
138 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
139 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) );
140 prev->setEnabled( index > 0 );
141 next->setEnabled( (index+1)*blockSize < total );
146 \brief Customization of standard "Save file" dialog box for dump info operation
150 class DumpFileDlg : public SUIT_FileDlg
153 DumpFileDlg( QWidget* parent );
155 QCheckBox* myBaseChk;
156 QCheckBox* myElemChk;
158 QCheckBox* myCtrlChk;
165 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
167 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
169 QWidget* hB = new QWidget( this );
170 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
171 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
172 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
173 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
175 QGridLayout* layout = new QGridLayout( hB );
176 layout->addWidget( myBaseChk, 0, 0 );
177 layout->addWidget( myElemChk, 0, 1 );
178 layout->addWidget( myAddChk, 1, 0 );
179 layout->addWidget( myCtrlChk, 1, 1 );
181 QPushButton* pb = new QPushButton( this );
183 int row = grid->rowCount();
184 grid->addWidget( new QLabel( "", this ), row, 0 );
185 grid->addWidget( hB, row, 1, 1, 3 );
186 grid->addWidget( pb, row, 5 );
193 \brief Get depth of the tree item
195 \param theItem tree widget item
196 \return item's depth in tree widget (where top-level items have zero depth)
198 static int itemDepth( QTreeWidgetItem* item )
201 QTreeWidgetItem* p = item->parent();
210 \class SMESHGUI_MeshInfo
211 \brief Base mesh information widget
213 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
218 \param parent parent widget
220 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
221 : QFrame( parent ), myWidgets( iElementsEnd )
223 setFrameStyle( StyledPanel | Sunken );
225 QGridLayout* l = new QGridLayout( this );
226 l->setMargin( MARGIN );
227 l->setSpacing( SPACING );
232 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
233 QLabel* aName = createField();
234 aName->setObjectName("meshName");
235 aName->setMinimumWidth( 150 );
236 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
237 QLabel* aObj = createField();
238 aObj->setObjectName("meshType");
239 aObj->setMinimumWidth( 150 );
240 myWidgets[ index++ ] << aNameLab << aName;
241 myWidgets[ index++ ] << aObjLab << aObj;
244 QWidget* aNodesLine = createLine();
245 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
246 QLabel* aNodes = createField();
247 aNodes->setObjectName("nbNodes");
248 myWidgets[ index++ ] << aNodesLine;
249 myWidgets[ index++ ] << aNodesLab << aNodes;
252 QWidget* aElemLine = createLine();
253 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
254 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
255 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
256 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
257 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
258 myWidgets[ index++ ] << aElemLine;
259 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
261 // ... Number elements
262 QWidget* aNbLine = createLine();
263 QLabel* aNbTotal = createField();
264 aNbTotal->setObjectName("totalNbElems");
265 QLabel* aNbLin = createField();
266 aNbLin->setObjectName("totalNbLinearElems");
267 QLabel* aNbQuad = createField();
268 aNbQuad->setObjectName("totalNbQuadraticElems");
269 QLabel* aNbBiQuad = createField();
270 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
271 myWidgets[ index++ ] << aNbLine;
272 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
275 QWidget* a0DLine = createLine();
276 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
277 QLabel* a0DTotal = createField();
278 a0DTotal->setObjectName("nb0D");
280 myWidgets[ index++ ] << a0DLine;
281 myWidgets[ index++ ] << a0DLab << a0DTotal;
284 QWidget* aBallLine = createLine();
285 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
286 QLabel* aBallTotal = createField();
287 aBallTotal->setObjectName("nbBall");
288 myWidgets[ index++ ] << aBallLine;
289 myWidgets[ index++ ] << aBallLab << aBallTotal;
292 QWidget* a1DLine = createLine();
293 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
294 QLabel* a1DTotal = createField();
295 a1DTotal->setObjectName("nb1D");
296 QLabel* a1DLin = createField();
297 a1DLin->setObjectName("nbLinear1D");
298 QLabel* a1DQuad = createField();
299 a1DQuad->setObjectName("nbQuadratic1D");
300 myWidgets[ index++ ] << a1DLine;
301 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
304 QWidget* a2DLine = createLine();
305 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
306 QLabel* a2DTotal = createField();
307 a2DTotal->setObjectName("nb2D");
308 QLabel* a2DLin = createField();
309 a2DLin->setObjectName("nbLinear2D");
310 QLabel* a2DQuad = createField();
311 a2DQuad->setObjectName("nbQuadratic2D");
312 QLabel* a2DBiQuad = createField();
313 a2DBiQuad->setObjectName("nbBiQuadratic2D");
314 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
315 QLabel* a2DTriTotal = createField();
316 a2DTriTotal->setObjectName("nbTriangle");
317 QLabel* a2DTriLin = createField();
318 a2DTriLin->setObjectName("nbLinearTriangle");
319 QLabel* a2DTriQuad = createField();
320 a2DTriQuad->setObjectName("nbQuadraticTriangle");
321 QLabel* a2DTriBiQuad = createField();
322 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
323 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
324 QLabel* a2DQuaTotal = createField();
325 a2DQuaTotal->setObjectName("nbQuadrangle");
326 QLabel* a2DQuaLin = createField();
327 a2DQuaLin->setObjectName("nbLinearQuadrangle");
328 QLabel* a2DQuaQuad = createField();
329 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
330 QLabel* a2DQuaBiQuad = createField();
331 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
332 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
333 QLabel* a2DPolTotal = createField();
334 a2DPolTotal->setObjectName("nbPolygon");
335 QLabel* a2DPolLin = createField();
336 a2DPolLin->setObjectName("nbLinearPolygon");
337 QLabel* a2DPolQuad = createField();
338 a2DPolQuad->setObjectName("nbQuadraticPolygon");
339 myWidgets[ index++ ] << a2DLine;
340 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
341 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
342 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
343 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
346 QWidget* a3DLine = createLine();
347 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
348 QLabel* a3DTotal = createField();
349 a3DTotal->setObjectName("nb3D");
350 QLabel* a3DLin = createField();
351 a3DLin->setObjectName("nbLinear3D");
352 QLabel* a3DQuad = createField();
353 a3DQuad->setObjectName("nbQuadratic3D");
354 QLabel* a3DBiQuad = createField();
355 a3DBiQuad->setObjectName("nbBiQuadratic3D");
356 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
357 QLabel* a3DTetTotal = createField();
358 a3DTetTotal->setObjectName("nbTetrahedron");
359 QLabel* a3DTetLin = createField();
360 a3DTetLin->setObjectName("nbLinearTetrahedron");
361 QLabel* a3DTetQuad = createField();
362 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
363 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
364 QLabel* a3DHexTotal = createField();
365 a3DHexTotal->setObjectName("nbHexahedron");
366 QLabel* a3DHexLin = createField();
367 a3DHexLin->setObjectName("nbLinearHexahedron");
368 QLabel* a3DHexQuad = createField();
369 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
370 QLabel* a3DHexBiQuad = createField();
371 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
372 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
373 QLabel* a3DPyrTotal = createField();
374 a3DPyrTotal->setObjectName("nbPyramid");
375 QLabel* a3DPyrLin = createField();
376 a3DPyrLin->setObjectName("nbLinearPyramid");
377 QLabel* a3DPyrQuad = createField();
378 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
379 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
380 QLabel* a3DPriTotal = createField();
381 a3DPriTotal->setObjectName("nbPrism");
382 QLabel* a3DPriLin = createField();
383 a3DPriLin->setObjectName("nbLinearPrism");
384 QLabel* a3DPriQuad = createField();
385 a3DPriQuad->setObjectName("nbQuadraticPrism");
386 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
387 QLabel* a3DHexPriTotal = createField();
388 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
389 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
390 QLabel* a3DPolTotal = createField();
391 a3DPolTotal->setObjectName("nbPolyhedron");
392 myWidgets[ index++ ] << a3DLine;
393 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
394 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
395 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
396 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
397 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
398 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
399 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
401 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
402 myLoadBtn->setAutoDefault( true );
403 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
405 setFontAttributes( aNameLab, Bold );
406 setFontAttributes( aObjLab, Bold );
407 setFontAttributes( aNodesLab, Bold );
408 setFontAttributes( aElemLab, Bold );
409 setFontAttributes( aElemTotal, Italic );
410 setFontAttributes( aElemLin, Italic );
411 setFontAttributes( aElemQuad, Italic );
412 setFontAttributes( aElemBiQuad, Italic );
413 setFontAttributes( a0DLab, Bold );
414 setFontAttributes( aBallLab, Bold );
415 setFontAttributes( a1DLab, Bold );
416 setFontAttributes( a2DLab, Bold );
417 setFontAttributes( a3DLab, Bold );
419 l->addWidget( aNameLab, 0, 0 );
420 l->addWidget( aName, 0, 1, 1, 4 );
421 l->addWidget( aObjLab, 1, 0 );
422 l->addWidget( aObj, 1, 1, 1, 4 );
423 l->addWidget( aNodesLine, 2, 0, 1, 5 );
424 l->addWidget( aNodesLab, 3, 0 );
425 l->addWidget( aNodes, 3, 1 );
426 l->addWidget( aElemLine, 4, 0, 1, 5 );
427 l->addWidget( aElemLab, 5, 0 );
428 l->addWidget( aElemTotal, 5, 1 );
429 l->addWidget( aElemLin, 5, 2 );
430 l->addWidget( aElemQuad, 5, 3 );
431 l->addWidget( aElemBiQuad, 5, 4 );
432 l->addWidget( aNbLine, 6, 1, 1, 4 );
433 l->addWidget( aNbTotal, 7, 1 );
434 l->addWidget( aNbLin, 7, 2 );
435 l->addWidget( aNbQuad, 7, 3 );
436 l->addWidget( aNbBiQuad, 7, 4 );
437 l->addWidget( a0DLine, 8, 1, 1, 4 );
438 l->addWidget( a0DLab, 9, 0 );
439 l->addWidget( a0DTotal, 9, 1 );
440 l->addWidget( aBallLine, 10, 1, 1, 4 );
441 l->addWidget( aBallLab, 11, 0 );
442 l->addWidget( aBallTotal, 11, 1 );
443 l->addWidget( a1DLine, 12, 1, 1, 4 );
444 l->addWidget( a1DLab, 13, 0 );
445 l->addWidget( a1DTotal, 13, 1 );
446 l->addWidget( a1DLin, 13, 2 );
447 l->addWidget( a1DQuad, 13, 3 );
448 l->addWidget( a2DLine, 14, 1, 1, 4 );
449 l->addWidget( a2DLab, 15, 0 );
450 l->addWidget( a2DTotal, 15, 1 );
451 l->addWidget( a2DLin, 15, 2 );
452 l->addWidget( a2DQuad, 15, 3 );
453 l->addWidget( a2DBiQuad, 15, 4 );
454 l->addWidget( a2DTriLab, 16, 0 );
455 l->addWidget( a2DTriTotal, 16, 1 );
456 l->addWidget( a2DTriLin, 16, 2 );
457 l->addWidget( a2DTriQuad, 16, 3 );
458 l->addWidget( a2DTriBiQuad, 16, 4 );
459 l->addWidget( a2DQuaLab, 17, 0 );
460 l->addWidget( a2DQuaTotal, 17, 1 );
461 l->addWidget( a2DQuaLin, 17, 2 );
462 l->addWidget( a2DQuaQuad, 17, 3 );
463 l->addWidget( a2DQuaBiQuad, 17, 4 );
464 l->addWidget( a2DPolLab, 18, 0 );
465 l->addWidget( a2DPolTotal, 18, 1 );
466 l->addWidget( a2DPolLin, 18, 2 );
467 l->addWidget( a2DPolQuad, 18, 3 );
468 l->addWidget( a3DLine, 19, 1, 1, 4 );
469 l->addWidget( a3DLab, 20, 0 );
470 l->addWidget( a3DTotal, 20, 1 );
471 l->addWidget( a3DLin, 20, 2 );
472 l->addWidget( a3DQuad, 20, 3 );
473 l->addWidget( a3DBiQuad, 20, 4 );
474 l->addWidget( a3DTetLab, 21, 0 );
475 l->addWidget( a3DTetTotal, 21, 1 );
476 l->addWidget( a3DTetLin, 21, 2 );
477 l->addWidget( a3DTetQuad, 21, 3 );
478 l->addWidget( a3DHexLab, 22, 0 );
479 l->addWidget( a3DHexTotal, 22, 1 );
480 l->addWidget( a3DHexLin, 22, 2 );
481 l->addWidget( a3DHexQuad, 22, 3 );
482 l->addWidget( a3DHexBiQuad, 22, 4 );
483 l->addWidget( a3DPyrLab, 23, 0 );
484 l->addWidget( a3DPyrTotal, 23, 1 );
485 l->addWidget( a3DPyrLin, 23, 2 );
486 l->addWidget( a3DPyrQuad, 23, 3 );
487 l->addWidget( a3DPriLab, 24, 0 );
488 l->addWidget( a3DPriTotal, 24, 1 );
489 l->addWidget( a3DPriLin, 24, 2 );
490 l->addWidget( a3DPriQuad, 24, 3 );
491 l->addWidget( a3DHexPriLab, 25, 0 );
492 l->addWidget( a3DHexPriTotal, 25, 1 );
493 l->addWidget( a3DPolLab, 26, 0 );
494 l->addWidget( a3DPolTotal, 26, 1 );
495 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
497 l->setColumnStretch( 0, 0 );
498 l->setColumnStretch( 1, 5 );
499 l->setColumnStretch( 2, 5 );
500 l->setColumnStretch( 3, 5 );
501 l->setColumnStretch( 4, 5 );
502 l->setRowStretch( 27, 5 );
510 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
515 \brief Show information on the mesh object.
516 \param obj object being processed (mesh, sub-mesh, group, ID source)
518 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
521 if ( !CORBA::is_nil( obj ) ) {
522 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
524 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
525 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
526 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
527 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
528 if ( !aMesh->_is_nil() ) {
529 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
531 else if ( !aSubMesh->_is_nil() ) {
532 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
534 else if ( !aGroup->_is_nil() ) {
536 switch( aGroup->GetType() ) {
537 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
538 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
539 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
540 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
541 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
542 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
543 default: objType = tr( "OBJECT_GROUP" );break;
545 myWidgets[iObject][iSingle]->setProperty( "text", objType );
547 SMESH::long_array_var info = obj->GetMeshInfo();
548 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
549 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
550 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
551 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
552 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
553 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
554 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
555 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
556 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
557 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
558 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
559 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
560 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
561 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
563 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
564 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
565 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
566 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
567 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
568 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
569 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
570 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
571 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
572 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
573 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
574 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
575 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
576 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
577 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
578 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
579 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
580 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
581 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
582 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
583 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
584 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
585 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
586 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
587 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
588 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
589 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
590 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
591 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
592 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
593 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
594 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
595 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
596 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
597 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
598 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
599 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
600 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
601 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
602 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
603 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
604 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
605 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
606 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
607 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
608 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
609 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
610 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
611 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
612 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
613 // before full loading from study file, type of elements in a sub-mesh can't be defined
615 bool infoOK = obj->IsMeshInfoCorrect();
616 myLoadBtn->setVisible( !infoOK );
620 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
621 // 2. No info at all (for a group on geom or filter)
622 bool hasAnyInfo = false;
623 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
624 hasAnyInfo = info[i];
625 if ( hasAnyInfo ) // believe it is a sub-mesh
627 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
629 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
630 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
631 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
632 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
633 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
634 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
635 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
636 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
637 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
638 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
640 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
643 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
644 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
645 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
648 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
650 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
651 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
652 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
653 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
654 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
655 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
656 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
661 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
662 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
667 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
668 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
669 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
670 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
671 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
676 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
677 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
678 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
679 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
681 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
682 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
683 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
684 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
685 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
686 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
687 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
688 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
690 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
691 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
692 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
694 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
695 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
696 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
697 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
698 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
699 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
700 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
703 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
704 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
706 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
707 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
712 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
713 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
714 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
715 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
716 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
723 \brief Load mesh from a study file
725 void SMESHGUI_MeshInfo::loadMesh()
727 SUIT_OverrideCursor wc;
729 SALOME_ListIO selected;
730 SMESHGUI::selectionMgr()->selectedObjects( selected );
732 if ( selected.Extent() == 1 ) {
733 Handle(SALOME_InteractiveObject) IO = selected.First();
734 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
735 if ( !CORBA::is_nil( obj ) ) {
736 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
737 if ( !mesh->_is_nil() )
747 \brief Reset the widget to the initial state (nullify all fields).
749 void SMESHGUI_MeshInfo::clear()
751 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
752 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
753 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
754 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
755 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
756 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
757 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
758 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
759 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
760 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
761 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
762 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
763 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
764 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
765 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
766 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
767 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
768 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
769 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
770 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
771 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ) );
772 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
773 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
774 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
775 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
776 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
777 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
778 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
779 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
780 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
781 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
782 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
783 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
784 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
785 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
786 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
787 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
788 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
789 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
790 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
791 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
792 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
793 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
794 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
795 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
796 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
800 \brief Create info field
801 \return new info field
803 QLabel* SMESHGUI_MeshInfo::createField()
805 QLabel* lab = new QLabel( this );
806 lab->setFrameStyle( StyledPanel | Sunken );
807 lab->setAlignment( Qt::AlignCenter );
808 lab->setAutoFillBackground( true );
809 QPalette pal = lab->palette();
810 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
811 lab->setPalette( pal );
812 lab->setMinimumWidth( 70 );
817 \brief Create horizontal rule.
818 \return new line object
820 QWidget* SMESHGUI_MeshInfo::createLine()
822 QFrame* line = new QFrame( this );
823 line->setFrameStyle( HLine | Sunken );
828 \brief Change widget font attributes (bold, italic, ...).
830 \param attr font attributes (XORed flags)
831 \param val value to be set to attributes
833 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
837 if ( attr & Bold ) f.setBold( val );
838 if ( attr & Italic ) f.setItalic( val );
844 \brief Show/hide group(s) of fields.
845 \param start beginning of the block
846 \param end end of the block
847 \param on visibility flag
849 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
851 start = qMax( 0, start );
852 end = qMin( end, (int)iElementsEnd );
853 for ( int i = start; i < end; i++ ) {
854 wlist wl = myWidgets[i];
855 foreach ( QWidget* w, wl ) w->setVisible( on );
859 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
861 out << QString( 9, '-' ) << "\n";
862 out << tr( "BASE_INFO" ) << "\n";
863 out << QString( 9, '-' ) << "\n";
864 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
865 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
866 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
867 out << tr( "ELEMENTS_LAB" ) << "\n";
868 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
869 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
870 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
871 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
872 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
873 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
874 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
875 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
876 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
877 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
878 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
879 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
880 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
881 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
883 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
886 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
887 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
888 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
889 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
890 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
891 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
895 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
899 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
900 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
901 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
903 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
904 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
906 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
907 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
909 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
910 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
911 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
913 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
915 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
917 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
920 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
921 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
923 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
924 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
928 \class SMESHGUI_ElemInfo
929 \brief Base class for the mesh element information widget.
934 \param parent parent widget
936 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
937 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
939 myFrame = new QWidget( this );
940 myExtra = new ExtraWidget( this );
941 QVBoxLayout* vbl = new QVBoxLayout( this );
943 vbl->setSpacing( 0 );
944 vbl->addWidget( myFrame );
945 vbl->addWidget( myExtra );
946 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
947 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
954 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
959 \brief Set mesh data source (actor)
960 \param actor mesh object actor
962 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
964 if ( myActor != actor ) {
972 \brief Show mesh element information
973 \param id mesh node / element ID
974 \param isElem show mesh element information if \c true or mesh node information if \c false
976 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
980 showInfo( ids, isElem );
984 \brief Show mesh element information
985 \param ids mesh nodes / elements identifiers
986 \param isElem show mesh element information if \c true or mesh node information if \c false
988 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
990 QList<long> newIds = ids.toList();
992 if ( myIDs == newIds && myIsElement == isElem ) return;
995 myIsElement = isElem;
998 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1002 \brief Clear mesh element information widget
1004 void SMESHGUI_ElemInfo::clear()
1013 \brief Get central area widget
1014 \return central widget
1016 QWidget* SMESHGUI_ElemInfo::frame() const
1023 \return actor being used
1025 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1031 \brief Get current info mode.
1032 \return \c true if mesh element information is shown or \c false if node information is shown
1034 bool SMESHGUI_ElemInfo::isElements() const
1040 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1041 \brief Show information on the specified nodes / elements
1043 This function is to be redefined in sub-classes.
1045 \param ids nodes / elements identifiers information is to be shown on
1049 \brief Internal clean-up (reset widget)
1051 void SMESHGUI_ElemInfo::clearInternal()
1056 \brief Get node connectivity
1057 \param node mesh node
1058 \return node connectivity map
1060 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1064 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1065 while ( it && it->more() ) {
1066 const SMDS_MeshElement* ne = it->next();
1067 elmap[ ne->GetType() ] << ne->GetID();
1074 \brief Format connectivity data to string representation
1075 \param connectivity connetivity map
1076 \param type element type
1077 \return string representation of the connectivity
1079 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1082 if ( connectivity.contains( type ) ) {
1083 QList<int> elements = connectivity[ type ];
1085 foreach( int id, elements )
1086 str << QString::number( id );
1088 return str.join( " " );
1092 \brief Calculate gravity center of the mesh element
1093 \param element mesh element
1095 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1099 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1100 while ( nodeIt->more() ) {
1101 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1102 xyz.add( node->X(), node->Y(), node->Z() );
1104 xyz.divide( element->NbNodes() );
1110 \brief Calculate normal vector to the mesh face
1111 \param element mesh face
1113 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1115 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1116 return XYZ(n.X(), n.Y(), n.Z());
1120 \brief This slot is called from "Show Previous" button click.
1121 Shows information on the previous group of the items.
1123 void SMESHGUI_ElemInfo::showPrevious()
1125 myIndex = qMax( 0, myIndex-1 );
1127 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1131 \brief This slot is called from "Show Next" button click.
1132 Shows information on the next group of the items.
1134 void SMESHGUI_ElemInfo::showNext()
1136 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1138 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1142 \brief Update widgets state
1144 void SMESHGUI_ElemInfo::updateControls()
1146 myExtra->updateControls( myIDs.count(), myIndex );
1150 \class SMESHGUI_SimpleElemInfo
1151 \brief Represents mesh element information in the simple text area.
1156 \param parent parent widget
1158 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1159 : SMESHGUI_ElemInfo( parent )
1161 myInfo = new QTextBrowser( frame() );
1162 QVBoxLayout* l = new QVBoxLayout( frame() );
1164 l->addWidget( myInfo );
1168 \brief Show mesh element information
1169 \param ids mesh nodes / elements identifiers
1171 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1176 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1177 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1178 int cprecision = -1;
1179 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1180 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1181 foreach ( long id, ids ) {
1182 if ( !isElements() ) {
1186 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1187 if ( !node ) return;
1190 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1192 myInfo->append( "" );
1194 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1195 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1196 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1197 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1199 myInfo->append( "" );
1201 Connectivity connectivity = nodeConnectivity( node );
1202 if ( !connectivity.isEmpty() ) {
1203 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1204 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1205 if ( !con.isEmpty() )
1206 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1207 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1208 if ( !con.isEmpty() )
1209 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1210 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1211 if ( !con.isEmpty() )
1212 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1213 con = formatConnectivity( connectivity, SMDSAbs_Face );
1214 if ( !con.isEmpty() )
1215 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1216 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1217 if ( !con.isEmpty() )
1218 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1221 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1224 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1225 if ( !CORBA::is_nil( aMeshPtr ) ) {
1226 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1227 int shapeID = pos->shapeID;
1228 if ( shapeID > 0 ) {
1230 double u = 0, v = 0;
1231 switch ( pos->shapeType ) {
1233 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1234 if ( pos->params.length() == 1 )
1238 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1239 if ( pos->params.length() == 2 ) {
1245 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1248 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1252 myInfo->append( "" );
1253 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1254 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1255 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1256 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1257 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1258 if ( pos->shapeType == GEOM::FACE ) {
1259 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1260 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1265 // groups node belongs to
1266 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1267 if ( !CORBA::is_nil( aMesh ) ) {
1268 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1269 myInfo->append( "" ); // separator
1270 bool top_created = false;
1271 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1272 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1273 if ( CORBA::is_nil( aGrp ) ) continue;
1274 QString aName = aGrp->GetName();
1275 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1276 if ( !top_created ) {
1277 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1280 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1281 if ( grp_details ) {
1282 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1283 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1284 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1286 // type : group on geometry, standalone group, group on filter
1287 if ( !CORBA::is_nil( aStdGroup ) ) {
1288 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1289 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1291 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1292 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1293 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1294 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1295 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1297 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1298 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1301 else if ( !CORBA::is_nil( aFltGroup ) ) {
1302 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1303 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1307 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1308 arg( QString::number( aGrp->Size() ) ) );
1311 SALOMEDS::Color color = aGrp->GetColor();
1312 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1313 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1321 // show element info
1323 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1324 SMESH::Controls::NumericalFunctorPtr afunctor;
1327 // Element ID && Type
1329 switch( e->GetType() ) {
1330 case SMDSAbs_0DElement:
1331 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1333 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1335 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1337 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1338 case SMDSAbs_Volume:
1339 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1343 if ( stype.isEmpty() ) return;
1344 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1346 myInfo->append( "" );
1350 switch( e->GetEntityType() ) {
1351 case SMDSEntity_Triangle:
1352 case SMDSEntity_Quad_Triangle:
1353 case SMDSEntity_BiQuad_Triangle:
1354 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1355 case SMDSEntity_Quadrangle:
1356 case SMDSEntity_Quad_Quadrangle:
1357 case SMDSEntity_BiQuad_Quadrangle:
1358 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1359 case SMDSEntity_Polygon:
1360 case SMDSEntity_Quad_Polygon:
1361 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1362 case SMDSEntity_Tetra:
1363 case SMDSEntity_Quad_Tetra:
1364 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1365 case SMDSEntity_Pyramid:
1366 case SMDSEntity_Quad_Pyramid:
1367 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1368 case SMDSEntity_Hexa:
1369 case SMDSEntity_Quad_Hexa:
1370 case SMDSEntity_TriQuad_Hexa:
1371 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1372 case SMDSEntity_Penta:
1373 case SMDSEntity_Quad_Penta:
1374 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1375 case SMDSEntity_Hexagonal_Prism:
1376 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1377 case SMDSEntity_Polyhedra:
1378 case SMDSEntity_Quad_Polyhedra:
1379 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1383 if ( !gtype.isEmpty() )
1384 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1386 // Quadratic flag (any element except 0D)
1387 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1388 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1390 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1392 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1395 myInfo->append( "" );
1398 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1399 for ( int idx = 1; nodeIt->more(); idx++ ) {
1400 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1401 // node number and ID
1402 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1404 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1405 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1406 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1407 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1408 // node connectivity
1409 Connectivity connectivity = nodeConnectivity( node );
1410 if ( !connectivity.isEmpty() ) {
1411 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1412 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1413 if ( !con.isEmpty() )
1414 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1415 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1416 if ( !con.isEmpty() )
1417 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1418 con = formatConnectivity( connectivity, SMDSAbs_Face );
1419 if ( !con.isEmpty() )
1420 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1421 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1422 if ( !con.isEmpty() )
1423 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1426 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1430 myInfo->append( "" );
1433 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1435 if ( e->GetType() == SMDSAbs_Edge ) {
1436 afunctor.reset( new SMESH::Controls::Length() );
1437 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1438 afunctor->SetPrecision( cprecision );
1439 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1441 if( e->GetType() == SMDSAbs_Face ) {
1443 afunctor.reset( new SMESH::Controls::Area() );
1444 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1445 afunctor->SetPrecision( cprecision );
1446 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1448 afunctor.reset( new SMESH::Controls::Taper() );
1449 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1450 afunctor->SetPrecision( cprecision );
1451 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1453 afunctor.reset( new SMESH::Controls::AspectRatio() );
1454 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1455 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1457 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1458 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1459 afunctor->SetPrecision( cprecision );
1460 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1462 afunctor.reset( new SMESH::Controls::Warping() );
1463 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1464 afunctor->SetPrecision( cprecision );
1465 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1467 afunctor.reset( new SMESH::Controls::Skew() );
1468 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1469 afunctor->SetPrecision( cprecision );
1470 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1472 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1473 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1474 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1476 if( e->GetType() == SMDSAbs_Volume ) {
1478 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1479 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1480 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1482 afunctor.reset( new SMESH::Controls::Volume() );
1483 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1484 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1486 afunctor.reset( new SMESH::Controls::Volume() );
1487 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1488 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1491 myInfo->append( "" );
1494 XYZ gc = gravityCenter( e );
1495 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1498 if( e->GetType() == SMDSAbs_Face ) {
1499 XYZ gc = normal( e );
1500 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1504 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1505 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1506 if ( !CORBA::is_nil( aMesh ) ) {
1507 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1508 int shapeID = pos.shapeID;
1509 if ( shapeID > 0 ) {
1510 myInfo->append( "" ); // separator
1512 switch ( pos.shapeType ) {
1513 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1514 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1515 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1516 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1517 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1518 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1520 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1525 // Groups the element belongs to
1526 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1527 if ( !CORBA::is_nil( aMesh ) ) {
1528 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1529 myInfo->append( "" ); // separator
1530 bool top_created = false;
1531 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1532 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1533 if ( CORBA::is_nil( aGrp ) ) continue;
1534 QString aName = aGrp->GetName();
1535 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1536 if ( !top_created ) {
1537 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1540 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1541 if ( grp_details ) {
1542 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1543 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1544 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1546 // type : group on geometry, standalone group, group on filter
1547 if ( !CORBA::is_nil( aStdGroup ) ) {
1548 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1549 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1551 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1552 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1553 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1554 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1555 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1557 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1558 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1561 else if ( !CORBA::is_nil( aFltGroup ) ) {
1562 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1563 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1566 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1567 arg( QString::number( aGrp->Size() ) ) );
1570 SALOMEDS::Color color = aGrp->GetColor();
1571 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1572 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1579 if ( ids.count() > 1 ) {
1580 myInfo->append( "" );
1581 myInfo->append( "------" );
1582 myInfo->append( "" );
1589 \brief Internal clean-up (reset widget)
1591 void SMESHGUI_SimpleElemInfo::clearInternal()
1596 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1598 out << QString( 12, '-' ) << "\n";
1599 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1600 out << QString( 12, '-' ) << "\n";
1601 out << myInfo->toPlainText();
1607 \class SMESHGUI_TreeElemInfo::ItemDelegate
1608 \brief Item delegate for tree mesh info widget
1611 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1614 ItemDelegate( QObject* );
1615 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1622 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1627 \brief Create item editor widget
1630 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1632 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1633 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1638 \class SMESHGUI_TreeElemInfo
1639 \brief Represents mesh element information in the tree-like form.
1644 \param parent parent widget
1646 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1647 : SMESHGUI_ElemInfo( parent )
1649 myInfo = new QTreeWidget( frame() );
1650 myInfo->setColumnCount( 2 );
1651 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1652 myInfo->header()->setStretchLastSection( true );
1653 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1654 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1656 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1658 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1659 QVBoxLayout* l = new QVBoxLayout( frame() );
1661 l->addWidget( myInfo );
1662 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1666 \brief Show mesh element information
1667 \param ids mesh nodes / elements identifiers
1669 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1674 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1675 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1676 int cprecision = -1;
1677 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1678 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1679 foreach ( long id, ids ) {
1680 if ( !isElements() ) {
1684 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1686 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1689 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1690 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1691 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1693 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1694 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1695 QTreeWidgetItem* xItem = createItem( coordItem );
1696 xItem->setText( 0, "X" );
1697 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1698 QTreeWidgetItem* yItem = createItem( coordItem );
1699 yItem->setText( 0, "Y" );
1700 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1701 QTreeWidgetItem* zItem = createItem( coordItem );
1702 zItem->setText( 0, "Z" );
1703 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1705 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1706 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1707 Connectivity connectivity = nodeConnectivity( node );
1708 if ( !connectivity.isEmpty() ) {
1709 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1710 if ( !con.isEmpty() ) {
1711 QTreeWidgetItem* i = createItem( conItem );
1712 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1713 i->setText( 1, con );
1715 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1716 if ( !con.isEmpty() ) {
1717 QTreeWidgetItem* i = createItem( conItem );
1718 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1719 i->setText( 1, con );
1720 i->setData( 1, TypeRole, NodeConnectivity );
1722 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1723 if ( !con.isEmpty() ) {
1724 QTreeWidgetItem* i = createItem( conItem );
1725 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1726 i->setText( 1, con );
1727 i->setData( 1, TypeRole, NodeConnectivity );
1729 con = formatConnectivity( connectivity, SMDSAbs_Face );
1730 if ( !con.isEmpty() ) {
1731 QTreeWidgetItem* i = createItem( conItem );
1732 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1733 i->setText( 1, con );
1734 i->setData( 1, TypeRole, NodeConnectivity );
1736 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1737 if ( !con.isEmpty() ) {
1738 QTreeWidgetItem* i = createItem( conItem );
1739 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1740 i->setText( 1, con );
1741 i->setData( 1, TypeRole, NodeConnectivity );
1745 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1748 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1749 if ( !CORBA::is_nil( aMeshPtr ) ) {
1750 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1751 int shapeID = pos->shapeID;
1752 if ( shapeID > 0 ) {
1754 double u = 0, v = 0;
1755 switch ( pos->shapeType ) {
1757 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1758 if ( pos->params.length() == 1 )
1762 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1763 if ( pos->params.length() == 2 ) {
1769 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1772 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1775 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1776 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1777 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1778 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1779 QTreeWidgetItem* uItem = createItem( posItem );
1780 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1781 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1782 if ( pos->shapeType == GEOM::FACE ) {
1783 QTreeWidgetItem* vItem = createItem( posItem );
1784 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1785 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1790 // groups node belongs to
1791 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1792 if ( !CORBA::is_nil( aMesh ) ) {
1793 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1794 QTreeWidgetItem* groupsItem = 0;
1795 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1796 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1797 if ( CORBA::is_nil( aGrp ) ) continue;
1798 QString aName = aGrp->GetName();
1799 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1800 if ( !groupsItem ) {
1801 groupsItem = createItem( nodeItem, Bold );
1802 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1804 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1805 it->setText( 0, aName.trimmed() );
1806 if ( grp_details ) {
1807 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1808 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1809 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1811 // type : group on geometry, standalone group, group on filter
1812 QTreeWidgetItem* typeItem = createItem( it );
1813 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1814 if ( !CORBA::is_nil( aStdGroup ) ) {
1815 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1817 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1818 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1819 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1820 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1822 QTreeWidgetItem* gobjItem = createItem( typeItem );
1823 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1824 gobjItem->setText( 1, sobj->GetName().c_str() );
1827 else if ( !CORBA::is_nil( aFltGroup ) ) {
1828 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1832 QTreeWidgetItem* sizeItem = createItem( it );
1833 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1834 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1837 SALOMEDS::Color color = aGrp->GetColor();
1838 QTreeWidgetItem* colorItem = createItem( it );
1839 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1840 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1848 // show element info
1850 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1851 SMESH::Controls::NumericalFunctorPtr afunctor;
1854 // element ID && type
1856 switch( e->GetType() ) {
1857 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1858 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1859 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1860 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1861 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1864 if ( stype.isEmpty() ) return;
1865 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1866 elemItem->setText( 0, stype );
1867 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1870 switch( e->GetEntityType() ) {
1871 case SMDSEntity_Triangle:
1872 case SMDSEntity_Quad_Triangle:
1873 case SMDSEntity_BiQuad_Triangle:
1874 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1875 case SMDSEntity_Quadrangle:
1876 case SMDSEntity_Quad_Quadrangle:
1877 case SMDSEntity_BiQuad_Quadrangle:
1878 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1879 case SMDSEntity_Polygon:
1880 case SMDSEntity_Quad_Polygon:
1881 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1882 case SMDSEntity_Tetra:
1883 case SMDSEntity_Quad_Tetra:
1884 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1885 case SMDSEntity_Pyramid:
1886 case SMDSEntity_Quad_Pyramid:
1887 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1888 case SMDSEntity_Hexa:
1889 case SMDSEntity_Quad_Hexa:
1890 case SMDSEntity_TriQuad_Hexa:
1891 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1892 case SMDSEntity_Penta:
1893 case SMDSEntity_Quad_Penta:
1894 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1895 case SMDSEntity_Hexagonal_Prism:
1896 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1897 case SMDSEntity_Polyhedra:
1898 case SMDSEntity_Quad_Polyhedra:
1899 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1903 if ( !gtype.isEmpty() ) {
1904 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1905 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1906 typeItem->setText( 1, gtype );
1908 // quadratic flag (for edges, faces and volumes)
1909 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1911 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1912 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1913 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1915 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1917 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1918 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1919 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1922 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1923 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1926 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1927 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1928 for ( int idx = 1; nodeIt->more(); idx++ ) {
1929 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1930 nodeInfo( node, idx, e->NbNodes(), conItem );
1934 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1935 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1936 QList<const SMDS_MeshElement*> uniqueNodes;
1937 while ( nodeIt->more() )
1938 uniqueNodes.append( nodeIt->next() );
1940 SMDS_VolumeTool vtool( e );
1941 const int nbFaces = vtool.NbFaces();
1942 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1943 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1944 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1945 faceItem->setExpanded( true );
1947 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1948 const int nbNodes = vtool.NbFaceNodes( face_id );
1949 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1950 const SMDS_MeshNode* node = aNodeIds[node_id];
1951 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1956 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1957 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1959 if( e->GetType()==SMDSAbs_Edge){
1960 afunctor.reset( new SMESH::Controls::Length() );
1961 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1962 afunctor->SetPrecision( cprecision );
1963 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1964 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1965 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1967 if( e->GetType() == SMDSAbs_Face ) {
1969 afunctor.reset( new SMESH::Controls::Area() );
1970 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1971 afunctor->SetPrecision( cprecision );
1972 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1973 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1974 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1976 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1978 afunctor.reset( new SMESH::Controls::Taper() );
1979 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1980 afunctor->SetPrecision( cprecision );
1981 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1982 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1983 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1985 afunctor.reset( new SMESH::Controls::Warping() );
1986 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1987 afunctor->SetPrecision( cprecision );
1988 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1989 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1990 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1995 afunctor.reset( new SMESH::Controls::AspectRatio() );
1996 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1997 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1998 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1999 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2002 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2003 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2004 afunctor->SetPrecision( cprecision );
2005 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2006 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
2007 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2009 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2011 afunctor.reset( new SMESH::Controls::Skew() );
2012 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2013 afunctor->SetPrecision( cprecision );
2014 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2015 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
2016 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2021 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2022 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2023 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2024 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2025 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2028 if( e->GetType() == SMDSAbs_Volume ) {
2032 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2033 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2034 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2035 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
2036 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 XYZ gc = gravityCenter( e );
2054 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2055 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
2056 QTreeWidgetItem* xItem = createItem( gcItem );
2057 xItem->setText( 0, "X" );
2058 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2059 QTreeWidgetItem* yItem = createItem( gcItem );
2060 yItem->setText( 0, "Y" );
2061 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2062 QTreeWidgetItem* zItem = createItem( gcItem );
2063 zItem->setText( 0, "Z" );
2064 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2067 if( e->GetType() == SMDSAbs_Face ) {
2068 XYZ gc = normal( e );
2069 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2070 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2071 QTreeWidgetItem* xItem = createItem( nItem );
2072 xItem->setText( 0, "X" );
2073 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2074 QTreeWidgetItem* yItem = createItem( nItem );
2075 yItem->setText( 0, "Y" );
2076 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2077 QTreeWidgetItem* zItem = createItem( nItem );
2078 zItem->setText( 0, "Z" );
2079 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2083 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2084 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2085 if ( !CORBA::is_nil( aMesh ) ) {
2086 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2087 int shapeID = pos.shapeID;
2088 if ( shapeID > 0 ) {
2089 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2091 switch ( pos.shapeType ) {
2092 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2093 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2094 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2095 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2096 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2097 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2099 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2100 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2104 // groups element belongs to
2105 if ( !CORBA::is_nil( aMesh ) ) {
2106 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2107 QTreeWidgetItem* groupsItem = 0;
2108 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2109 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2110 if ( CORBA::is_nil( aGrp ) ) continue;
2111 QString aName = aGrp->GetName();
2112 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2113 if ( !groupsItem ) {
2114 groupsItem = createItem( elemItem, Bold );
2115 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2117 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2118 it->setText( 0, aName.trimmed() );
2119 if ( grp_details ) {
2120 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2121 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2122 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2124 // type : group on geometry, standalone group, group on filter
2125 QTreeWidgetItem* typeItem = createItem( it );
2126 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2127 if ( !CORBA::is_nil( aStdGroup ) ) {
2128 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2130 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2131 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2132 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2133 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2135 QTreeWidgetItem* gobjItem = createItem( typeItem );
2136 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2137 gobjItem->setText( 1, sobj->GetName().c_str() );
2140 else if ( !CORBA::is_nil( aFltGroup ) ) {
2141 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2145 QTreeWidgetItem* sizeItem = createItem( it );
2146 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2147 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2150 SALOMEDS::Color color = aGrp->GetColor();
2151 QTreeWidgetItem* colorItem = createItem( it );
2152 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2153 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2164 \brief Show node information
2165 \param node mesh node for showing
2166 \param index index of current node
2167 \param nbNodes number of unique nodes in element
2168 \param parentItem parent item of tree
2170 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2171 int nbNodes, QTreeWidgetItem* parentItem )
2173 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2174 // node number and ID
2175 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2176 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2177 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2178 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2179 nodeItem->setData( 1, IdRole, node->GetID() );
2180 nodeItem->setExpanded( false );
2182 QTreeWidgetItem* coordItem = createItem( nodeItem );
2183 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2184 QTreeWidgetItem* xItem = createItem( coordItem );
2185 xItem->setText( 0, "X" );
2186 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2187 QTreeWidgetItem* yItem = createItem( coordItem );
2188 yItem->setText( 0, "Y" );
2189 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2190 QTreeWidgetItem* zItem = createItem( coordItem );
2191 zItem->setText( 0, "Z" );
2192 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2193 // node connectivity
2194 QTreeWidgetItem* nconItem = createItem( nodeItem );
2195 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2196 Connectivity connectivity = nodeConnectivity( node );
2197 if ( !connectivity.isEmpty() ) {
2198 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2199 if ( !con.isEmpty() ) {
2200 QTreeWidgetItem* i = createItem( nconItem );
2201 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2202 i->setText( 1, con );
2204 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2205 if ( !con.isEmpty() ) {
2206 QTreeWidgetItem* i = createItem( nconItem );
2207 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2208 i->setText( 1, con );
2209 i->setData( 1, TypeRole, NodeConnectivity );
2211 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2212 if ( !con.isEmpty() ) {
2213 QTreeWidgetItem* i = createItem( nconItem );
2214 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2215 i->setText( 1, con );
2216 i->setData( 1, TypeRole, NodeConnectivity );
2218 con = formatConnectivity( connectivity, SMDSAbs_Face );
2219 if ( !con.isEmpty() ) {
2220 QTreeWidgetItem* i = createItem( nconItem );
2221 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2222 i->setText( 1, con );
2223 i->setData( 1, TypeRole, NodeConnectivity );
2225 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2226 if ( !con.isEmpty() ) {
2227 QTreeWidgetItem* i = createItem( nconItem );
2228 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2229 i->setText( 1, con );
2230 i->setData( 1, TypeRole, NodeConnectivity );
2235 \brief Internal clean-up (reset widget)
2237 void SMESHGUI_TreeElemInfo::clearInternal()
2244 \brief Create new tree item.
2245 \param parent parent tree widget item
2246 \param flags item flag
2247 \return new tree widget item
2249 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2251 QTreeWidgetItem* item;
2253 item = new QTreeWidgetItem( parent );
2255 item = new QTreeWidgetItem( myInfo );
2257 item->setFlags( item->flags() | Qt::ItemIsEditable );
2259 QFont f = item->font( 0 );
2261 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2262 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2263 item->setFont( i, f );
2266 item->setExpanded( true );
2270 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2272 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2273 if ( widgets.isEmpty() ) return;
2274 QTreeWidgetItem* aTreeItem = widgets.first();
2275 int type = aTreeItem->data( 1, TypeRole ).toInt();
2276 int id = aTreeItem->data( 1, IdRole ).toInt();
2278 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2279 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2280 emit( itemInfo( id ) );
2281 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2282 emit( itemInfo( aTreeItem->text( 1 ) ) );
2285 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2288 int type = theItem->data( 1, TypeRole ).toInt();
2289 int id = theItem->data( 1, IdRole ).toInt();
2290 if ( type == ElemConnectivity && id > 0 )
2291 emit( itemInfo( id ) );
2292 else if ( type == NodeConnectivity )
2293 emit( itemInfo( theItem->text( 1 ) ) );
2297 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2299 out << QString( 12, '-' ) << "\n";
2300 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2301 out << QString( 12, '-' ) << "\n";
2303 QTreeWidgetItemIterator it( myInfo );
2305 if ( !( *it )->text(0).isEmpty() ) {
2306 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2307 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2317 \brief Mesh information computer
2320 The class is created for different computation operation. Currently it is used
2321 to compute number of underlying nodes for the groups.
2327 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2328 QTreeWidgetItem* item,
2331 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2333 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2337 \brief Compute function
2339 void GrpComputor::compute()
2341 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2342 SUIT_OverrideCursor wc;
2343 QTreeWidgetItem* item = myItem;
2345 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2346 item->treeWidget()->removeItemWidget( item, 1 );
2347 item->setText( 1, QString::number( nb ));
2352 \class SMESHGUI_AddInfo
2353 \brief The wigdet shows additional information on the mesh object.
2358 \param parent parent widget
2360 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2361 : QTreeWidget( parent )
2363 setColumnCount( 2 );
2364 header()->setStretchLastSection( true );
2365 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2366 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2368 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2376 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2381 \brief Show additional information on the selected object
2382 \param obj object being processed (mesh, sub-mesh, group, ID source)
2384 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2386 setProperty( "group_index", 0 );
2387 setProperty( "submesh_index", 0 );
2388 myComputors.clear();
2391 if ( CORBA::is_nil( obj ) ) return;
2393 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2394 if ( !sobj ) return;
2397 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2398 nameItem->setText( 0, tr( "NAME" ) );
2399 nameItem->setText( 1, sobj->GetName().c_str() );
2401 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2402 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2403 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2405 if ( !aMesh->_is_nil() )
2406 meshInfo( aMesh, nameItem );
2407 else if ( !aSubMesh->_is_nil() )
2408 subMeshInfo( aSubMesh, nameItem );
2409 else if ( !aGroup->_is_nil() )
2410 groupInfo( aGroup.in(), nameItem );
2414 \brief Create new tree item.
2415 \param parent parent tree widget item
2416 \param flags item flag
2417 \return new tree widget item
2419 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2421 QTreeWidgetItem* item;
2424 item = new QTreeWidgetItem( parent );
2426 item = new QTreeWidgetItem( this );
2428 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2430 QFont f = item->font( 0 );
2432 for ( int i = 0; i < columnCount(); i++ ) {
2433 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2434 item->setFont( i, f );
2437 item->setExpanded( true );
2442 \brief Show mesh info
2443 \param mesh mesh object
2444 \param parent parent tree item
2446 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2449 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2450 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2451 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2452 typeItem->setText( 0, tr( "TYPE" ) );
2453 if ( !CORBA::is_nil( shape ) ) {
2454 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2455 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2457 QTreeWidgetItem* gobjItem = createItem( typeItem );
2458 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2459 gobjItem->setText( 1, sobj->GetName().c_str() );
2462 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2463 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2464 QTreeWidgetItem* fileItem = createItem( typeItem );
2465 fileItem->setText( 0, tr( "FILE_NAME" ) );
2466 fileItem->setText( 1, (char*)inf->fileName );
2469 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2473 myGroups = mesh->GetGroups();
2477 mySubMeshes = mesh->GetSubMeshes();
2482 \brief Show sub-mesh info
2483 \param subMesh sub-mesh object
2484 \param parent parent tree item
2486 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2488 bool isShort = parent->parent() != 0;
2492 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2494 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2495 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2496 nameItem->setText( 1, sobj->GetName().c_str() );
2501 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2502 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2504 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2505 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2506 gobjItem->setText( 1, sobj->GetName().c_str() );
2511 \brief Show group info
2512 \param grp mesh group object
2513 \param parent parent tree item
2515 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2517 bool isShort = parent->parent() != 0;
2519 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2520 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2521 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2525 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2527 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2528 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2529 nameItem->setText( 1, sobj->GetName().c_str() );
2533 // type : group on geometry, standalone group, group on filter
2534 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2535 typeItem->setText( 0, tr( "TYPE" ) );
2536 if ( !CORBA::is_nil( aStdGroup ) ) {
2537 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2539 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2540 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2541 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2542 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2544 QTreeWidgetItem* gobjItem = createItem( typeItem );
2545 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2546 gobjItem->setText( 1, sobj->GetName().c_str() );
2549 else if ( !CORBA::is_nil( aFltGroup ) ) {
2550 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2555 QString etype = tr( "UNKNOWN" );
2556 switch( grp->GetType() ) {
2558 etype = tr( "NODE" );
2561 etype = tr( "EDGE" );
2564 etype = tr( "FACE" );
2567 etype = tr( "VOLUME" );
2570 etype = tr( "0DELEM" );
2573 etype = tr( "BALL" );
2578 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2579 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2580 etypeItem->setText( 1, etype );
2583 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2584 bool meshLoaded = mesh->IsLoaded();
2586 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2588 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2589 groupSize = grp->Size();
2591 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2592 sizeItem->setText( 0, tr( "SIZE" ) );
2593 if ( groupSize > -1 ) {
2594 sizeItem->setText( 1, QString::number( groupSize ) );
2597 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2598 setItemWidget( sizeItem, 1, btn );
2599 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2600 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2601 myComputors.append( comp );
2603 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2607 SALOMEDS::Color color = grp->GetColor();
2608 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2609 colorItem->setText( 0, tr( "COLOR" ) );
2610 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2612 // nb of underlying nodes
2613 if ( grp->GetType() != SMESH::NODE) {
2614 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2615 nodesItem->setText( 0, tr( "NB_NODES" ) );
2616 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2617 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2618 if ( toShowNodes && meshLoaded ) {
2619 // already calculated and up-to-date
2620 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2623 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2624 setItemWidget( nodesItem, 1, btn );
2625 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2626 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2627 myComputors.append( comp );
2629 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2634 void SMESHGUI_AddInfo::showGroups()
2636 myComputors.clear();
2638 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2639 if ( !parent ) return;
2641 int idx = property( "group_index" ).toInt();
2643 QTreeWidgetItem* itemGroups = 0;
2644 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2645 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2646 itemGroups = parent->child( i );
2647 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2649 extra->updateControls( myGroups->length(), idx );
2650 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2654 QMap<int, QTreeWidgetItem*> grpItems;
2655 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2656 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2657 if ( CORBA::is_nil( grp ) ) continue;
2658 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2659 if ( !grpSObj ) continue;
2661 int grpType = grp->GetType();
2663 if ( !itemGroups ) {
2664 // create top-level groups container item
2665 itemGroups = createItem( parent, Bold | All );
2666 itemGroups->setText( 0, tr( "GROUPS" ) );
2667 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2669 // total number of groups > 10, show extra widgets for info browsing
2670 if ((int) myGroups->length() > MAXITEMS ) {
2671 ExtraWidget* extra = new ExtraWidget( this, true );
2672 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2673 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2674 setItemWidget( itemGroups, 1, extra );
2675 extra->updateControls( myGroups->length(), idx );
2679 if ( grpItems.find( grpType ) == grpItems.end() ) {
2680 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2681 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2682 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2686 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2687 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2690 groupInfo( grp.in(), grpNameItem );
2694 void SMESHGUI_AddInfo::showSubMeshes()
2696 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2697 if ( !parent ) return;
2699 int idx = property( "submesh_index" ).toInt();
2701 QTreeWidgetItem* itemSubMeshes = 0;
2702 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2703 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2704 itemSubMeshes = parent->child( i );
2705 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2707 extra->updateControls( mySubMeshes->length(), idx );
2708 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2712 QMap<int, QTreeWidgetItem*> smItems;
2713 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2714 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2715 if ( CORBA::is_nil( sm ) ) continue;
2716 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2717 if ( !smSObj ) continue;
2719 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2720 if ( CORBA::is_nil(gobj ) ) continue;
2722 int smType = gobj->GetShapeType();
2723 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2725 if ( !itemSubMeshes ) {
2726 itemSubMeshes = createItem( parent, Bold | All );
2727 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2728 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2730 // total number of sub-meshes > 10, show extra widgets for info browsing
2731 if ((int) mySubMeshes->length() > MAXITEMS ) {
2732 ExtraWidget* extra = new ExtraWidget( this, true );
2733 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2734 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2735 setItemWidget( itemSubMeshes, 1, extra );
2736 extra->updateControls( mySubMeshes->length(), idx );
2740 if ( smItems.find( smType ) == smItems.end() ) {
2741 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2742 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2743 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2747 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2748 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2751 subMeshInfo( sm.in(), smNameItem );
2756 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2758 void SMESHGUI_AddInfo::changeLoadToCompute()
2760 for ( int i = 0; i < myComputors.count(); ++i )
2762 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2764 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2765 btn->setText( tr("COMPUTE") );
2770 void SMESHGUI_AddInfo::showPreviousGroups()
2772 int idx = property( "group_index" ).toInt();
2773 setProperty( "group_index", idx-1 );
2777 void SMESHGUI_AddInfo::showNextGroups()
2779 int idx = property( "group_index" ).toInt();
2780 setProperty( "group_index", idx+1 );
2784 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2786 int idx = property( "submesh_index" ).toInt();
2787 setProperty( "submesh_index", idx-1 );
2791 void SMESHGUI_AddInfo::showNextSubMeshes()
2793 int idx = property( "submesh_index" ).toInt();
2794 setProperty( "submesh_index", idx+1 );
2798 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2800 out << QString( 15, '-') << "\n";
2801 out << tr( "ADDITIONAL_INFO" ) << "\n";
2802 out << QString( 15, '-' ) << "\n";
2803 QTreeWidgetItemIterator it( this );
2805 if ( !( ( *it )->text(0) ).isEmpty() ) {
2806 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2807 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2808 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2810 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2819 \class SMESHGUI_MeshInfoDlg
2820 \brief Mesh information dialog box
2825 \param parent parent widget
2826 \param page specifies the dialog page to be shown at the start-up
2828 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2829 : QDialog( parent ), myActor( 0 )
2832 setAttribute( Qt::WA_DeleteOnClose, true );
2833 setWindowTitle( tr( "MESH_INFO" ) );
2834 setSizeGripEnabled( true );
2836 myTabWidget = new QTabWidget( this );
2840 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2841 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2845 QWidget* w = new QWidget( myTabWidget );
2847 myMode = new QButtonGroup( this );
2848 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2849 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2850 myMode->button( NodeMode )->setChecked( true );
2851 myID = new QLineEdit( w );
2852 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2854 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2855 mode = qMin( 1, qMax( 0, mode ) );
2858 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2860 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2862 QGridLayout* elemLayout = new QGridLayout( w );
2863 elemLayout->setMargin( MARGIN );
2864 elemLayout->setSpacing( SPACING );
2865 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2866 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2867 elemLayout->addWidget( myID, 0, 2 );
2868 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2870 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2874 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2875 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2879 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2880 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2884 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2885 okBtn->setAutoDefault( true );
2886 okBtn->setDefault( true );
2888 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2889 dumpBtn->setAutoDefault( true );
2890 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2891 helpBtn->setAutoDefault( true );
2893 QHBoxLayout* btnLayout = new QHBoxLayout;
2894 btnLayout->setSpacing( SPACING );
2895 btnLayout->setMargin( 0 );
2897 btnLayout->addWidget( okBtn );
2898 btnLayout->addWidget( dumpBtn );
2899 btnLayout->addStretch( 10 );
2900 btnLayout->addWidget( helpBtn );
2902 QVBoxLayout* l = new QVBoxLayout ( this );
2903 l->setMargin( MARGIN );
2904 l->setSpacing( SPACING );
2905 l->addWidget( myTabWidget );
2906 l->addLayout( btnLayout );
2908 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2910 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2911 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2912 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2913 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2914 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2915 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2916 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2917 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2918 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2919 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2927 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2932 \brief Show mesh information
2933 \param IO interactive object
2935 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2940 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2941 if ( !CORBA::is_nil( obj ) )
2943 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2944 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2945 if ( myTabWidget->currentIndex() == CtrlInfo )
2946 myCtrlInfo->showInfo( obj );
2949 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2950 SVTK_Selector* selector = SMESH::GetSelector();
2953 if ( myActor && selector ) {
2954 nb = myMode->checkedId() == NodeMode ?
2955 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2956 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2958 myElemInfo->setSource( myActor ) ;
2960 myID->setText( ID.trimmed() );
2962 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2963 foreach ( ID, idTxt )
2964 ids << ID.trimmed().toLong();
2965 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2969 myElemInfo->clear();
2976 \brief Perform clean-up actions on the dialog box closing.
2978 void SMESHGUI_MeshInfoDlg::reject()
2980 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2981 selMgr->clearFilters();
2982 SMESH::SetPointRepresentation( false );
2983 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2984 aViewWindow->SetSelectionMode( ActorSelection );
2989 \brief Process keyboard event
2990 \param e key press event
2992 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2994 QDialog::keyPressEvent( e );
2995 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3002 \brief Reactivate dialog box, when mouse pointer goes into it.
3004 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3010 \brief Setup selection mode depending on the current dialog box state.
3012 void SMESHGUI_MeshInfoDlg::updateSelection()
3014 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3016 disconnect( selMgr, 0, this, 0 );
3017 selMgr->clearFilters();
3019 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
3020 SMESH::SetPointRepresentation( false );
3021 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3022 aViewWindow->SetSelectionMode( ActorSelection );
3025 if ( myMode->checkedId() == NodeMode ) {
3026 SMESH::SetPointRepresentation( true );
3027 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3028 aViewWindow->SetSelectionMode( NodeSelection );
3031 SMESH::SetPointRepresentation( false );
3032 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3033 aViewWindow->SetSelectionMode( CellSelection );
3037 QString oldID = myID->text().trimmed();
3038 SMESH_Actor* oldActor = myActor;
3041 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3044 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3045 myID->setText( oldID );
3051 \brief Show help page
3053 void SMESHGUI_MeshInfoDlg::help()
3055 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3056 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3057 "mesh_infos_page.html#mesh_element_info_anchor" );
3061 \brief Show mesh information
3063 void SMESHGUI_MeshInfoDlg::updateInfo()
3065 SUIT_OverrideCursor wc;
3067 SALOME_ListIO selected;
3068 SMESHGUI::selectionMgr()->selectedObjects( selected );
3070 if ( selected.Extent() == 1 ) {
3071 Handle(SALOME_InteractiveObject) IO = selected.First();
3080 \brief Activate dialog box
3082 void SMESHGUI_MeshInfoDlg::activate()
3084 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3085 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3086 myTabWidget->setEnabled( true );
3091 \brief Deactivate dialog box
3093 void SMESHGUI_MeshInfoDlg::deactivate()
3095 myTabWidget->setEnabled( false );
3096 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3100 \brief Called when users switches between node / element modes.
3102 void SMESHGUI_MeshInfoDlg::modeChanged()
3109 \brief Caled when users prints mesh element ID in the corresponding field.
3111 void SMESHGUI_MeshInfoDlg::idChanged()
3113 SVTK_Selector* selector = SMESH::GetSelector();
3114 if ( myActor && selector ) {
3115 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3116 TColStd_MapOfInteger ID;
3118 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3119 foreach ( QString tid, idTxt ) {
3120 long id = tid.trimmed().toLong();
3121 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3122 myActor->GetObject()->GetMesh()->FindElement( id ) :
3123 myActor->GetObject()->GetMesh()->FindNode( id );
3129 selector->AddOrRemoveIndex( IO, ID, false );
3130 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3131 aViewWindow->highlight( IO, true, true );
3132 aViewWindow->Repaint();
3134 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3138 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3140 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3141 myMode->button( NodeMode )->click();
3142 myID->setText( QString::number( id ) );
3146 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3148 if ( !theStr.isEmpty() ) {
3149 myMode->button( ElemMode )->click();
3150 myID->setText( theStr );
3154 void SMESHGUI_MeshInfoDlg::dump()
3156 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3158 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3159 if ( !appStudy ) return;
3160 _PTR( Study ) aStudy = appStudy->studyDS();
3162 QStringList aFilters;
3163 aFilters.append( tr( "TEXT_FILES" ) );
3165 bool anIsBase = true;
3166 bool anIsElem = true;
3167 bool anIsAdd = true;
3168 bool anIsCtrl = true;
3170 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3171 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3172 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3173 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3174 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3177 DumpFileDlg fd( this );
3178 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3179 fd.setNameFilters( aFilters );
3180 fd.myBaseChk->setChecked( anIsBase );
3181 fd.myElemChk->setChecked( anIsElem );
3182 fd.myAddChk ->setChecked( anIsAdd );
3183 fd.myCtrlChk->setChecked( anIsCtrl );
3184 if ( fd.exec() == QDialog::Accepted )
3186 QString aFileName = fd.selectedFile();
3188 bool toBase = fd.myBaseChk->isChecked();
3189 bool toElem = fd.myElemChk->isChecked();
3190 bool toAdd = fd.myAddChk->isChecked();
3191 bool toCtrl = fd.myCtrlChk->isChecked();
3193 if ( !aFileName.isEmpty() ) {
3194 QFileInfo aFileInfo( aFileName );
3195 if ( aFileInfo.isDir() )
3198 QFile aFile( aFileName );
3199 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3202 QTextStream out( &aFile );
3204 if ( toBase ) myBaseInfo->saveInfo( out );
3205 if ( toElem ) myElemInfo->saveInfo( out );
3206 if ( toAdd ) myAddInfo ->saveInfo( out );
3207 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3213 \class SMESHGUI_CtrlInfo
3214 \brief Class for the mesh controls information widget.
3219 \param parent parent widget
3221 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3222 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3224 setFrameStyle( StyledPanel | Sunken );
3226 myMainLayout = new QGridLayout( this );
3227 myMainLayout->setMargin( MARGIN );
3228 myMainLayout->setSpacing( SPACING );
3231 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3232 QLabel* aName = createField();
3233 aName->setMinimumWidth( 150 );
3236 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3237 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3239 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3242 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3243 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3244 QLabel* aNodesFree = createField();
3245 myWidgets << aNodesFree;
3246 myPredicates << aFilterMgr->CreateFreeNodes();
3248 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3249 QLabel* aNodesNbConn = createField();
3250 myWidgets << aNodesNbConn;
3251 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3253 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3254 QLabel* aNodesDouble = createField();
3255 myWidgets << aNodesDouble;
3256 myPredicates << aFilterMgr->CreateEqualNodes();
3257 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3258 myToleranceWidget = new SMESHGUI_SpinBox( this );
3259 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3260 myToleranceWidget->setAcceptNames( false );
3261 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3264 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3265 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3266 QLabel* anEdgesDouble = createField();
3267 myWidgets << anEdgesDouble;
3268 myPredicates << aFilterMgr->CreateEqualEdges();
3271 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3272 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3273 QLabel* aFacesDouble = createField();
3274 myWidgets << aFacesDouble;
3275 myPredicates << aFilterMgr->CreateEqualFaces();
3276 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3277 QLabel* aFacesOver = createField();
3278 myWidgets << aFacesOver;
3279 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3280 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3281 myPlot = createPlot( this );
3282 myAspectRatio = aFilterMgr->CreateAspectRatio();
3285 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3286 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3287 QLabel* aVolumesDouble = createField();
3288 myWidgets << aVolumesDouble;
3289 myPredicates << aFilterMgr->CreateEqualVolumes();
3290 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3291 QLabel* aVolumesOver = createField();
3292 myWidgets << aVolumesOver;
3293 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3294 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3295 myPlot3D = createPlot( this );
3296 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3298 QToolButton* aFreeNodesBtn = new QToolButton( this );
3299 aFreeNodesBtn->setIcon(aComputeIcon);
3300 myButtons << aFreeNodesBtn; //0
3302 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3303 aNodesNbConnBtn->setIcon(aComputeIcon);
3304 myButtons << aNodesNbConnBtn; //1
3306 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3307 aDoubleNodesBtn->setIcon(aComputeIcon);
3308 myButtons << aDoubleNodesBtn; //2
3310 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3311 aDoubleEdgesBtn->setIcon(aComputeIcon);
3312 myButtons << aDoubleEdgesBtn; //3
3314 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3315 aDoubleFacesBtn->setIcon(aComputeIcon);
3316 myButtons << aDoubleFacesBtn; //4
3318 QToolButton* aOverContFacesBtn = new QToolButton( this );
3319 aOverContFacesBtn->setIcon(aComputeIcon);
3320 myButtons << aOverContFacesBtn; //5
3322 QToolButton* aComputeFaceBtn = new QToolButton( this );
3323 aComputeFaceBtn->setIcon(aComputeIcon);
3324 myButtons << aComputeFaceBtn; //6
3326 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3327 aDoubleVolumesBtn->setIcon(aComputeIcon);
3328 myButtons << aDoubleVolumesBtn; //7
3330 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3331 aOverContVolumesBtn->setIcon(aComputeIcon);
3332 myButtons << aOverContVolumesBtn; //8
3334 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3335 aComputeVolumeBtn->setIcon(aComputeIcon);
3336 myButtons << aComputeVolumeBtn; //9
3338 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3339 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3340 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3341 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3342 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3343 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3344 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3345 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3346 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3347 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3348 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3350 setFontAttributes( aNameLab );
3351 setFontAttributes( aNodesLab );
3352 setFontAttributes( anEdgesLab );
3353 setFontAttributes( aFacesLab );
3354 setFontAttributes( aVolumesLab );
3356 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3357 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3358 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3359 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3360 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3361 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3362 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3363 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3364 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3365 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3366 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3367 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3368 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3369 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3370 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3371 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3372 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3373 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3374 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3375 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3376 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3377 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3378 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3379 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3380 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3381 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3382 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3383 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3384 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3385 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3386 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3387 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3388 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3389 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3390 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3391 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3392 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3393 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3395 myMainLayout->setColumnStretch( 0, 0 );
3396 myMainLayout->setColumnStretch( 1, 5 );
3397 myMainLayout->setRowStretch ( 11, 5 );
3398 myMainLayout->setRowStretch ( 16, 5 );
3399 myMainLayout->setRowStretch ( 17, 1 );
3407 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3411 \brief Change widget font attributes (bold, ...).
3413 \param attr font attributes (XORed flags)
3415 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3418 QFont f = w->font();
3425 \brief Create info field
3426 \return new info field
3428 QLabel* SMESHGUI_CtrlInfo::createField()
3430 QLabel* lab = new QLabel( this );
3431 lab->setFrameStyle( StyledPanel | Sunken );
3432 lab->setAlignment( Qt::AlignCenter );
3433 lab->setAutoFillBackground( true );
3434 QPalette pal = lab->palette();
3435 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3436 lab->setPalette( pal );
3437 lab->setMinimumWidth( 60 );
3442 \brief Create QwtPlot
3445 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3447 QwtPlot* aPlot = new QwtPlot( parent );
3448 aPlot->setMinimumSize( 100, 100 );
3449 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3450 xFont.setPointSize( 5 );
3451 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3452 yFont.setPointSize( 5 );
3453 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3454 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3460 \brief Show controls information on the selected object
3462 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3466 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3467 if ( myObject->_is_nil() ) return;
3469 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3470 myWidgets[0]->setText( aSO->GetName().c_str() );
3472 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3473 if ( mesh->_is_nil() ) return;
3475 const bool meshLoaded = mesh->IsLoaded();
3476 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3477 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3478 for ( int i = 0; i < myButtons.count(); ++i )
3479 myButtons[i]->setEnabled( true );
3481 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3482 if ( ! &nbElemsByType.in() ) return;
3484 const CORBA::Long ctrlLimit =
3485 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3488 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3489 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3490 nbElemsByType[ SMESH::FACE ] +
3491 nbElemsByType[ SMESH::VOLUME ] );
3492 if ( nbNodes + nbElems > 0 ) {
3493 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3495 computeFreeNodesInfo();
3496 computeNodesNbConnInfo();
3498 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3499 computeDoubleNodesInfo();
3502 myButtons[0]->setEnabled( true );
3503 myButtons[1]->setEnabled( true );
3504 myButtons[2]->setEnabled( true );
3508 for( int i=2; i<=11; i++)
3509 myMainLayout->itemAt(i)->widget()->setVisible( false );
3513 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3515 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3516 computeDoubleEdgesInfo();
3518 myButtons[3]->setEnabled( true );
3521 for( int i=11; i<=14; i++)
3522 myMainLayout->itemAt(i)->widget()->setVisible( false );
3526 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3527 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3529 computeDoubleFacesInfo();
3530 // over constrained faces
3531 computeOverConstrainedFacesInfo();
3532 // aspect Ratio histogram
3533 computeAspectRatio();
3536 myButtons[4]->setEnabled( true );
3537 myButtons[5]->setEnabled( true );
3538 myButtons[6]->setEnabled( true );
3540 #ifdef DISABLE_PLOT2DVIEWER
3541 myMainLayout->setRowStretch(12,0);
3542 for( int i=25; i<=27; i++)
3543 myMainLayout->itemAt(i)->widget()->setVisible( false );
3547 myMainLayout->setRowStretch(12,0);
3548 for( int i=18; i<=27; i++)
3549 myMainLayout->itemAt(i)->widget()->setVisible( false );
3553 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3554 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3556 computeDoubleVolumesInfo();
3557 // over constrained volumes
3558 computeOverConstrainedVolumesInfo();
3559 // aspect Ratio 3D histogram
3560 computeAspectRatio3D();
3563 myButtons[7]->setEnabled( true );
3564 myButtons[8]->setEnabled( true );
3565 myButtons[9]->setEnabled( true );
3567 #ifdef DISABLE_PLOT2DVIEWER
3568 myMainLayout->setRowStretch(17,0);
3569 for( int i=35; i<=37; i++)
3570 myMainLayout->itemAt(i)->widget()->setVisible( false );
3574 myMainLayout->setRowStretch(17,0);
3575 for( int i=28; i<=37; i++)
3576 myMainLayout->itemAt(i)->widget()->setVisible( false );
3580 //================================================================================
3582 * \brief Computes and shows nb of elements satisfying a given predicate
3583 * \param [in] ft - a predicate type (SMESH::FunctorType)
3584 * \param [in] iBut - index of one of myButtons to disable
3585 * \param [in] iWdg - index of one of myWidgets to show the computed number
3587 //================================================================================
3589 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3591 myButtons[ iBut ]->setEnabled( false );
3592 myWidgets[ iWdg ]->setText( "" );
3593 if ( myObject->_is_nil() ) return;
3595 SUIT_OverrideCursor wc;
3597 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3598 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3601 this->showInfo( myObject ); // try to show all values
3602 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3603 return; // <ft> predicate already computed
3605 // look for a predicate of type <ft>
3606 for ( int i = 0; i < myPredicates.count(); ++i )
3607 if ( myPredicates[i]->GetFunctorType() == ft )
3609 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3610 myWidgets[ iWdg ]->setText( QString::number( nb ));
3614 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3616 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3619 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3621 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3624 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3626 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3629 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3631 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3634 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3636 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3639 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3641 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3644 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3646 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3649 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3651 myButtons[ 1 ]->setEnabled( false );
3652 myWidgets[ 2 ]->setText( "" );
3653 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3654 if ( mesh->_is_nil() ) return;
3655 if ( !mesh->IsLoaded() )
3658 this->showInfo( myObject ); // try to show all values
3659 if ( !myWidgets[ 2 ]->text().isEmpty() )
3660 return; // already computed
3662 myNodeConnFunctor->SetMesh( mesh );
3663 SMESH::Histogram_var histogram =
3664 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3666 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3669 void SMESHGUI_CtrlInfo::computeAspectRatio()
3671 #ifndef DISABLE_PLOT2DVIEWER
3672 myButtons[6]->setEnabled( false );
3674 if ( myObject->_is_nil() ) return;
3676 SUIT_OverrideCursor wc;
3678 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3679 if ( aHistogram && !aHistogram->isEmpty() ) {
3680 QwtPlotItem* anItem = aHistogram->createPlotItem();
3681 anItem->attach( myPlot );
3688 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3690 #ifndef DISABLE_PLOT2DVIEWER
3691 myButtons[9]->setEnabled( false );
3693 if ( myObject->_is_nil() ) return;
3695 SUIT_OverrideCursor wc;
3697 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3698 if ( aHistogram && !aHistogram->isEmpty() ) {
3699 QwtPlotItem* anItem = aHistogram->createPlotItem();
3700 anItem->attach( myPlot3D );
3708 \brief Internal clean-up (reset widget)
3710 void SMESHGUI_CtrlInfo::clearInternal()
3712 for( int i=0; i<=35; i++)
3713 myMainLayout->itemAt(i)->widget()->setVisible( true );
3714 for( int i=0; i<=9; i++)
3715 myButtons[i]->setEnabled( false );
3716 myPlot->detachItems();
3717 myPlot3D->detachItems();
3720 myWidgets[0]->setText( QString() );
3721 for ( int i = 1; i < myWidgets.count(); i++ )
3722 myWidgets[i]->setText( "" );
3723 myMainLayout->setRowStretch(11,5);
3724 myMainLayout->setRowStretch(16,5);
3727 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3729 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3730 myButtons[1]->setEnabled( true );
3731 myWidgets[2]->setText("");
3734 #ifndef DISABLE_PLOT2DVIEWER
3735 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3737 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3738 if ( mesh->_is_nil() ) return 0;
3739 if ( !mesh->IsLoaded() )
3741 aNumFun->SetMesh( mesh );
3743 CORBA::Long cprecision = 6;
3744 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3745 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3746 aNumFun->SetPrecision( cprecision );
3748 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3750 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3751 /*isLogarithmic=*/false,
3753 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3754 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3755 if ( &histogramVar.in() )
3757 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3758 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3759 if ( histogramVar->length() >= 2 )
3760 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3766 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3767 out << QString( 20, '-' ) << "\n";
3768 out << tr( "CTRL_INFO" ) << "\n";
3769 out << QString( 20, '-' ) << "\n";
3770 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3771 out << tr( "NODES_INFO" ) << "\n";
3772 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3773 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3774 out << tr( "EDGES_INFO" ) << "\n";
3775 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3776 out << tr( "FACES_INFO" ) << "\n";
3777 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3778 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3779 out << tr( "VOLUMES_INFO" ) << "\n";
3780 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3781 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3785 \class SMESHGUI_CtrlInfoDlg
3786 \brief Controls information dialog box
3791 \param parent parent widget
3793 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3796 setAttribute( Qt::WA_DeleteOnClose, true );
3797 setWindowTitle( tr( "CTRL_INFO" ) );
3798 setMinimumSize( 400, 600 );
3800 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3803 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3804 okBtn->setAutoDefault( true );
3805 okBtn->setDefault( true );
3807 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3808 dumpBtn->setAutoDefault( true );
3809 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3810 helpBtn->setAutoDefault( true );
3812 QHBoxLayout* btnLayout = new QHBoxLayout;
3813 btnLayout->setSpacing( SPACING );
3814 btnLayout->setMargin( 0 );
3816 btnLayout->addWidget( okBtn );
3817 btnLayout->addWidget( dumpBtn );
3818 btnLayout->addStretch( 10 );
3819 btnLayout->addWidget( helpBtn );
3821 QVBoxLayout* l = new QVBoxLayout ( this );
3822 l->setMargin( MARGIN );
3823 l->setSpacing( SPACING );
3824 l->addWidget( myCtrlInfo );
3825 l->addLayout( btnLayout );
3827 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3828 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3829 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3830 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3831 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3839 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3844 \brief Show controls information
3845 \param IO interactive object
3847 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3849 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3850 myCtrlInfo->showInfo( obj );
3854 \brief Perform clean-up actions on the dialog box closing.
3856 void SMESHGUI_CtrlInfoDlg::reject()
3858 SMESH::SetPointRepresentation( false );
3863 \brief Setup selection mode depending on the current dialog box state.
3865 void SMESHGUI_CtrlInfoDlg::updateSelection()
3867 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3868 disconnect( selMgr, 0, this, 0 );
3869 SMESH::SetPointRepresentation( false );
3870 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3875 \brief Show mesh information
3877 void SMESHGUI_CtrlInfoDlg::updateInfo()
3879 SUIT_OverrideCursor wc;
3881 SALOME_ListIO selected;
3882 SMESHGUI::selectionMgr()->selectedObjects( selected );
3884 if ( selected.Extent() == 1 ) {
3885 Handle(SALOME_InteractiveObject) IO = selected.First();
3891 \brief Activate dialog box
3893 void SMESHGUI_CtrlInfoDlg::activate()
3895 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3896 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3901 \brief Deactivate dialog box
3903 void SMESHGUI_CtrlInfoDlg::deactivate()
3905 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3909 * \brief Dump contents into a file
3911 void SMESHGUI_CtrlInfoDlg::dump()
3913 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3915 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3916 if ( !appStudy ) return;
3917 _PTR( Study ) aStudy = appStudy->studyDS();
3919 QStringList aFilters;
3920 aFilters.append( tr( "TEXT_FILES" ) );
3922 DumpFileDlg fd( this );
3923 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3924 fd.setNameFilters( aFilters );
3925 fd.myBaseChk->hide();
3926 fd.myElemChk->hide();
3927 fd.myAddChk ->hide();
3928 fd.myCtrlChk->hide();
3929 if ( fd.exec() == QDialog::Accepted )
3931 QString aFileName = fd.selectedFile();
3932 if ( !aFileName.isEmpty() ) {
3933 QFileInfo aFileInfo( aFileName );
3934 if ( aFileInfo.isDir() )
3937 QFile aFile( aFileName );
3938 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3941 QTextStream out( &aFile );
3942 myCtrlInfo->saveInfo( out );
3950 void SMESHGUI_CtrlInfoDlg::help()
3952 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");