1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESHGUI_MeshInfo.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SMESHGUI_MeshInfo.h"
27 #include "SMDSAbs_ElementType.hxx"
28 #include "SMDS_BallElement.hxx"
29 #include "SMDS_EdgePosition.hxx"
30 #include "SMDS_FacePosition.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_VolumeTool.hxx"
33 #include "SMESHDS_Mesh.hxx"
35 #include "SMESHGUI_FilterUtils.h"
36 #include "SMESHGUI_IdPreview.h"
37 #include "SMESHGUI_IdValidator.h"
38 #include "SMESHGUI_SpinBox.h"
39 #include "SMESHGUI_Utils.h"
40 #include "SMESHGUI_VTKUtils.h"
41 #include "SMESH_Actor.h"
43 #include <LightApp_SelectionMgr.h>
44 #include <SUIT_FileDlg.h>
45 #include <SUIT_OverrideCursor.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_Session.h>
48 #include <SVTK_ViewWindow.h>
50 #include <SALOMEDSClient_Study.hxx>
51 #include <SalomeApp_Study.h>
53 #include <QApplication>
54 #include <QButtonGroup>
56 #include <QContextMenuEvent>
57 #include <QGridLayout>
58 #include <QHBoxLayout>
59 #include <QHeaderView>
60 #include <QItemDelegate>
65 #include <QPushButton>
66 #include <QToolButton>
67 #include <QRadioButton>
68 #include <QTextStream>
70 #include <QTextBrowser>
71 #include <QVBoxLayout>
73 #include "utilities.h"
75 #include <SALOMEconfig.h>
76 #include CORBA_SERVER_HEADER(GEOM_Gen)
80 const int SPACING = 6;
82 const int MAXITEMS = 10;
83 const int GROUPS_ID = 100;
84 const int SUBMESHES_ID = 200;
85 const int SPACING_INFO = 2;
87 const char* id_preview_resource = "id_preview_resource";
90 TypeRole = Qt::UserRole + 10,
95 NodeConnectivity = 100,
104 class ExtraWidget : public QWidget
107 ExtraWidget( QWidget*, bool = false );
110 void updateControls( int, int, int = MAXITEMS );
119 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
121 current = new QLabel( this );
122 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
123 prev = new QPushButton( tr( "<<" ), this );
124 next = new QPushButton( tr( ">>" ), this );
125 QHBoxLayout* hbl = new QHBoxLayout( this );
126 hbl->setContentsMargins( 0, SPACING, 0, 0 );
127 hbl->setSpacing( SPACING );
129 hbl->addWidget( current );
130 hbl->addWidget( prev );
131 hbl->addWidget( next );
134 ExtraWidget::~ExtraWidget()
138 void ExtraWidget::updateControls( int total, int index, int blockSize )
140 setVisible( total > blockSize );
141 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
142 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total )).arg( total ));
143 prev->setEnabled( index > 0 );
144 next->setEnabled( (index+1)*blockSize < total );
149 \brief Customization of standard "Save file" dialog box for dump info operation
153 class DumpFileDlg : public SUIT_FileDlg
156 DumpFileDlg( QWidget* parent );
158 QCheckBox* myBaseChk;
159 QCheckBox* myElemChk;
161 QCheckBox* myCtrlChk;
168 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
170 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
172 QWidget* hB = new QWidget( this );
173 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
174 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
175 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
176 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
178 QGridLayout* layout = new QGridLayout( hB );
179 layout->addWidget( myBaseChk, 0, 0 );
180 layout->addWidget( myElemChk, 0, 1 );
181 layout->addWidget( myAddChk, 1, 0 );
182 layout->addWidget( myCtrlChk, 1, 1 );
184 QPushButton* pb = new QPushButton( this );
186 int row = grid->rowCount();
187 grid->addWidget( new QLabel( "", this ), row, 0 );
188 grid->addWidget( hB, row, 1, 1, 3 );
189 grid->addWidget( pb, row, 5 );
196 \brief Get depth of the tree item
198 \param theItem tree widget item
199 \return item's depth in tree widget (where top-level items have zero depth)
201 static int itemDepth( QTreeWidgetItem* item )
204 QTreeWidgetItem* p = item->parent();
213 \class SMESHGUI_MeshInfo
214 \brief Base mesh information widget
216 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
221 \param parent parent widget
223 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
224 : QFrame( parent ), myWidgets( iElementsEnd )
226 setFrameStyle( StyledPanel | Sunken );
228 QGridLayout* l = new QGridLayout( this );
229 l->setMargin( MARGIN );
230 l->setSpacing( SPACING );
235 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
236 QLabel* aName = createField();
237 aName->setObjectName("meshName");
238 aName->setMinimumWidth( 150 );
239 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
240 QLabel* aObj = createField();
241 aObj->setObjectName("meshType");
242 aObj->setMinimumWidth( 150 );
243 myWidgets[ index++ ] << aNameLab << aName;
244 myWidgets[ index++ ] << aObjLab << aObj;
247 QWidget* aNodesLine = createLine();
248 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
249 QLabel* aNodes = createField();
250 aNodes->setObjectName("nbNodes");
251 myWidgets[ index++ ] << aNodesLine;
252 myWidgets[ index++ ] << aNodesLab << aNodes;
255 QWidget* aElemLine = createLine();
256 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
257 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
258 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
259 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
260 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
261 myWidgets[ index++ ] << aElemLine;
262 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
264 // ... Number elements
265 QWidget* aNbLine = createLine();
266 QLabel* aNbTotal = createField();
267 aNbTotal->setObjectName("totalNbElems");
268 QLabel* aNbLin = createField();
269 aNbLin->setObjectName("totalNbLinearElems");
270 QLabel* aNbQuad = createField();
271 aNbQuad->setObjectName("totalNbQuadraticElems");
272 QLabel* aNbBiQuad = createField();
273 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
274 myWidgets[ index++ ] << aNbLine;
275 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
278 QWidget* a0DLine = createLine();
279 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
280 QLabel* a0DTotal = createField();
281 a0DTotal->setObjectName("nb0D");
283 myWidgets[ index++ ] << a0DLine;
284 myWidgets[ index++ ] << a0DLab << a0DTotal;
287 QWidget* aBallLine = createLine();
288 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
289 QLabel* aBallTotal = createField();
290 aBallTotal->setObjectName("nbBall");
291 myWidgets[ index++ ] << aBallLine;
292 myWidgets[ index++ ] << aBallLab << aBallTotal;
295 QWidget* a1DLine = createLine();
296 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
297 QLabel* a1DTotal = createField();
298 a1DTotal->setObjectName("nb1D");
299 QLabel* a1DLin = createField();
300 a1DLin->setObjectName("nbLinear1D");
301 QLabel* a1DQuad = createField();
302 a1DQuad->setObjectName("nbQuadratic1D");
303 myWidgets[ index++ ] << a1DLine;
304 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
307 QWidget* a2DLine = createLine();
308 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
309 QLabel* a2DTotal = createField();
310 a2DTotal->setObjectName("nb2D");
311 QLabel* a2DLin = createField();
312 a2DLin->setObjectName("nbLinear2D");
313 QLabel* a2DQuad = createField();
314 a2DQuad->setObjectName("nbQuadratic2D");
315 QLabel* a2DBiQuad = createField();
316 a2DBiQuad->setObjectName("nbBiQuadratic2D");
317 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
318 QLabel* a2DTriTotal = createField();
319 a2DTriTotal->setObjectName("nbTriangle");
320 QLabel* a2DTriLin = createField();
321 a2DTriLin->setObjectName("nbLinearTriangle");
322 QLabel* a2DTriQuad = createField();
323 a2DTriQuad->setObjectName("nbQuadraticTriangle");
324 QLabel* a2DTriBiQuad = createField();
325 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
326 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
327 QLabel* a2DQuaTotal = createField();
328 a2DQuaTotal->setObjectName("nbQuadrangle");
329 QLabel* a2DQuaLin = createField();
330 a2DQuaLin->setObjectName("nbLinearQuadrangle");
331 QLabel* a2DQuaQuad = createField();
332 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
333 QLabel* a2DQuaBiQuad = createField();
334 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
335 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
336 QLabel* a2DPolTotal = createField();
337 a2DPolTotal->setObjectName("nbPolygon");
338 QLabel* a2DPolLin = createField();
339 a2DPolLin->setObjectName("nbLinearPolygon");
340 QLabel* a2DPolQuad = createField();
341 a2DPolQuad->setObjectName("nbQuadraticPolygon");
342 myWidgets[ index++ ] << a2DLine;
343 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
344 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
345 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
346 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
349 QWidget* a3DLine = createLine();
350 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
351 QLabel* a3DTotal = createField();
352 a3DTotal->setObjectName("nb3D");
353 QLabel* a3DLin = createField();
354 a3DLin->setObjectName("nbLinear3D");
355 QLabel* a3DQuad = createField();
356 a3DQuad->setObjectName("nbQuadratic3D");
357 QLabel* a3DBiQuad = createField();
358 a3DBiQuad->setObjectName("nbBiQuadratic3D");
359 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
360 QLabel* a3DTetTotal = createField();
361 a3DTetTotal->setObjectName("nbTetrahedron");
362 QLabel* a3DTetLin = createField();
363 a3DTetLin->setObjectName("nbLinearTetrahedron");
364 QLabel* a3DTetQuad = createField();
365 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
366 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
367 QLabel* a3DHexTotal = createField();
368 a3DHexTotal->setObjectName("nbHexahedron");
369 QLabel* a3DHexLin = createField();
370 a3DHexLin->setObjectName("nbLinearHexahedron");
371 QLabel* a3DHexQuad = createField();
372 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
373 QLabel* a3DHexBiQuad = createField();
374 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
375 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
376 QLabel* a3DPyrTotal = createField();
377 a3DPyrTotal->setObjectName("nbPyramid");
378 QLabel* a3DPyrLin = createField();
379 a3DPyrLin->setObjectName("nbLinearPyramid");
380 QLabel* a3DPyrQuad = createField();
381 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
382 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
383 QLabel* a3DPriTotal = createField();
384 a3DPriTotal->setObjectName("nbPrism");
385 QLabel* a3DPriLin = createField();
386 a3DPriLin->setObjectName("nbLinearPrism");
387 QLabel* a3DPriQuad = createField();
388 a3DPriQuad->setObjectName("nbQuadraticPrism");
389 QLabel* a3DPriBiQuad = createField();
390 a3DPriBiQuad->setObjectName("nbBiQuadraticPrism");
391 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
392 QLabel* a3DHexPriTotal = createField();
393 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
394 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
395 QLabel* a3DPolTotal = createField();
396 a3DPolTotal->setObjectName("nbPolyhedron");
397 myWidgets[ index++ ] << a3DLine;
398 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
399 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
400 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
401 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
402 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad;
403 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
404 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
406 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
407 myLoadBtn->setAutoDefault( true );
408 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ));
410 setFontAttributes( aNameLab, Bold );
411 setFontAttributes( aObjLab, Bold );
412 setFontAttributes( aNodesLab, Bold );
413 setFontAttributes( aElemLab, Bold );
414 setFontAttributes( aElemTotal, Italic );
415 setFontAttributes( aElemLin, Italic );
416 setFontAttributes( aElemQuad, Italic );
417 setFontAttributes( aElemBiQuad, Italic );
418 setFontAttributes( a0DLab, Bold );
419 setFontAttributes( aBallLab, Bold );
420 setFontAttributes( a1DLab, Bold );
421 setFontAttributes( a2DLab, Bold );
422 setFontAttributes( a3DLab, Bold );
424 l->addWidget( aNameLab, 0, 0 );
425 l->addWidget( aName, 0, 1, 1, 4 );
426 l->addWidget( aObjLab, 1, 0 );
427 l->addWidget( aObj, 1, 1, 1, 4 );
428 l->addWidget( aNodesLine, 2, 0, 1, 5 );
429 l->addWidget( aNodesLab, 3, 0 );
430 l->addWidget( aNodes, 3, 1 );
431 l->addWidget( aElemLine, 4, 0, 1, 5 );
432 l->addWidget( aElemLab, 5, 0 );
433 l->addWidget( aElemTotal, 5, 1 );
434 l->addWidget( aElemLin, 5, 2 );
435 l->addWidget( aElemQuad, 5, 3 );
436 l->addWidget( aElemBiQuad, 5, 4 );
437 l->addWidget( aNbLine, 6, 1, 1, 4 );
438 l->addWidget( aNbTotal, 7, 1 );
439 l->addWidget( aNbLin, 7, 2 );
440 l->addWidget( aNbQuad, 7, 3 );
441 l->addWidget( aNbBiQuad, 7, 4 );
442 l->addWidget( a0DLine, 8, 1, 1, 4 );
443 l->addWidget( a0DLab, 9, 0 );
444 l->addWidget( a0DTotal, 9, 1 );
445 l->addWidget( aBallLine, 10, 1, 1, 4 );
446 l->addWidget( aBallLab, 11, 0 );
447 l->addWidget( aBallTotal, 11, 1 );
448 l->addWidget( a1DLine, 12, 1, 1, 4 );
449 l->addWidget( a1DLab, 13, 0 );
450 l->addWidget( a1DTotal, 13, 1 );
451 l->addWidget( a1DLin, 13, 2 );
452 l->addWidget( a1DQuad, 13, 3 );
453 l->addWidget( a2DLine, 14, 1, 1, 4 );
454 l->addWidget( a2DLab, 15, 0 );
455 l->addWidget( a2DTotal, 15, 1 );
456 l->addWidget( a2DLin, 15, 2 );
457 l->addWidget( a2DQuad, 15, 3 );
458 l->addWidget( a2DBiQuad, 15, 4 );
459 l->addWidget( a2DTriLab, 16, 0 );
460 l->addWidget( a2DTriTotal, 16, 1 );
461 l->addWidget( a2DTriLin, 16, 2 );
462 l->addWidget( a2DTriQuad, 16, 3 );
463 l->addWidget( a2DTriBiQuad, 16, 4 );
464 l->addWidget( a2DQuaLab, 17, 0 );
465 l->addWidget( a2DQuaTotal, 17, 1 );
466 l->addWidget( a2DQuaLin, 17, 2 );
467 l->addWidget( a2DQuaQuad, 17, 3 );
468 l->addWidget( a2DQuaBiQuad, 17, 4 );
469 l->addWidget( a2DPolLab, 18, 0 );
470 l->addWidget( a2DPolTotal, 18, 1 );
471 l->addWidget( a2DPolLin, 18, 2 );
472 l->addWidget( a2DPolQuad, 18, 3 );
473 l->addWidget( a3DLine, 19, 1, 1, 4 );
474 l->addWidget( a3DLab, 20, 0 );
475 l->addWidget( a3DTotal, 20, 1 );
476 l->addWidget( a3DLin, 20, 2 );
477 l->addWidget( a3DQuad, 20, 3 );
478 l->addWidget( a3DBiQuad, 20, 4 );
479 l->addWidget( a3DTetLab, 21, 0 );
480 l->addWidget( a3DTetTotal, 21, 1 );
481 l->addWidget( a3DTetLin, 21, 2 );
482 l->addWidget( a3DTetQuad, 21, 3 );
483 l->addWidget( a3DHexLab, 22, 0 );
484 l->addWidget( a3DHexTotal, 22, 1 );
485 l->addWidget( a3DHexLin, 22, 2 );
486 l->addWidget( a3DHexQuad, 22, 3 );
487 l->addWidget( a3DHexBiQuad, 22, 4 );
488 l->addWidget( a3DPyrLab, 23, 0 );
489 l->addWidget( a3DPyrTotal, 23, 1 );
490 l->addWidget( a3DPyrLin, 23, 2 );
491 l->addWidget( a3DPyrQuad, 23, 3 );
492 l->addWidget( a3DPriLab, 24, 0 );
493 l->addWidget( a3DPriTotal, 24, 1 );
494 l->addWidget( a3DPriLin, 24, 2 );
495 l->addWidget( a3DPriQuad, 24, 3 );
496 l->addWidget( a3DPriBiQuad, 24, 4 );
497 l->addWidget( a3DHexPriLab, 25, 0 );
498 l->addWidget( a3DHexPriTotal, 25, 1 );
499 l->addWidget( a3DPolLab, 26, 0 );
500 l->addWidget( a3DPolTotal, 26, 1 );
501 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
503 l->setColumnStretch( 0, 0 );
504 l->setColumnStretch( 1, 5 );
505 l->setColumnStretch( 2, 5 );
506 l->setColumnStretch( 3, 5 );
507 l->setColumnStretch( 4, 5 );
508 l->setRowStretch( 27, 5 );
516 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
521 \brief Show information on the mesh object.
522 \param obj object being processed (mesh, sub-mesh, group, ID source)
524 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
527 if ( !CORBA::is_nil( obj )) {
528 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
530 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
531 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
532 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
533 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
534 if ( !aMesh->_is_nil() ) {
535 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ));
537 else if ( !aSubMesh->_is_nil() ) {
538 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ));
540 else if ( !aGroup->_is_nil() ) {
542 switch( aGroup->GetType() ) {
543 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
544 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
545 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
546 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
547 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
548 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
549 default: objType = tr( "OBJECT_GROUP" );break;
551 myWidgets[iObject][iSingle]->setProperty( "text", objType );
553 SMESH::long_array_var info = obj->GetMeshInfo();
554 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ));
555 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ));
556 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ));
557 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
558 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ));
559 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ));
560 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ));
561 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
562 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
563 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
564 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
565 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
566 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
567 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
569 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
570 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ));
571 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ));
572 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ));
573 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ));
574 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ));
575 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ));
576 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ));
577 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ));
578 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ));
579 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ));
580 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ));
581 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
582 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ));
583 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ));
584 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
585 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
586 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
587 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta];
588 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
589 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
590 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta];
591 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
592 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ));
593 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ));
594 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ));
595 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ));
596 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ));
597 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ));
598 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ));
599 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ));
600 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ));
601 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ));
602 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ));
603 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ));
604 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ));
605 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ));
606 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ));
607 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ));
608 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ));
609 myWidgets[i3DPrisms][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] ));
610 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ));
611 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ));
612 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
613 long nbElemLinearial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
614 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
615 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
616 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ));
617 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinearial ));
618 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ));
619 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ));
620 // before full loading from study file, type of elements in a sub-mesh can't be defined
622 bool infoOK = obj->IsMeshInfoCorrect();
623 myLoadBtn->setVisible( !infoOK );
627 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
628 // 2. No info at all (for a group on geom or filter)
629 bool hasAnyInfo = false;
630 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
631 hasAnyInfo = info[i];
632 if ( hasAnyInfo ) // believe it is a sub-mesh
634 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
636 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
637 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
638 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
640 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
643 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
644 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
645 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
646 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
647 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
648 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
649 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
650 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
651 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
652 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
653 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
655 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
657 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
661 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
662 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
667 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
668 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
669 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
670 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
671 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
672 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
673 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
674 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
675 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
676 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
677 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
678 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
683 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
684 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
685 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
686 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
687 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
688 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
690 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
691 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
692 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
694 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
695 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
696 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
697 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
698 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
699 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
700 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
703 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
704 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
706 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
707 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
712 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
713 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
714 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
715 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
716 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
717 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
718 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
719 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
720 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
721 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
722 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
723 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
730 \brief Load mesh from a study file
732 void SMESHGUI_MeshInfo::loadMesh()
734 SUIT_OverrideCursor wc;
736 SALOME_ListIO selected;
737 SMESHGUI::selectionMgr()->selectedObjects( selected );
739 if ( selected.Extent() == 1 ) {
740 Handle(SALOME_InteractiveObject) IO = selected.First();
741 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
742 if ( !CORBA::is_nil( obj )) {
743 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
744 if ( !mesh->_is_nil() )
754 \brief Reset the widget to the initial state (nullify all fields).
756 void SMESHGUI_MeshInfo::clear()
758 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
759 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
760 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ));
761 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ));
762 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ));
763 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ));
764 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ));
765 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
766 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ));
767 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ));
768 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
769 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
770 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ));
771 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ));
772 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
773 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
774 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ));
775 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ));
776 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
777 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
778 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ));
779 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
780 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ));
781 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ));
782 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ));
783 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
784 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
785 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
786 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
787 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
788 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
789 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
790 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
791 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
792 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ));
793 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ));
794 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ));
795 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
796 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ));
797 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ));
798 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
799 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
800 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ));
801 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ));
802 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ));
803 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
807 \brief Create info field
808 \return new info field
810 QLabel* SMESHGUI_MeshInfo::createField()
812 QLabel* lab = new QLabel( this );
813 lab->setFrameStyle( StyledPanel | Sunken );
814 lab->setAlignment( Qt::AlignCenter );
815 lab->setAutoFillBackground( true );
816 QPalette pal = lab->palette();
817 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
818 lab->setPalette( pal );
819 lab->setMinimumWidth( 70 );
824 \brief Create horizontal rule.
825 \return new line object
827 QWidget* SMESHGUI_MeshInfo::createLine()
829 QFrame* line = new QFrame( this );
830 line->setFrameStyle( HLine | Sunken );
835 \brief Change widget font attributes (bold, italic, ...).
837 \param attr font attributes (XORed flags)
838 \param val value to be set to attributes
840 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
844 if ( attr & Bold ) f.setBold( val );
845 if ( attr & Italic ) f.setItalic( val );
851 \brief Show/hide group(s) of fields.
852 \param start beginning of the block
853 \param end end of the block
854 \param on visibility flag
856 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
858 start = qMax( 0, start );
859 end = qMin( end, (int)iElementsEnd );
860 for ( int i = start; i < end; i++ ) {
861 wlist wl = myWidgets[i];
862 foreach ( QWidget* w, wl ) w->setVisible( on );
866 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
868 out << QString( 9, '-' ) << "\n";
869 out << tr( "BASE_INFO" ) << "\n";
870 out << QString( 9, '-' ) << "\n";
871 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" )).toString() << "\n";
872 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" )).toString() << "\n";
873 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" )).toString() << "\n";
874 out << tr( "ELEMENTS_LAB" ) << "\n";
875 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" )).toString() << "\n";
876 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" )).toString() << "\n";
877 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" )).toString() << "\n";
878 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" )).toString() << "\n";
879 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
880 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" )).toString() << "\n";
881 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" )).toString() << "\n";
883 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" )).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" )).toString() << "\n";
886 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" )).toString() << "\n";
887 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
888 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" )).toString() << "\n";
889 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" )).toString() << "\n";
890 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" )).toString() << "\n";
891 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" )).toString() << "\n";
892 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" )).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" )).toString() << "\n";
895 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" )).toString() << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" )).toString() << "\n";
897 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" )).toString() << "\n";
899 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" )).toString() << "\n";
900 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" )).toString() << "\n";
901 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" )).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
903 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" )).toString() << "\n";
904 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" )).toString() << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" )).toString() << "\n";
906 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
907 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" )).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" )).toString() << "\n";
909 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" )).toString() << "\n";
910 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" )).toString() << "\n";
911 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" )).toString() << "\n";
913 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" )).toString() << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" )).toString() << "\n";
915 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" )).toString() << "\n";
917 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" )).toString() << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" )).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" )).toString() << "\n";
920 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
921 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" )).toString() << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" )).toString() << "\n";
923 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" )).toString() << "\n";
924 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
925 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" )).toString() << "\n";
926 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" )).toString() << "\n";
927 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" )).toString() << "\n";
928 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
929 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" )).toString() << "\n";
930 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
931 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" )).toString() << "\n" << "\n";
935 \class SMESHGUI_ElemInfo
936 \brief Base class for the mesh element information widget.
941 \param parent parent widget
943 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
944 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
946 myFrame = new QWidget( this );
947 myExtra = new ExtraWidget( this );
948 QVBoxLayout* vbl = new QVBoxLayout( this );
950 vbl->setSpacing( 0 );
951 vbl->addWidget( myFrame );
952 vbl->addWidget( myExtra );
953 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ));
954 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ));
961 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
966 \brief Set mesh data source (actor)
967 \param actor mesh object actor
969 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor, SMESH::SMESH_IDSource_var obj )
971 if ( myActor != actor ) {
974 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
975 myMeshHasShape = ( !mesh->_is_nil() && mesh->HasShapeToMesh() );
981 \brief Show mesh element information
982 \param id mesh node / element ID
983 \param isElem show mesh element information if \c true or mesh node information if \c false
985 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
989 showInfo( ids, isElem );
993 \brief Show mesh element information
994 \param ids mesh nodes / elements identifiers
995 \param isElem show mesh element information if \c true or mesh node information if \c false
997 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
999 QList<long> newIds = ids.toList();
1001 if ( myIDs == newIds && myIsElement == isElem ) return;
1004 myIsElement = isElem;
1007 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1011 \brief Clear mesh element information widget
1013 void SMESHGUI_ElemInfo::clear()
1022 \brief Get central area widget
1023 \return central widget
1025 QWidget* SMESHGUI_ElemInfo::frame() const
1032 \return actor being used
1034 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1040 \brief Get current info mode.
1041 \return \c true if mesh element information is shown or \c false if node information is shown
1043 bool SMESHGUI_ElemInfo::isElements() const
1049 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1050 \brief Show information on the specified nodes / elements
1052 This function is to be redefined in sub-classes.
1054 \param ids nodes / elements identifiers information is to be shown on
1058 \brief Internal clean-up (reset widget)
1060 void SMESHGUI_ElemInfo::clearInternal()
1065 \brief Get node connectivity
1066 \param node mesh node
1067 \return node connectivity map
1069 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1073 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1074 while ( it && it->more() ) {
1075 const SMDS_MeshElement* ne = it->next();
1076 elmap[ ne->GetType() ] << ne->GetID();
1083 \brief Format connectivity data to string representation
1084 \param connectivity connetivity map
1085 \param type element type
1086 \return string representation of the connectivity
1088 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1091 if ( connectivity.contains( type )) {
1092 QList<int> elements = connectivity[ type ];
1094 foreach( int id, elements )
1095 str << QString::number( id );
1097 return str.join( " " );
1101 \brief Calculate gravity center of the mesh element
1102 \param element mesh element
1104 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1108 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1109 while ( nodeIt->more() ) {
1110 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1111 xyz.add( node->X(), node->Y(), node->Z() );
1113 xyz.divide( element->NbNodes() );
1119 \brief Calculate normal vector to the mesh face
1120 \param element mesh face
1122 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1124 gp_XYZ n = SMESH::getNormale( SMDS_Mesh::DownCast<SMDS_MeshFace>( element ));
1125 return XYZ(n.X(), n.Y(), n.Z());
1129 \brief This slot is called from "Show Previous" button click.
1130 Shows information on the previous group of the items.
1132 void SMESHGUI_ElemInfo::showPrevious()
1134 myIndex = qMax( 0, myIndex-1 );
1136 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1140 \brief This slot is called from "Show Next" button click.
1141 Shows information on the next group of the items.
1143 void SMESHGUI_ElemInfo::showNext()
1145 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1147 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1151 \brief Update widgets state
1153 void SMESHGUI_ElemInfo::updateControls()
1155 myExtra->updateControls( myIDs.count(), myIndex );
1159 \class SMESHGUI_SimpleElemInfo
1160 \brief Represents mesh element information in the simple text area.
1165 \param parent parent widget
1167 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1168 : SMESHGUI_ElemInfo( parent )
1170 myInfo = new QTextBrowser( frame() );
1171 QVBoxLayout* l = new QVBoxLayout( frame() );
1173 l->addWidget( myInfo );
1177 \brief Show mesh element information
1178 \param ids mesh nodes / elements identifiers
1180 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1185 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1186 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1187 int cprecision = -1;
1188 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1189 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1190 foreach ( long id, ids ) {
1191 if ( !isElements() ) {
1195 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1196 if ( !node ) return;
1199 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id ));
1201 myInfo->append( "" );
1203 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1204 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1205 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1206 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1208 myInfo->append( "" );
1210 Connectivity connectivity = nodeConnectivity( node );
1211 if ( !connectivity.isEmpty() ) {
1212 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1213 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1214 if ( !con.isEmpty() )
1215 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1216 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1217 if ( !con.isEmpty() )
1218 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1219 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1220 if ( !con.isEmpty() )
1221 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con ));
1222 con = formatConnectivity( connectivity, SMDSAbs_Face );
1223 if ( !con.isEmpty() )
1224 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1225 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1226 if ( !con.isEmpty() )
1227 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1230 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1233 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1234 if ( !CORBA::is_nil( aMeshPtr )) {
1235 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1236 int shapeID = pos->shapeID;
1237 if ( shapeID > 0 ) {
1239 double u = 0, v = 0;
1240 switch ( pos->shapeType ) {
1242 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1243 if ( pos->params.length() == 1 )
1247 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1248 if ( pos->params.length() == 2 ) {
1254 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1257 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1261 myInfo->append( "" );
1262 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) );
1263 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ));
1264 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1265 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )).
1266 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1267 if ( pos->shapeType == GEOM::FACE ) {
1268 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )).
1269 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1274 // groups node belongs to
1275 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1276 if ( !CORBA::is_nil( aMesh )) {
1277 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1278 myInfo->append( "" ); // separator
1279 bool top_created = false;
1280 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1281 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1282 if ( CORBA::is_nil( aGrp )) continue;
1283 QString aName = aGrp->GetName();
1284 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1285 if ( !top_created ) {
1286 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1289 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1290 if ( grp_details ) {
1291 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1292 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1293 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1295 // type : group on geometry, standalone group, group on filter
1296 if ( !CORBA::is_nil( aStdGroup )) {
1297 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1298 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1300 else if ( !CORBA::is_nil( aGeomGroup )) {
1301 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1302 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1303 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1304 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1306 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1307 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1310 else if ( !CORBA::is_nil( aFltGroup )) {
1311 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1312 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1316 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1317 arg( QString::number( aGrp->Size() )) );
1320 SALOMEDS::Color color = aGrp->GetColor();
1321 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1322 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1330 // show element info
1332 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1333 SMESH::Controls::NumericalFunctorPtr afunctor;
1336 // Element ID && Type
1338 switch( e->GetType() ) {
1339 case SMDSAbs_0DElement:
1340 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1342 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1344 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1346 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1347 case SMDSAbs_Volume:
1348 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1352 if ( stype.isEmpty() ) return;
1353 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ));
1355 myInfo->append( "" );
1359 switch( e->GetEntityType() ) {
1360 case SMDSEntity_Triangle:
1361 case SMDSEntity_Quad_Triangle:
1362 case SMDSEntity_BiQuad_Triangle:
1363 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1364 case SMDSEntity_Quadrangle:
1365 case SMDSEntity_Quad_Quadrangle:
1366 case SMDSEntity_BiQuad_Quadrangle:
1367 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1368 case SMDSEntity_Polygon:
1369 case SMDSEntity_Quad_Polygon:
1370 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1371 case SMDSEntity_Tetra:
1372 case SMDSEntity_Quad_Tetra:
1373 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1374 case SMDSEntity_Pyramid:
1375 case SMDSEntity_Quad_Pyramid:
1376 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1377 case SMDSEntity_Hexa:
1378 case SMDSEntity_Quad_Hexa:
1379 case SMDSEntity_TriQuad_Hexa:
1380 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1381 case SMDSEntity_Penta:
1382 case SMDSEntity_Quad_Penta:
1383 case SMDSEntity_BiQuad_Penta:
1384 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1385 case SMDSEntity_Hexagonal_Prism:
1386 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1387 case SMDSEntity_Polyhedra:
1388 case SMDSEntity_Quad_Polyhedra:
1389 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1393 if ( !gtype.isEmpty() )
1394 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype ));
1396 // Quadratic flag (any element except 0D)
1397 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1398 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) );
1400 if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast<SMDS_BallElement>( e )) {
1402 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() ));
1405 myInfo->append( "" );
1408 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1409 for ( int idx = 1; nodeIt->more(); idx++ ) {
1410 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1411 // node number and ID
1412 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ));
1414 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1415 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1416 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1417 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1418 // node connectivity
1419 Connectivity connectivity = nodeConnectivity( node );
1420 if ( !connectivity.isEmpty() ) {
1421 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1422 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1423 if ( !con.isEmpty() )
1424 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1425 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1426 if ( !con.isEmpty() )
1427 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1428 con = formatConnectivity( connectivity, SMDSAbs_Face );
1429 if ( !con.isEmpty() )
1430 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1431 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1432 if ( !con.isEmpty() )
1433 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1436 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1440 myInfo->append( "" );
1443 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) );
1445 if ( e->GetType() == SMDSAbs_Edge ) {
1446 afunctor.reset( new SMESH::Controls::Length() );
1447 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1448 afunctor->SetPrecision( cprecision );
1449 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) );
1451 if( e->GetType() == SMDSAbs_Face ) {
1453 afunctor.reset( new SMESH::Controls::Area() );
1454 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1455 afunctor->SetPrecision( cprecision );
1456 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1458 afunctor.reset( new SMESH::Controls::Taper() );
1459 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1460 afunctor->SetPrecision( cprecision );
1461 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1463 afunctor.reset( new SMESH::Controls::AspectRatio() );
1464 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1465 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1467 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1468 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1469 afunctor->SetPrecision( cprecision );
1470 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1472 afunctor.reset( new SMESH::Controls::Warping() );
1473 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1474 afunctor->SetPrecision( cprecision );
1475 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1477 afunctor.reset( new SMESH::Controls::Skew() );
1478 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1479 afunctor->SetPrecision( cprecision );
1480 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1482 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1483 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1484 afunctor->SetPrecision( cprecision );
1485 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) );
1487 afunctor.reset( new SMESH::Controls::Length2D() );
1488 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1489 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MIN_ELEM_EDGE" )).arg( afunctor->GetValue( id )) );
1491 if( e->GetType() == SMDSAbs_Volume ) {
1493 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1494 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1495 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1497 afunctor.reset( new SMESH::Controls::Volume() );
1498 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1499 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1501 afunctor.reset( new SMESH::Controls::Volume() );
1502 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1503 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) );
1506 myInfo->append( "" );
1509 XYZ gc = gravityCenter( e );
1510 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1513 if( e->GetType() == SMDSAbs_Face ) {
1514 XYZ gc = normal( e );
1515 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1519 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1520 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1521 if ( !CORBA::is_nil( aMesh )) {
1522 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1523 int shapeID = pos.shapeID;
1524 if ( shapeID > 0 ) {
1525 myInfo->append( "" ); // separator
1527 switch ( pos.shapeType ) {
1528 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1529 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1530 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1531 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1532 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1533 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1535 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID ));
1540 // Groups the element belongs to
1541 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1542 if ( !CORBA::is_nil( aMesh )) {
1543 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1544 myInfo->append( "" ); // separator
1545 bool top_created = false;
1546 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1547 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1548 if ( CORBA::is_nil( aGrp )) continue;
1549 QString aName = aGrp->GetName();
1550 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1551 if ( !top_created ) {
1552 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1555 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1556 if ( grp_details ) {
1557 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1558 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1559 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1561 // type : group on geometry, standalone group, group on filter
1562 if ( !CORBA::is_nil( aStdGroup )) {
1563 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1564 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1566 else if ( !CORBA::is_nil( aGeomGroup )) {
1567 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1568 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1569 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1570 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1572 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1573 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1576 else if ( !CORBA::is_nil( aFltGroup )) {
1577 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1578 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1581 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1582 arg( QString::number( aGrp->Size() )) );
1585 SALOMEDS::Color color = aGrp->GetColor();
1586 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1587 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1594 if ( ids.count() > 1 ) {
1595 myInfo->append( "" );
1596 myInfo->append( "------" );
1597 myInfo->append( "" );
1604 \brief Internal clean-up (reset widget)
1606 void SMESHGUI_SimpleElemInfo::clearInternal()
1611 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1613 out << QString( 12, '-' ) << "\n";
1614 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1615 out << QString( 12, '-' ) << "\n";
1616 out << myInfo->toPlainText();
1622 \class SMESHGUI_TreeElemInfo::ItemDelegate
1623 \brief Item delegate for tree mesh info widget
1626 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1629 ItemDelegate( QObject* );
1630 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1637 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1642 \brief Create item editor widget
1645 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1647 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1648 if ( qobject_cast<QLineEdit*>( w )) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1653 \class SMESHGUI_TreeElemInfo
1654 \brief Represents mesh element information in the tree-like form.
1659 \param parent parent widget
1661 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1662 : SMESHGUI_ElemInfo( parent )
1664 myInfo = new QTreeWidget( frame() );
1665 myInfo->setColumnCount( 2 );
1666 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ));
1667 myInfo->header()->setStretchLastSection( true );
1668 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1669 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1671 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1673 myInfo->setItemDelegate( new ItemDelegate( myInfo ));
1674 QVBoxLayout* l = new QVBoxLayout( frame() );
1676 l->addWidget( myInfo );
1677 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) );
1678 connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1679 connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1683 \brief Show mesh element information
1684 \param ids mesh nodes / elements identifiers
1686 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1691 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1692 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1693 int cprecision = -1;
1694 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1695 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1696 foreach ( long id, ids ) {
1697 if ( !isElements() ) {
1701 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1703 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1706 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1707 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ));
1708 nodeItem->setText( 1, QString( "#%1" ).arg( id ));
1710 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1711 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
1712 QTreeWidgetItem* xItem = createItem( coordItem );
1713 xItem->setText( 0, "X" );
1714 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1715 QTreeWidgetItem* yItem = createItem( coordItem );
1716 yItem->setText( 0, "Y" );
1717 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1718 QTreeWidgetItem* zItem = createItem( coordItem );
1719 zItem->setText( 0, "Z" );
1720 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1722 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1723 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1724 Connectivity connectivity = nodeConnectivity( node );
1725 if ( !connectivity.isEmpty() ) {
1726 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1727 if ( !con.isEmpty() ) {
1728 QTreeWidgetItem* i = createItem( conItem );
1729 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
1730 i->setText( 1, con );
1732 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1733 if ( !con.isEmpty() ) {
1734 QTreeWidgetItem* i = createItem( conItem );
1735 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
1736 i->setText( 1, con );
1737 i->setData( 1, TypeRole, NodeConnectivity );
1739 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1740 if ( !con.isEmpty() ) {
1741 QTreeWidgetItem* i = createItem( conItem );
1742 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
1743 i->setText( 1, con );
1744 i->setData( 1, TypeRole, NodeConnectivity );
1746 con = formatConnectivity( connectivity, SMDSAbs_Face );
1747 if ( !con.isEmpty() ) {
1748 QTreeWidgetItem* i = createItem( conItem );
1749 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
1750 i->setText( 1, con );
1751 i->setData( 1, TypeRole, NodeConnectivity );
1753 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1754 if ( !con.isEmpty() ) {
1755 QTreeWidgetItem* i = createItem( conItem );
1756 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
1757 i->setText( 1, con );
1758 i->setData( 1, TypeRole, NodeConnectivity );
1762 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ));
1765 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1766 if ( !CORBA::is_nil( aMeshPtr )) {
1767 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1768 int shapeID = pos->shapeID;
1769 if ( shapeID > 0 ) {
1771 double u = 0, v = 0;
1772 switch ( pos->shapeType ) {
1774 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1775 if ( pos->params.length() == 1 )
1779 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1780 if ( pos->params.length() == 2 ) {
1786 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1789 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1792 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1793 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1794 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1795 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1796 QTreeWidgetItem* uItem = createItem( posItem );
1797 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1798 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1799 if ( pos->shapeType == GEOM::FACE ) {
1800 QTreeWidgetItem* vItem = createItem( posItem );
1801 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1802 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1807 // groups node belongs to
1808 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1809 if ( !CORBA::is_nil( aMesh )) {
1810 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1811 QTreeWidgetItem* groupsItem = 0;
1812 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1813 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1814 if ( CORBA::is_nil( aGrp )) continue;
1815 QString aName = aGrp->GetName();
1816 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1817 if ( !groupsItem ) {
1818 groupsItem = createItem( nodeItem, Bold );
1819 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
1821 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1822 it->setText( 0, aName.trimmed() );
1823 if ( grp_details ) {
1824 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1825 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1826 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1828 // type : group on geometry, standalone group, group on filter
1829 QTreeWidgetItem* typeItem = createItem( it );
1830 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
1831 if ( !CORBA::is_nil( aStdGroup )) {
1832 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
1834 else if ( !CORBA::is_nil( aGeomGroup )) {
1835 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
1836 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1837 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1839 QTreeWidgetItem* gobjItem = createItem( typeItem );
1840 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
1841 gobjItem->setText( 1, sobj->GetName().c_str() );
1844 else if ( !CORBA::is_nil( aFltGroup )) {
1845 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
1849 QTreeWidgetItem* sizeItem = createItem( it );
1850 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
1851 sizeItem->setText( 1, QString::number( aGrp->Size() ));
1854 SALOMEDS::Color color = aGrp->GetColor();
1855 QTreeWidgetItem* colorItem = createItem( it );
1856 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
1857 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
1865 // show element info
1867 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1868 SMESH::Controls::NumericalFunctorPtr afunctor;
1871 // element ID && type
1873 switch( e->GetType() ) {
1874 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1875 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1876 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1877 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1878 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1881 if ( stype.isEmpty() ) return;
1882 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1883 elemItem->setText( 0, stype );
1884 elemItem->setText( 1, QString( "#%1" ).arg( id ));
1887 switch( e->GetEntityType() ) {
1888 case SMDSEntity_Triangle:
1889 case SMDSEntity_Quad_Triangle:
1890 case SMDSEntity_BiQuad_Triangle:
1891 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1892 case SMDSEntity_Quadrangle:
1893 case SMDSEntity_Quad_Quadrangle:
1894 case SMDSEntity_BiQuad_Quadrangle:
1895 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1896 case SMDSEntity_Polygon:
1897 case SMDSEntity_Quad_Polygon:
1898 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1899 case SMDSEntity_Tetra:
1900 case SMDSEntity_Quad_Tetra:
1901 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1902 case SMDSEntity_Pyramid:
1903 case SMDSEntity_Quad_Pyramid:
1904 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1905 case SMDSEntity_Hexa:
1906 case SMDSEntity_Quad_Hexa:
1907 case SMDSEntity_TriQuad_Hexa:
1908 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1909 case SMDSEntity_Penta:
1910 case SMDSEntity_Quad_Penta:
1911 case SMDSEntity_BiQuad_Penta:
1912 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1913 case SMDSEntity_Hexagonal_Prism:
1914 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1915 case SMDSEntity_Polyhedra:
1916 case SMDSEntity_Quad_Polyhedra:
1917 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1921 if ( !gtype.isEmpty() ) {
1922 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1923 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ));
1924 typeItem->setText( 1, gtype );
1926 // quadratic flag (for edges, faces and volumes)
1927 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1929 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1930 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ));
1931 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ));
1933 if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast< SMDS_BallElement >( e )) {
1935 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1936 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ));
1937 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1940 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1941 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1944 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1945 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1946 for ( int idx = 1; nodeIt->more(); idx++ ) {
1947 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1948 nodeInfo( node, idx, e->NbNodes(), conItem );
1952 SMDS_NodeIteratorPtr nodeIt = e->nodeIterator();
1953 std::set< const SMDS_MeshNode* > addedNodes;
1954 QList<const SMDS_MeshElement*> uniqueNodes;
1955 while ( nodeIt->more() ) {
1956 const SMDS_MeshNode* node = nodeIt->next();
1957 if ( addedNodes.insert( node ).second )
1958 uniqueNodes.append( nodeIt->next() );
1960 SMDS_VolumeTool vtool( e );
1961 const int nbFaces = vtool.NbFaces();
1962 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1963 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1964 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces ));
1965 faceItem->setExpanded( true );
1967 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1968 const int nbNodes = vtool.NbFaceNodes ( face_id );
1969 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1970 const SMDS_MeshNode* node = aNodeIds[node_id];
1971 nodeInfo( node, uniqueNodes.indexOf(node) + 1, uniqueNodes.size(), faceItem );
1976 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1977 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ));
1979 if( e->GetType()==SMDSAbs_Edge){
1980 afunctor.reset( new SMESH::Controls::Length() );
1981 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1982 afunctor->SetPrecision( cprecision );
1983 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1984 lenItem->setText( 0, tr( "LENGTH_EDGES" ));
1985 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1987 if( e->GetType() == SMDSAbs_Face ) {
1989 afunctor.reset( new SMESH::Controls::Area() );
1990 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1991 afunctor->SetPrecision( cprecision );
1992 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1993 areaItem->setText( 0, tr( "AREA_ELEMENTS" ));
1994 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ));
1996 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1998 afunctor.reset( new SMESH::Controls::Taper() );
1999 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2000 afunctor->SetPrecision( cprecision );
2001 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
2002 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ));
2003 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2005 afunctor.reset( new SMESH::Controls::Warping() );
2006 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2007 afunctor->SetPrecision( cprecision );
2008 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
2009 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
2010 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2015 afunctor.reset( new SMESH::Controls::AspectRatio() );
2016 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2017 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
2018 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2019 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2022 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2023 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2024 afunctor->SetPrecision( cprecision );
2025 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2026 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ));
2027 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2029 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2031 afunctor.reset( new SMESH::Controls::Skew() );
2032 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2033 afunctor->SetPrecision( cprecision );
2034 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2035 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ));
2036 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2039 if ( hasShapeToMesh() )
2041 afunctor.reset( new SMESH::Controls::Deflection2D() );
2042 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2043 QTreeWidgetItem* deflItem = createItem( cntrItem, Bold );
2044 deflItem->setText( 0, tr( "DEFLECTION_2D" ));
2045 deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2050 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2051 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2052 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2053 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2054 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2057 if( e->GetType() == SMDSAbs_Volume ) {
2061 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2062 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2063 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2064 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ));
2065 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2068 afunctor.reset( new SMESH::Controls::Volume() );
2069 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2070 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2071 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ));
2072 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2074 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2075 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2076 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2077 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ));
2078 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2082 afunctor.reset( new SMESH::Controls::Length2D() );
2083 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2084 QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold );
2085 minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" ));
2086 SMESH::Controls::TSequenceOfXYZ points;
2087 afunctor->GetPoints( e, points ); // "non-standard" way, to make it work for all elem types
2088 minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( points )) );
2091 XYZ gc = gravityCenter( e );
2092 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2093 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ));
2094 QTreeWidgetItem* xItem = createItem( gcItem );
2095 xItem->setText( 0, "X" );
2096 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2097 QTreeWidgetItem* yItem = createItem( gcItem );
2098 yItem->setText( 0, "Y" );
2099 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2100 QTreeWidgetItem* zItem = createItem( gcItem );
2101 zItem->setText( 0, "Z" );
2102 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2105 if( e->GetType() == SMDSAbs_Face ) {
2106 XYZ gc = normal( e );
2107 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2108 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ));
2109 QTreeWidgetItem* xItem = createItem( nItem );
2110 xItem->setText( 0, "X" );
2111 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2112 QTreeWidgetItem* yItem = createItem( nItem );
2113 yItem->setText( 0, "Y" );
2114 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2115 QTreeWidgetItem* zItem = createItem( nItem );
2116 zItem->setText( 0, "Z" );
2117 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2121 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2122 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2123 if ( !CORBA::is_nil( aMesh )) {
2124 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2125 int shapeID = pos.shapeID;
2126 if ( shapeID > 0 ) {
2127 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2129 switch ( pos.shapeType ) {
2130 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2131 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2132 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2133 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2134 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2135 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2137 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ));
2138 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ));
2142 // groups element belongs to
2143 if ( !CORBA::is_nil( aMesh )) {
2144 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2145 QTreeWidgetItem* groupsItem = 0;
2146 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2147 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2148 if ( CORBA::is_nil( aGrp )) continue;
2149 QString aName = aGrp->GetName();
2150 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
2151 if ( !groupsItem ) {
2152 groupsItem = createItem( elemItem, Bold );
2153 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
2155 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2156 it->setText( 0, aName.trimmed() );
2157 if ( grp_details ) {
2158 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2159 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2160 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2162 // type : group on geometry, standalone group, group on filter
2163 QTreeWidgetItem* typeItem = createItem( it );
2164 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
2165 if ( !CORBA::is_nil( aStdGroup )) {
2166 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
2168 else if ( !CORBA::is_nil( aGeomGroup )) {
2169 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
2170 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2171 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2173 QTreeWidgetItem* gobjItem = createItem( typeItem );
2174 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2175 gobjItem->setText( 1, sobj->GetName().c_str() );
2178 else if ( !CORBA::is_nil( aFltGroup )) {
2179 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2183 QTreeWidgetItem* sizeItem = createItem( it );
2184 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2185 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2188 SALOMEDS::Color color = aGrp->GetColor();
2189 QTreeWidgetItem* colorItem = createItem( it );
2190 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2191 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2202 \brief Show node information
2203 \param node mesh node for showing
2204 \param index index of current node
2205 \param nbNodes number of unique nodes in element
2206 \param parentItem parent item of tree
2208 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2209 int nbNodes, QTreeWidgetItem* parentItem )
2211 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2212 // node number and ID
2213 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2214 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2215 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2216 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2217 nodeItem->setData( 1, IdRole, node->GetID() );
2218 nodeItem->setExpanded( false );
2220 QTreeWidgetItem* coordItem = createItem( nodeItem );
2221 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2222 QTreeWidgetItem* xItem = createItem( coordItem );
2223 xItem->setText( 0, "X" );
2224 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2225 QTreeWidgetItem* yItem = createItem( coordItem );
2226 yItem->setText( 0, "Y" );
2227 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2228 QTreeWidgetItem* zItem = createItem( coordItem );
2229 zItem->setText( 0, "Z" );
2230 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2231 // node connectivity
2232 QTreeWidgetItem* nconItem = createItem( nodeItem );
2233 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2234 Connectivity connectivity = nodeConnectivity( node );
2235 if ( !connectivity.isEmpty() ) {
2236 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2237 if ( !con.isEmpty() ) {
2238 QTreeWidgetItem* i = createItem( nconItem );
2239 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2240 i->setText( 1, con );
2242 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2243 if ( !con.isEmpty() ) {
2244 QTreeWidgetItem* i = createItem( nconItem );
2245 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2246 i->setText( 1, con );
2247 i->setData( 1, TypeRole, NodeConnectivity );
2249 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2250 if ( !con.isEmpty() ) {
2251 QTreeWidgetItem* i = createItem( nconItem );
2252 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2253 i->setText( 1, con );
2254 i->setData( 1, TypeRole, NodeConnectivity );
2256 con = formatConnectivity( connectivity, SMDSAbs_Face );
2257 if ( !con.isEmpty() ) {
2258 QTreeWidgetItem* i = createItem( nconItem );
2259 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2260 i->setText( 1, con );
2261 i->setData( 1, TypeRole, NodeConnectivity );
2263 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2264 if ( !con.isEmpty() ) {
2265 QTreeWidgetItem* i = createItem( nconItem );
2266 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2267 i->setText( 1, con );
2268 i->setData( 1, TypeRole, NodeConnectivity );
2273 \brief Internal clean-up (reset widget)
2275 void SMESHGUI_TreeElemInfo::clearInternal()
2282 \brief Create new tree item.
2283 \param parent parent tree widget item
2284 \param flags item flag
2285 \return new tree widget item
2287 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2289 QTreeWidgetItem* item;
2291 item = new QTreeWidgetItem( parent );
2293 item = new QTreeWidgetItem( myInfo );
2295 item->setFlags( item->flags() | Qt::ItemIsEditable );
2297 QFont f = item->font( 0 );
2299 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2300 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2301 item->setFont( i, f );
2304 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2306 QString resName = expandedResource( parent );
2307 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2310 item->setExpanded( true );
2314 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2316 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2317 if ( widgets.isEmpty() ) return;
2318 QTreeWidgetItem* aTreeItem = widgets.first();
2319 int type = aTreeItem->data( 1, TypeRole ).toInt();
2320 int id = aTreeItem->data( 1, IdRole ).toInt();
2322 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2323 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2324 emit( itemInfo( id ));
2325 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2326 emit( itemInfo( aTreeItem->text( 1 )) );
2329 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2332 int type = theItem->data( 1, TypeRole ).toInt();
2333 int id = theItem->data( 1, IdRole ).toInt();
2334 if ( type == ElemConnectivity && id > 0 )
2335 emit( itemInfo( id ));
2336 else if ( type == NodeConnectivity )
2337 emit( itemInfo( theItem->text( 1 )) );
2341 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2344 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2347 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2349 return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0);
2352 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2354 out << QString( 12, '-' ) << "\n";
2355 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2356 out << QString( 12, '-' ) << "\n";
2358 QTreeWidgetItemIterator it( myInfo );
2360 if ( !( *it )->text(0).isEmpty() ) {
2361 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2362 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2372 \brief Mesh information computer
2375 The class is created for different computation operation. Currently it is used
2376 to compute number of underlying nodes for the groups.
2382 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2383 QTreeWidgetItem* item,
2386 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2388 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2392 \brief Compute function
2394 void GrpComputor::compute()
2396 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2397 SUIT_OverrideCursor wc;
2398 QTreeWidgetItem* item = myItem;
2400 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2401 item->treeWidget()->removeItemWidget( item, 1 );
2402 item->setText( 1, QString::number( nb ));
2407 \class SMESHGUI_AddInfo
2408 \brief The wigdet shows additional information on the mesh object.
2413 \param parent parent widget
2415 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2416 : QTreeWidget( parent )
2418 setColumnCount( 2 );
2419 header()->setStretchLastSection( true );
2420 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2421 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2423 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2431 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2436 \brief Show additional information on the selected object
2437 \param obj object being processed (mesh, sub-mesh, group, ID source)
2439 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2441 setProperty( "group_index", 0 );
2442 setProperty( "submesh_index", 0 );
2443 myComputors.clear();
2446 if ( CORBA::is_nil( obj )) return;
2448 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2449 if ( !sobj ) return;
2452 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2453 nameItem->setText( 0, tr( "NAME" ));
2454 nameItem->setText( 1, sobj->GetName().c_str() );
2456 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2457 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2458 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2460 if ( !aMesh->_is_nil() )
2461 meshInfo( aMesh, nameItem );
2462 else if ( !aSubMesh->_is_nil() )
2463 subMeshInfo( aSubMesh, nameItem );
2464 else if ( !aGroup->_is_nil() )
2465 groupInfo( aGroup.in(), nameItem );
2469 \brief Create new tree item.
2470 \param parent parent tree widget item
2471 \param flags item flag
2472 \return new tree widget item
2474 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2476 QTreeWidgetItem* item;
2479 item = new QTreeWidgetItem( parent );
2481 item = new QTreeWidgetItem( this );
2483 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2485 QFont f = item->font( 0 );
2487 for ( int i = 0; i < columnCount(); i++ ) {
2488 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2489 item->setFont( i, f );
2492 item->setExpanded( true );
2497 \brief Show mesh info
2498 \param mesh mesh object
2499 \param parent parent tree item
2501 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2504 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2505 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2506 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2507 typeItem->setText( 0, tr( "TYPE" ));
2508 if ( !CORBA::is_nil( shape )) {
2509 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ));
2510 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2512 QTreeWidgetItem* gobjItem = createItem( typeItem );
2513 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2514 gobjItem->setText( 1, sobj->GetName().c_str() );
2517 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2518 typeItem->setText( 1, tr( "MESH_FROM_FILE" ));
2519 QTreeWidgetItem* fileItem = createItem( typeItem );
2520 fileItem->setText( 0, tr( "FILE_NAME" ));
2521 fileItem->setText( 1, (char*)inf->fileName );
2524 typeItem->setText( 1, tr( "STANDALONE_MESH" ));
2528 myGroups = mesh->GetGroups();
2532 mySubMeshes = mesh->GetSubMeshes();
2537 \brief Show sub-mesh info
2538 \param subMesh sub-mesh object
2539 \param parent parent tree item
2541 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2543 bool isShort = parent->parent() != 0;
2547 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2549 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2550 nameItem->setText( 0, tr( "PARENT_MESH" ));
2551 nameItem->setText( 1, sobj->GetName().c_str() );
2556 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2557 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2559 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2560 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2561 gobjItem->setText( 1, sobj->GetName().c_str() );
2566 \brief Show group info
2567 \param grp mesh group object
2568 \param parent parent tree item
2570 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2572 bool isShort = parent->parent() != 0;
2574 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2575 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2576 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2580 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2582 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2583 nameItem->setText( 0, tr( "PARENT_MESH" ));
2584 nameItem->setText( 1, sobj->GetName().c_str() );
2588 // type : group on geometry, standalone group, group on filter
2589 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2590 typeItem->setText( 0, tr( "TYPE" ));
2591 if ( !CORBA::is_nil( aStdGroup )) {
2592 typeItem->setText( 1, tr( "STANDALONE_GROUP" ));
2594 else if ( !CORBA::is_nil( aGeomGroup )) {
2595 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ));
2596 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2597 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2599 QTreeWidgetItem* gobjItem = createItem( typeItem );
2600 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2601 gobjItem->setText( 1, sobj->GetName().c_str() );
2604 else if ( !CORBA::is_nil( aFltGroup )) {
2605 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ));
2610 QString etype = tr( "UNKNOWN" );
2611 switch( grp->GetType() ) {
2613 etype = tr( "NODE" );
2616 etype = tr( "EDGE" );
2619 etype = tr( "FACE" );
2622 etype = tr( "VOLUME" );
2625 etype = tr( "0DELEM" );
2628 etype = tr( "BALL" );
2633 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2634 etypeItem->setText( 0, tr( "ENTITY_TYPE" ));
2635 etypeItem->setText( 1, etype );
2638 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2639 bool meshLoaded = mesh->IsLoaded();
2641 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2643 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2644 groupSize = grp->Size();
2646 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2647 sizeItem->setText( 0, tr( "SIZE" ));
2648 if ( groupSize > -1 ) {
2649 sizeItem->setText( 1, QString::number( groupSize ));
2652 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2653 setItemWidget( sizeItem, 1, btn );
2654 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2655 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2656 myComputors.append( comp );
2658 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2662 SALOMEDS::Color color = grp->GetColor();
2663 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2664 colorItem->setText( 0, tr( "COLOR" ));
2665 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2667 // nb of underlying nodes
2668 if ( grp->GetType() != SMESH::NODE) {
2669 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2670 nodesItem->setText( 0, tr( "NB_NODES" ));
2671 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2672 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2673 if ( toShowNodes && meshLoaded ) {
2674 // already calculated and up-to-date
2675 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ));
2678 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2679 setItemWidget( nodesItem, 1, btn );
2680 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2681 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2682 myComputors.append( comp );
2684 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2689 void SMESHGUI_AddInfo::showGroups()
2691 myComputors.clear();
2693 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2694 if ( !parent ) return;
2696 int idx = property( "group_index" ).toInt();
2698 QTreeWidgetItem* itemGroups = 0;
2699 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2700 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2701 itemGroups = parent->child( i );
2702 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ));
2704 extra->updateControls( myGroups->length(), idx );
2705 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2709 QMap<int, QTreeWidgetItem*> grpItems;
2710 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2711 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2712 if ( CORBA::is_nil( grp )) continue;
2713 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2714 if ( !grpSObj ) continue;
2716 int grpType = grp->GetType();
2718 if ( !itemGroups ) {
2719 // create top-level groups container item
2720 itemGroups = createItem( parent, Bold | All );
2721 itemGroups->setText( 0, tr( "GROUPS" ));
2722 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2724 // total number of groups > 10, show extra widgets for info browsing
2725 if ((int) myGroups->length() > MAXITEMS ) {
2726 ExtraWidget* extra = new ExtraWidget( this, true );
2727 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ));
2728 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ));
2729 setItemWidget( itemGroups, 1, extra );
2730 extra->updateControls( myGroups->length(), idx );
2734 if ( grpItems.find( grpType ) == grpItems.end() ) {
2735 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2736 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ));
2737 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2741 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2742 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2745 groupInfo( grp.in(), grpNameItem );
2749 void SMESHGUI_AddInfo::showSubMeshes()
2751 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2752 if ( !parent ) return;
2754 int idx = property( "submesh_index" ).toInt();
2756 QTreeWidgetItem* itemSubMeshes = 0;
2757 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2758 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2759 itemSubMeshes = parent->child( i );
2760 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ));
2762 extra->updateControls( mySubMeshes->length(), idx );
2763 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2767 QMap<int, QTreeWidgetItem*> smItems;
2768 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2769 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2770 if ( CORBA::is_nil( sm )) continue;
2771 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2772 if ( !smSObj ) continue;
2774 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2775 if ( CORBA::is_nil(gobj )) continue;
2777 int smType = gobj->GetShapeType();
2778 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2780 if ( !itemSubMeshes ) {
2781 itemSubMeshes = createItem( parent, Bold | All );
2782 itemSubMeshes->setText( 0, tr( "SUBMESHES" ));
2783 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2785 // total number of sub-meshes > 10, show extra widgets for info browsing
2786 if ((int) mySubMeshes->length() > MAXITEMS ) {
2787 ExtraWidget* extra = new ExtraWidget( this, true );
2788 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ));
2789 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ));
2790 setItemWidget( itemSubMeshes, 1, extra );
2791 extra->updateControls( mySubMeshes->length(), idx );
2795 if ( smItems.find( smType ) == smItems.end() ) {
2796 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2797 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ));
2798 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2802 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2803 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2806 subMeshInfo( sm.in(), smNameItem );
2811 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2813 void SMESHGUI_AddInfo::changeLoadToCompute()
2815 for ( int i = 0; i < myComputors.count(); ++i )
2817 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2819 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 )) )
2820 btn->setText( tr("COMPUTE") );
2825 void SMESHGUI_AddInfo::showPreviousGroups()
2827 int idx = property( "group_index" ).toInt();
2828 setProperty( "group_index", idx-1 );
2832 void SMESHGUI_AddInfo::showNextGroups()
2834 int idx = property( "group_index" ).toInt();
2835 setProperty( "group_index", idx+1 );
2839 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2841 int idx = property( "submesh_index" ).toInt();
2842 setProperty( "submesh_index", idx-1 );
2846 void SMESHGUI_AddInfo::showNextSubMeshes()
2848 int idx = property( "submesh_index" ).toInt();
2849 setProperty( "submesh_index", idx+1 );
2853 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2855 out << QString( 15, '-') << "\n";
2856 out << tr( "ADDITIONAL_INFO" ) << "\n";
2857 out << QString( 15, '-' ) << "\n";
2858 QTreeWidgetItemIterator it( this );
2860 if ( !( ( *it )->text(0) ).isEmpty() ) {
2861 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2862 if ( ( *it )->text(0) == tr( "COLOR" )) {
2863 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2865 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2874 \class SMESHGUI_MeshInfoDlg
2875 \brief Mesh information dialog box
2880 \param parent parent widget
2881 \param page specifies the dialog page to be shown at the start-up
2883 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2884 : QDialog( parent ), myActor( 0 )
2887 setAttribute( Qt::WA_DeleteOnClose, true );
2888 setWindowTitle( tr( "MESH_INFO" ));
2889 setSizeGripEnabled( true );
2891 myTabWidget = new QTabWidget( this );
2895 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2896 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ));
2900 QWidget* w = new QWidget( myTabWidget );
2902 myMode = new QButtonGroup( this );
2903 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2904 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2905 myMode->button( NodeMode )->setChecked( true );
2906 myID = new QLineEdit( w );
2907 myID->setValidator( new SMESHGUI_IdValidator( this ));
2908 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
2909 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
2911 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2912 mode = qMin( 1, qMax( 0, mode ));
2915 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2917 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2919 QGridLayout* elemLayout = new QGridLayout( w );
2920 elemLayout->setMargin( MARGIN );
2921 elemLayout->setSpacing( SPACING );
2922 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2923 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2924 elemLayout->addWidget( myID, 0, 2 );
2925 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 );
2926 elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 );
2928 myTabWidget->addTab( w, tr( "ELEM_INFO" ));
2932 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2933 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ));
2937 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2938 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ));
2942 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2943 okBtn->setAutoDefault( true );
2944 okBtn->setDefault( true );
2946 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2947 dumpBtn->setAutoDefault( true );
2948 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2949 helpBtn->setAutoDefault( true );
2951 QHBoxLayout* btnLayout = new QHBoxLayout;
2952 btnLayout->setSpacing( SPACING );
2953 btnLayout->setMargin( 0 );
2955 btnLayout->addWidget( okBtn );
2956 btnLayout->addWidget( dumpBtn );
2957 btnLayout->addStretch( 10 );
2958 btnLayout->addWidget( helpBtn );
2960 QVBoxLayout* l = new QVBoxLayout ( this );
2961 l->setMargin( MARGIN );
2962 l->setSpacing( SPACING );
2963 l->addWidget( myTabWidget );
2964 l->addLayout( btnLayout );
2966 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page )));
2968 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
2969 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
2970 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
2971 connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() ));
2972 connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() ));
2973 connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() ));
2974 connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) ));
2975 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
2976 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
2977 connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int )));
2978 connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
2980 myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false ));
2988 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2994 \brief Show mesh information
2995 \param IO interactive object
2997 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3002 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
3003 if ( !CORBA::is_nil( obj ))
3005 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
3006 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
3007 if ( myTabWidget->currentIndex() == CtrlInfo )
3008 myCtrlInfo->showInfo( obj );
3011 myActor = SMESH::FindActorByEntry( IO->getEntry() );
3012 SVTK_Selector* selector = SMESH::GetSelector();
3015 if ( myActor && selector ) {
3016 nb = myMode->checkedId() == NodeMode ?
3017 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
3018 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
3020 myElemInfo->setSource( myActor, obj ) ;
3022 myID->setText( ID.trimmed() );
3024 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
3025 foreach ( ID, idTxt )
3026 ids << ID.trimmed().toLong();
3027 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3031 myElemInfo->clear();
3038 \brief Perform clean-up actions on the dialog box closing.
3040 void SMESHGUI_MeshInfoDlg::reject()
3042 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3043 selMgr->clearFilters();
3044 SMESH::SetPointRepresentation( false );
3045 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3046 aViewWindow->SetSelectionMode( ActorSelection );
3048 myIDPreview->SetPointsLabeled(false);
3052 \brief Process keyboard event
3053 \param e key press event
3055 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3057 QDialog::keyPressEvent( e );
3058 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3065 \brief Reactivate dialog box, when mouse pointer goes into it.
3067 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3073 \brief Setup selection mode depending on the current dialog box state.
3075 void SMESHGUI_MeshInfoDlg::updateSelection()
3077 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3079 disconnect( selMgr, 0, this, 0 );
3080 selMgr->clearFilters();
3082 if ( myTabWidget->currentIndex() == BaseInfo ||
3083 myTabWidget->currentIndex() == AddInfo ||
3084 myTabWidget->currentIndex() == CtrlInfo ) {
3085 SMESH::SetPointRepresentation( false );
3086 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3087 aViewWindow->SetSelectionMode( ActorSelection );
3090 if ( myMode->checkedId() == NodeMode ) {
3091 SMESH::SetPointRepresentation( true );
3092 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3093 aViewWindow->SetSelectionMode( NodeSelection );
3096 SMESH::SetPointRepresentation( false );
3097 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3098 aViewWindow->SetSelectionMode( CellSelection );
3102 QString oldID = myID->text().trimmed();
3103 SMESH_Actor* oldActor = myActor;
3106 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3109 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3110 myID->setText( oldID );
3116 \brief Show help page
3118 void SMESHGUI_MeshInfoDlg::help()
3120 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3121 "mesh_infos.html#advanced-mesh-infos-anchor" :
3122 "mesh_infos.html#mesh-element-info-anchor" );
3126 \brief Show mesh information
3128 void SMESHGUI_MeshInfoDlg::updateInfo()
3130 SUIT_OverrideCursor wc;
3132 SALOME_ListIO selected;
3133 SMESHGUI::selectionMgr()->selectedObjects( selected );
3135 if ( selected.Extent() == 1 ) {
3136 Handle(SALOME_InteractiveObject) IO = selected.First();
3145 \brief Activate dialog box
3147 void SMESHGUI_MeshInfoDlg::activate()
3149 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3150 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3151 myTabWidget->setEnabled( true );
3156 \brief Deactivate dialog box
3158 void SMESHGUI_MeshInfoDlg::deactivate()
3160 myTabWidget->setEnabled( false );
3161 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3165 \brief Called when users switches between node / element modes.
3167 void SMESHGUI_MeshInfoDlg::modeChanged()
3174 \brief Called when users prints mesh element ID in the corresponding field.
3176 void SMESHGUI_MeshInfoDlg::idChanged()
3178 myIDPreview->SetPointsLabeled( false );
3180 SVTK_Selector* selector = SMESH::GetSelector();
3181 if ( myActor && selector ) {
3182 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3183 TColStd_MapOfInteger ID;
3185 std::vector<int> idVec;
3186 std::list< gp_XYZ > aGrCentersXYZ;
3187 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3188 foreach ( QString tid, idTxt ) {
3189 long id = tid.trimmed().toLong();
3190 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3191 myActor->GetObject()->GetMesh()->FindElement( id ) :
3192 myActor->GetObject()->GetMesh()->FindNode( id );
3196 if ( myMode->checkedId() == ElemMode )
3198 idVec.push_back( id );
3199 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ));
3203 selector->AddOrRemoveIndex( IO, ID, false );
3204 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3206 if ( myMode->checkedId() == NodeMode )
3207 myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID );
3209 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3211 bool showIDs = ( !ID.IsEmpty() &&
3212 myIDPreviewCheck->isChecked() &&
3213 myTabWidget->currentIndex() == ElemInfo );
3214 myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() );
3216 aViewWindow->highlight( IO, true, true );
3217 aViewWindow->Repaint();
3219 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3224 * \brief Show IDs clicked
3226 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3228 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3229 SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn );
3230 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3231 aViewWindow->Repaint();
3234 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3236 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) {
3237 myMode->button( NodeMode )->click();
3238 myID->setText( QString::number( id ));
3242 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3244 if ( !theStr.isEmpty() ) {
3245 myMode->button( ElemMode )->click();
3246 myID->setText( theStr );
3250 void SMESHGUI_MeshInfoDlg::dump()
3252 QStringList aFilters;
3253 aFilters.append( tr( "TEXT_FILES" ));
3255 bool anIsBase = true;
3256 bool anIsElem = true;
3257 bool anIsAdd = true;
3258 bool anIsCtrl = true;
3260 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3261 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3262 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3263 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3264 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3267 DumpFileDlg fd( this );
3268 fd.setWindowTitle( tr( "SAVE_INFO" ));
3269 fd.setNameFilters( aFilters );
3270 fd.myBaseChk->setChecked( anIsBase );
3271 fd.myElemChk->setChecked( anIsElem );
3272 fd.myAddChk ->setChecked( anIsAdd );
3273 fd.myCtrlChk->setChecked( anIsCtrl );
3274 if ( fd.exec() == QDialog::Accepted )
3276 QString aFileName = fd.selectedFile();
3278 bool toBase = fd.myBaseChk->isChecked();
3279 bool toElem = fd.myElemChk->isChecked();
3280 bool toAdd = fd.myAddChk->isChecked();
3281 bool toCtrl = fd.myCtrlChk->isChecked();
3283 if ( !aFileName.isEmpty() ) {
3284 QFileInfo aFileInfo( aFileName );
3285 if ( aFileInfo.isDir() )
3288 QFile aFile( aFileName );
3289 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3292 QTextStream out( &aFile );
3294 if ( toBase ) myBaseInfo->saveInfo( out );
3295 if ( toElem ) myElemInfo->saveInfo( out );
3296 if ( toAdd ) myAddInfo ->saveInfo( out );
3297 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3303 \class SMESHGUI_CtrlInfo
3304 \brief Class for the mesh controls information widget.
3309 \param parent parent widget
3311 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3312 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3314 setFrameStyle( StyledPanel | Sunken );
3316 myMainLayout = new QGridLayout( this );
3317 myMainLayout->setMargin( MARGIN );
3318 myMainLayout->setSpacing( SPACING );
3321 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3322 QLabel* aName = createField();
3323 aName->setMinimumWidth( 150 );
3326 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3327 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) );
3329 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3332 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3333 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3334 QLabel* aNodesFree = createField();
3335 myWidgets << aNodesFree;
3336 myPredicates << aFilterMgr->CreateFreeNodes();
3338 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3339 QLabel* aNodesNbConn = createField();
3340 myWidgets << aNodesNbConn;
3341 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3343 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3344 QLabel* aNodesDouble = createField();
3345 myWidgets << aNodesDouble;
3346 myPredicates << aFilterMgr->CreateEqualNodes();
3347 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3348 myToleranceWidget = new SMESHGUI_SpinBox( this );
3349 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3350 myToleranceWidget->setAcceptNames( false );
3351 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ));
3354 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3355 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3356 QLabel* anEdgesDouble = createField();
3357 myWidgets << anEdgesDouble;
3358 myPredicates << aFilterMgr->CreateEqualEdges();
3361 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3362 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3363 QLabel* aFacesDouble = createField();
3364 myWidgets << aFacesDouble;
3365 myPredicates << aFilterMgr->CreateEqualFaces();
3366 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3367 QLabel* aFacesOver = createField();
3368 myWidgets << aFacesOver;
3369 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3370 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3371 myPlot = createPlot( this );
3372 myAspectRatio = aFilterMgr->CreateAspectRatio();
3375 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3376 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3377 QLabel* aVolumesDouble = createField();
3378 myWidgets << aVolumesDouble;
3379 myPredicates << aFilterMgr->CreateEqualVolumes();
3380 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3381 QLabel* aVolumesOver = createField();
3382 myWidgets << aVolumesOver;
3383 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3384 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3385 myPlot3D = createPlot( this );
3386 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3388 QToolButton* aFreeNodesBtn = new QToolButton( this );
3389 aFreeNodesBtn->setIcon(aComputeIcon);
3390 myButtons << aFreeNodesBtn; //0
3392 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3393 aNodesNbConnBtn->setIcon(aComputeIcon);
3394 myButtons << aNodesNbConnBtn; //1
3396 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3397 aDoubleNodesBtn->setIcon(aComputeIcon);
3398 myButtons << aDoubleNodesBtn; //2
3400 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3401 aDoubleEdgesBtn->setIcon(aComputeIcon);
3402 myButtons << aDoubleEdgesBtn; //3
3404 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3405 aDoubleFacesBtn->setIcon(aComputeIcon);
3406 myButtons << aDoubleFacesBtn; //4
3408 QToolButton* aOverContFacesBtn = new QToolButton( this );
3409 aOverContFacesBtn->setIcon(aComputeIcon);
3410 myButtons << aOverContFacesBtn; //5
3412 QToolButton* aComputeFaceBtn = new QToolButton( this );
3413 aComputeFaceBtn->setIcon(aComputeIcon);
3414 myButtons << aComputeFaceBtn; //6
3416 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3417 aDoubleVolumesBtn->setIcon(aComputeIcon);
3418 myButtons << aDoubleVolumesBtn; //7
3420 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3421 aOverContVolumesBtn->setIcon(aComputeIcon);
3422 myButtons << aOverContVolumesBtn; //8
3424 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3425 aComputeVolumeBtn->setIcon(aComputeIcon);
3426 myButtons << aComputeVolumeBtn; //9
3428 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ));
3429 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ));
3430 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ));
3431 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ));
3432 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ));
3433 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ));
3434 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ));
3435 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ));
3436 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ));
3437 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ));
3438 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3440 setFontAttributes( aNameLab );
3441 setFontAttributes( aNodesLab );
3442 setFontAttributes( anEdgesLab );
3443 setFontAttributes( aFacesLab );
3444 setFontAttributes( aVolumesLab );
3446 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3447 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3448 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3449 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3450 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3451 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3452 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3453 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3454 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3455 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3456 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3457 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3458 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3459 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3460 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3461 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3462 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3463 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3464 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3465 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3466 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3467 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3468 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3469 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3470 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3471 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3472 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3473 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3474 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3475 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3476 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3477 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3478 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3479 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3480 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3481 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3482 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3483 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3485 myMainLayout->setColumnStretch( 0, 0 );
3486 myMainLayout->setColumnStretch( 1, 5 );
3487 myMainLayout->setRowStretch ( 11, 5 );
3488 myMainLayout->setRowStretch ( 16, 5 );
3489 myMainLayout->setRowStretch ( 17, 1 );
3497 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3501 \brief Change widget font attributes (bold, ...).
3503 \param attr font attributes (XORed flags)
3505 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3508 QFont f = w->font();
3515 \brief Create info field
3516 \return new info field
3518 QLabel* SMESHGUI_CtrlInfo::createField()
3520 QLabel* lab = new QLabel( this );
3521 lab->setFrameStyle( StyledPanel | Sunken );
3522 lab->setAlignment( Qt::AlignCenter );
3523 lab->setAutoFillBackground( true );
3524 QPalette pal = lab->palette();
3525 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
3526 lab->setPalette( pal );
3527 lab->setMinimumWidth( 60 );
3532 \brief Create QwtPlot
3535 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3537 QwtPlot* aPlot = new QwtPlot( parent );
3538 aPlot->setMinimumSize( 100, 100 );
3539 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3540 xFont.setPointSize( 5 );
3541 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3542 yFont.setPointSize( 5 );
3543 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3544 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3550 \brief Show controls information on the selected object
3552 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3556 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3557 if ( myObject->_is_nil() ) return;
3559 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3560 myWidgets[0]->setText( aSO->GetName().c_str() );
3562 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3563 if ( mesh->_is_nil() ) return;
3565 const bool meshLoaded = mesh->IsLoaded();
3566 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3567 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3568 for ( int i = 0; i < myButtons.count(); ++i )
3569 myButtons[i]->setEnabled( true );
3571 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3572 if ( ! &nbElemsByType.in() ) return;
3574 const CORBA::Long ctrlLimit =
3575 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3578 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3579 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3580 nbElemsByType[ SMESH::FACE ] +
3581 nbElemsByType[ SMESH::VOLUME ] );
3582 if ( nbNodes + nbElems > 0 ) {
3583 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3585 computeFreeNodesInfo();
3586 computeNodesNbConnInfo();
3588 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3589 computeDoubleNodesInfo();
3592 myButtons[0]->setEnabled( true );
3593 myButtons[1]->setEnabled( true );
3594 myButtons[2]->setEnabled( true );
3598 for( int i=2; i<=11; i++)
3599 myMainLayout->itemAt(i)->widget()->setVisible( false );
3603 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3605 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3606 computeDoubleEdgesInfo();
3608 myButtons[3]->setEnabled( true );
3611 for( int i=11; i<=14; i++)
3612 myMainLayout->itemAt(i)->widget()->setVisible( false );
3616 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3617 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3619 computeDoubleFacesInfo();
3620 // over constrained faces
3621 computeOverConstrainedFacesInfo();
3622 // aspect Ratio histogram
3623 computeAspectRatio();
3626 myButtons[4]->setEnabled( true );
3627 myButtons[5]->setEnabled( true );
3628 myButtons[6]->setEnabled( true );
3630 #ifdef DISABLE_PLOT2DVIEWER
3631 myMainLayout->setRowStretch(12,0);
3632 for( int i=25; i<=27; i++)
3633 myMainLayout->itemAt(i)->widget()->setVisible( false );
3637 myMainLayout->setRowStretch(12,0);
3638 for( int i=18; i<=27; i++)
3639 myMainLayout->itemAt(i)->widget()->setVisible( false );
3643 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3644 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3646 computeDoubleVolumesInfo();
3647 // over constrained volumes
3648 computeOverConstrainedVolumesInfo();
3649 // aspect Ratio 3D histogram
3650 computeAspectRatio3D();
3653 myButtons[7]->setEnabled( true );
3654 myButtons[8]->setEnabled( true );
3655 myButtons[9]->setEnabled( true );
3657 #ifdef DISABLE_PLOT2DVIEWER
3658 myMainLayout->setRowStretch(17,0);
3659 for( int i=35; i<=37; i++)
3660 myMainLayout->itemAt(i)->widget()->setVisible( false );
3664 myMainLayout->setRowStretch(17,0);
3665 for( int i=28; i<=37; i++)
3666 myMainLayout->itemAt(i)->widget()->setVisible( false );
3670 //================================================================================
3672 * \brief Computes and shows nb of elements satisfying a given predicate
3673 * \param [in] ft - a predicate type (SMESH::FunctorType)
3674 * \param [in] iBut - index of one of myButtons to disable
3675 * \param [in] iWdg - index of one of myWidgets to show the computed number
3677 //================================================================================
3679 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3681 myButtons[ iBut ]->setEnabled( false );
3682 myWidgets[ iWdg ]->setText( "" );
3683 if ( myObject->_is_nil() ) return;
3685 SUIT_OverrideCursor wc;
3687 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3688 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3691 this->showInfo( myObject ); // try to show all values
3692 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3693 return; // <ft> predicate already computed
3695 // look for a predicate of type <ft>
3696 for ( int i = 0; i < myPredicates.count(); ++i )
3697 if ( myPredicates[i]->GetFunctorType() == ft )
3699 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3700 myWidgets[ iWdg ]->setText( QString::number( nb ));
3704 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3706 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3709 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3711 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3714 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3716 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3719 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3721 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3724 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3726 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3729 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3731 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3734 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3736 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3739 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3741 myButtons[ 1 ]->setEnabled( false );
3742 myWidgets[ 2 ]->setText( "" );
3743 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3744 if ( mesh->_is_nil() ) return;
3745 if ( !mesh->IsLoaded() )
3748 this->showInfo( myObject ); // try to show all values
3749 if ( !myWidgets[ 2 ]->text().isEmpty() )
3750 return; // already computed
3752 myNodeConnFunctor->SetMesh( mesh );
3753 SMESH::Histogram_var histogram =
3754 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3756 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3759 void SMESHGUI_CtrlInfo::computeAspectRatio()
3761 #ifndef DISABLE_PLOT2DVIEWER
3762 myButtons[6]->setEnabled( false );
3764 if ( myObject->_is_nil() ) return;
3766 SUIT_OverrideCursor wc;
3768 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3769 if ( aHistogram && !aHistogram->isEmpty() ) {
3770 QwtPlotItem* anItem = aHistogram->createPlotItem();
3771 anItem->attach( myPlot );
3778 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3780 #ifndef DISABLE_PLOT2DVIEWER
3781 myButtons[9]->setEnabled( false );
3783 if ( myObject->_is_nil() ) return;
3785 SUIT_OverrideCursor wc;
3787 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3788 if ( aHistogram && !aHistogram->isEmpty() ) {
3789 QwtPlotItem* anItem = aHistogram->createPlotItem();
3790 anItem->attach( myPlot3D );
3798 \brief Internal clean-up (reset widget)
3800 void SMESHGUI_CtrlInfo::clearInternal()
3802 for( int i=0; i<=35; i++)
3803 myMainLayout->itemAt(i)->widget()->setVisible( true );
3804 for( int i=0; i<=9; i++)
3805 myButtons[i]->setEnabled( false );
3806 myPlot->detachItems();
3807 myPlot3D->detachItems();
3810 myWidgets[0]->setText( QString() );
3811 for ( int i = 1; i < myWidgets.count(); i++ )
3812 myWidgets[i]->setText( "" );
3813 myMainLayout->setRowStretch(11,5);
3814 myMainLayout->setRowStretch(16,5);
3817 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3819 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3820 myButtons[1]->setEnabled( true );
3821 myWidgets[2]->setText("");
3824 #ifndef DISABLE_PLOT2DVIEWER
3825 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3827 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3828 if ( mesh->_is_nil() ) return 0;
3829 if ( !mesh->IsLoaded() )
3831 aNumFun->SetMesh( mesh );
3833 CORBA::Long cprecision = 6;
3834 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
3835 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3836 aNumFun->SetPrecision( cprecision );
3838 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3840 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3841 /*isLogarithmic=*/false,
3843 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3844 aHistogram->setColor( palette().color( QPalette::Highlight ));
3845 if ( &histogramVar.in() )
3847 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3848 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3849 if ( histogramVar->length() >= 2 )
3850 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3856 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3857 out << QString( 20, '-' ) << "\n";
3858 out << tr( "CTRL_INFO" ) << "\n";
3859 out << QString( 20, '-' ) << "\n";
3860 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3861 out << tr( "NODES_INFO" ) << "\n";
3862 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3863 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3864 out << tr( "EDGES_INFO" ) << "\n";
3865 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3866 out << tr( "FACES_INFO" ) << "\n";
3867 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3868 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3869 out << tr( "VOLUMES_INFO" ) << "\n";
3870 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3871 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3875 \class SMESHGUI_CtrlInfoDlg
3876 \brief Controls information dialog box
3881 \param parent parent widget
3883 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3886 setAttribute( Qt::WA_DeleteOnClose, true );
3887 setWindowTitle( tr( "CTRL_INFO" ));
3888 setMinimumSize( 400, 600 );
3890 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3893 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3894 okBtn->setAutoDefault( true );
3895 okBtn->setDefault( true );
3897 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3898 dumpBtn->setAutoDefault( true );
3899 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3900 helpBtn->setAutoDefault( true );
3902 QHBoxLayout* btnLayout = new QHBoxLayout;
3903 btnLayout->setSpacing( SPACING );
3904 btnLayout->setMargin( 0 );
3906 btnLayout->addWidget( okBtn );
3907 btnLayout->addWidget( dumpBtn );
3908 btnLayout->addStretch( 10 );
3909 btnLayout->addWidget( helpBtn );
3911 QVBoxLayout* l = new QVBoxLayout ( this );
3912 l->setMargin( MARGIN );
3913 l->setSpacing( SPACING );
3914 l->addWidget( myCtrlInfo );
3915 l->addLayout( btnLayout );
3917 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
3918 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
3919 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
3920 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
3921 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
3929 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3934 \brief Show controls information
3935 \param IO interactive object
3937 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3939 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ))
3940 myCtrlInfo->showInfo( obj );
3944 \brief Perform clean-up actions on the dialog box closing.
3946 void SMESHGUI_CtrlInfoDlg::reject()
3948 SMESH::SetPointRepresentation( false );
3953 \brief Setup selection mode depending on the current dialog box state.
3955 void SMESHGUI_CtrlInfoDlg::updateSelection()
3957 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3958 disconnect( selMgr, 0, this, 0 );
3959 SMESH::SetPointRepresentation( false );
3960 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3965 \brief Show mesh information
3967 void SMESHGUI_CtrlInfoDlg::updateInfo()
3969 SUIT_OverrideCursor wc;
3971 SALOME_ListIO selected;
3972 SMESHGUI::selectionMgr()->selectedObjects( selected );
3974 if ( selected.Extent() == 1 ) {
3975 Handle(SALOME_InteractiveObject) IO = selected.First();
3981 \brief Activate dialog box
3983 void SMESHGUI_CtrlInfoDlg::activate()
3985 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3986 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3991 \brief Deactivate dialog box
3993 void SMESHGUI_CtrlInfoDlg::deactivate()
3995 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3999 * \brief Dump contents into a file
4001 void SMESHGUI_CtrlInfoDlg::dump()
4003 QStringList aFilters;
4004 aFilters.append( tr( "TEXT_FILES" ));
4006 DumpFileDlg fd( this );
4007 fd.setWindowTitle( tr( "SAVE_INFO" ));
4008 fd.setNameFilters( aFilters );
4009 fd.myBaseChk->hide();
4010 fd.myElemChk->hide();
4011 fd.myAddChk ->hide();
4012 fd.myCtrlChk->hide();
4013 if ( fd.exec() == QDialog::Accepted )
4015 QString aFileName = fd.selectedFile();
4016 if ( !aFileName.isEmpty() ) {
4017 QFileInfo aFileInfo( aFileName );
4018 if ( aFileInfo.isDir() )
4021 QFile aFile( aFileName );
4022 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
4025 QTextStream out( &aFile );
4026 myCtrlInfo->saveInfo( out );
4034 void SMESHGUI_CtrlInfoDlg::help()
4036 SMESH::ShowHelpFile("mesh_infos.html#mesh_quality_info_anchor");