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 nbElemLinerial = 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( nbElemLinerial ));
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( dynamic_cast<const 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 = dynamic_cast<const 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 = dynamic_cast<const 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 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1953 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1954 QList<const SMDS_MeshElement*> uniqueNodes;
1955 while ( nodeIt->more() )
1956 uniqueNodes.append( nodeIt->next() );
1958 SMDS_VolumeTool vtool( e );
1959 const int nbFaces = vtool.NbFaces();
1960 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1961 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1962 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces ));
1963 faceItem->setExpanded( true );
1965 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1966 const int nbNodes = vtool.NbFaceNodes( face_id );
1967 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1968 const SMDS_MeshNode* node = aNodeIds[node_id];
1969 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1974 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1975 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ));
1977 if( e->GetType()==SMDSAbs_Edge){
1978 afunctor.reset( new SMESH::Controls::Length() );
1979 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1980 afunctor->SetPrecision( cprecision );
1981 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1982 lenItem->setText( 0, tr( "LENGTH_EDGES" ));
1983 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1985 if( e->GetType() == SMDSAbs_Face ) {
1987 afunctor.reset( new SMESH::Controls::Area() );
1988 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1989 afunctor->SetPrecision( cprecision );
1990 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1991 areaItem->setText( 0, tr( "AREA_ELEMENTS" ));
1992 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ));
1994 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1996 afunctor.reset( new SMESH::Controls::Taper() );
1997 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1998 afunctor->SetPrecision( cprecision );
1999 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
2000 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ));
2001 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2003 afunctor.reset( new SMESH::Controls::Warping() );
2004 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2005 afunctor->SetPrecision( cprecision );
2006 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
2007 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
2008 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2013 afunctor.reset( new SMESH::Controls::AspectRatio() );
2014 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2015 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
2016 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2017 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2020 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2021 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2022 afunctor->SetPrecision( cprecision );
2023 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2024 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ));
2025 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2027 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2029 afunctor.reset( new SMESH::Controls::Skew() );
2030 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2031 afunctor->SetPrecision( cprecision );
2032 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2033 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ));
2034 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2037 if ( hasShapeToMesh() )
2039 afunctor.reset( new SMESH::Controls::Deflection2D() );
2040 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2041 QTreeWidgetItem* deflItem = createItem( cntrItem, Bold );
2042 deflItem->setText( 0, tr( "DEFLECTION_2D" ));
2043 deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2048 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2049 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2050 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2051 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2052 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2055 if( e->GetType() == SMDSAbs_Volume ) {
2059 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2060 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2061 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2062 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ));
2063 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2066 afunctor.reset( new SMESH::Controls::Volume() );
2067 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2068 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2069 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ));
2070 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2072 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2073 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2074 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2075 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ));
2076 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2080 afunctor.reset( new SMESH::Controls::Length2D() );
2081 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2082 QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold );
2083 minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" ));
2084 minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2087 XYZ gc = gravityCenter( e );
2088 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2089 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ));
2090 QTreeWidgetItem* xItem = createItem( gcItem );
2091 xItem->setText( 0, "X" );
2092 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2093 QTreeWidgetItem* yItem = createItem( gcItem );
2094 yItem->setText( 0, "Y" );
2095 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2096 QTreeWidgetItem* zItem = createItem( gcItem );
2097 zItem->setText( 0, "Z" );
2098 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2101 if( e->GetType() == SMDSAbs_Face ) {
2102 XYZ gc = normal( e );
2103 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2104 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ));
2105 QTreeWidgetItem* xItem = createItem( nItem );
2106 xItem->setText( 0, "X" );
2107 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2108 QTreeWidgetItem* yItem = createItem( nItem );
2109 yItem->setText( 0, "Y" );
2110 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2111 QTreeWidgetItem* zItem = createItem( nItem );
2112 zItem->setText( 0, "Z" );
2113 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2117 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2118 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2119 if ( !CORBA::is_nil( aMesh )) {
2120 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2121 int shapeID = pos.shapeID;
2122 if ( shapeID > 0 ) {
2123 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2125 switch ( pos.shapeType ) {
2126 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2127 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2128 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2129 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2130 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2131 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2133 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ));
2134 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ));
2138 // groups element belongs to
2139 if ( !CORBA::is_nil( aMesh )) {
2140 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2141 QTreeWidgetItem* groupsItem = 0;
2142 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2143 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2144 if ( CORBA::is_nil( aGrp )) continue;
2145 QString aName = aGrp->GetName();
2146 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
2147 if ( !groupsItem ) {
2148 groupsItem = createItem( elemItem, Bold );
2149 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
2151 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2152 it->setText( 0, aName.trimmed() );
2153 if ( grp_details ) {
2154 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2155 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2156 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2158 // type : group on geometry, standalone group, group on filter
2159 QTreeWidgetItem* typeItem = createItem( it );
2160 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
2161 if ( !CORBA::is_nil( aStdGroup )) {
2162 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
2164 else if ( !CORBA::is_nil( aGeomGroup )) {
2165 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
2166 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2167 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2169 QTreeWidgetItem* gobjItem = createItem( typeItem );
2170 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2171 gobjItem->setText( 1, sobj->GetName().c_str() );
2174 else if ( !CORBA::is_nil( aFltGroup )) {
2175 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2179 QTreeWidgetItem* sizeItem = createItem( it );
2180 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2181 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2184 SALOMEDS::Color color = aGrp->GetColor();
2185 QTreeWidgetItem* colorItem = createItem( it );
2186 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2187 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2198 \brief Show node information
2199 \param node mesh node for showing
2200 \param index index of current node
2201 \param nbNodes number of unique nodes in element
2202 \param parentItem parent item of tree
2204 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2205 int nbNodes, QTreeWidgetItem* parentItem )
2207 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2208 // node number and ID
2209 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2210 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2211 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2212 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2213 nodeItem->setData( 1, IdRole, node->GetID() );
2214 nodeItem->setExpanded( false );
2216 QTreeWidgetItem* coordItem = createItem( nodeItem );
2217 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2218 QTreeWidgetItem* xItem = createItem( coordItem );
2219 xItem->setText( 0, "X" );
2220 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2221 QTreeWidgetItem* yItem = createItem( coordItem );
2222 yItem->setText( 0, "Y" );
2223 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2224 QTreeWidgetItem* zItem = createItem( coordItem );
2225 zItem->setText( 0, "Z" );
2226 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2227 // node connectivity
2228 QTreeWidgetItem* nconItem = createItem( nodeItem );
2229 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2230 Connectivity connectivity = nodeConnectivity( node );
2231 if ( !connectivity.isEmpty() ) {
2232 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2233 if ( !con.isEmpty() ) {
2234 QTreeWidgetItem* i = createItem( nconItem );
2235 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2236 i->setText( 1, con );
2238 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2239 if ( !con.isEmpty() ) {
2240 QTreeWidgetItem* i = createItem( nconItem );
2241 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2242 i->setText( 1, con );
2243 i->setData( 1, TypeRole, NodeConnectivity );
2245 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2246 if ( !con.isEmpty() ) {
2247 QTreeWidgetItem* i = createItem( nconItem );
2248 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2249 i->setText( 1, con );
2250 i->setData( 1, TypeRole, NodeConnectivity );
2252 con = formatConnectivity( connectivity, SMDSAbs_Face );
2253 if ( !con.isEmpty() ) {
2254 QTreeWidgetItem* i = createItem( nconItem );
2255 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2256 i->setText( 1, con );
2257 i->setData( 1, TypeRole, NodeConnectivity );
2259 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2260 if ( !con.isEmpty() ) {
2261 QTreeWidgetItem* i = createItem( nconItem );
2262 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2263 i->setText( 1, con );
2264 i->setData( 1, TypeRole, NodeConnectivity );
2269 \brief Internal clean-up (reset widget)
2271 void SMESHGUI_TreeElemInfo::clearInternal()
2278 \brief Create new tree item.
2279 \param parent parent tree widget item
2280 \param flags item flag
2281 \return new tree widget item
2283 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2285 QTreeWidgetItem* item;
2287 item = new QTreeWidgetItem( parent );
2289 item = new QTreeWidgetItem( myInfo );
2291 item->setFlags( item->flags() | Qt::ItemIsEditable );
2293 QFont f = item->font( 0 );
2295 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2296 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2297 item->setFont( i, f );
2300 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2302 QString resName = expandedResource( parent );
2303 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2306 item->setExpanded( true );
2310 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2312 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2313 if ( widgets.isEmpty() ) return;
2314 QTreeWidgetItem* aTreeItem = widgets.first();
2315 int type = aTreeItem->data( 1, TypeRole ).toInt();
2316 int id = aTreeItem->data( 1, IdRole ).toInt();
2318 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2319 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2320 emit( itemInfo( id ));
2321 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2322 emit( itemInfo( aTreeItem->text( 1 )) );
2325 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2328 int type = theItem->data( 1, TypeRole ).toInt();
2329 int id = theItem->data( 1, IdRole ).toInt();
2330 if ( type == ElemConnectivity && id > 0 )
2331 emit( itemInfo( id ));
2332 else if ( type == NodeConnectivity )
2333 emit( itemInfo( theItem->text( 1 )) );
2337 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2340 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2343 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2345 return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0);
2348 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2350 out << QString( 12, '-' ) << "\n";
2351 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2352 out << QString( 12, '-' ) << "\n";
2354 QTreeWidgetItemIterator it( myInfo );
2356 if ( !( *it )->text(0).isEmpty() ) {
2357 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2358 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2368 \brief Mesh information computer
2371 The class is created for different computation operation. Currently it is used
2372 to compute number of underlying nodes for the groups.
2378 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2379 QTreeWidgetItem* item,
2382 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2384 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2388 \brief Compute function
2390 void GrpComputor::compute()
2392 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2393 SUIT_OverrideCursor wc;
2394 QTreeWidgetItem* item = myItem;
2396 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2397 item->treeWidget()->removeItemWidget( item, 1 );
2398 item->setText( 1, QString::number( nb ));
2403 \class SMESHGUI_AddInfo
2404 \brief The wigdet shows additional information on the mesh object.
2409 \param parent parent widget
2411 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2412 : QTreeWidget( parent )
2414 setColumnCount( 2 );
2415 header()->setStretchLastSection( true );
2416 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2417 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2419 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2427 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2432 \brief Show additional information on the selected object
2433 \param obj object being processed (mesh, sub-mesh, group, ID source)
2435 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2437 setProperty( "group_index", 0 );
2438 setProperty( "submesh_index", 0 );
2439 myComputors.clear();
2442 if ( CORBA::is_nil( obj )) return;
2444 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2445 if ( !sobj ) return;
2448 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2449 nameItem->setText( 0, tr( "NAME" ));
2450 nameItem->setText( 1, sobj->GetName().c_str() );
2452 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2453 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2454 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2456 if ( !aMesh->_is_nil() )
2457 meshInfo( aMesh, nameItem );
2458 else if ( !aSubMesh->_is_nil() )
2459 subMeshInfo( aSubMesh, nameItem );
2460 else if ( !aGroup->_is_nil() )
2461 groupInfo( aGroup.in(), nameItem );
2465 \brief Create new tree item.
2466 \param parent parent tree widget item
2467 \param flags item flag
2468 \return new tree widget item
2470 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2472 QTreeWidgetItem* item;
2475 item = new QTreeWidgetItem( parent );
2477 item = new QTreeWidgetItem( this );
2479 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2481 QFont f = item->font( 0 );
2483 for ( int i = 0; i < columnCount(); i++ ) {
2484 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2485 item->setFont( i, f );
2488 item->setExpanded( true );
2493 \brief Show mesh info
2494 \param mesh mesh object
2495 \param parent parent tree item
2497 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2500 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2501 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2502 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2503 typeItem->setText( 0, tr( "TYPE" ));
2504 if ( !CORBA::is_nil( shape )) {
2505 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ));
2506 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2508 QTreeWidgetItem* gobjItem = createItem( typeItem );
2509 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2510 gobjItem->setText( 1, sobj->GetName().c_str() );
2513 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2514 typeItem->setText( 1, tr( "MESH_FROM_FILE" ));
2515 QTreeWidgetItem* fileItem = createItem( typeItem );
2516 fileItem->setText( 0, tr( "FILE_NAME" ));
2517 fileItem->setText( 1, (char*)inf->fileName );
2520 typeItem->setText( 1, tr( "STANDALONE_MESH" ));
2524 myGroups = mesh->GetGroups();
2528 mySubMeshes = mesh->GetSubMeshes();
2533 \brief Show sub-mesh info
2534 \param subMesh sub-mesh object
2535 \param parent parent tree item
2537 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2539 bool isShort = parent->parent() != 0;
2543 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2545 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2546 nameItem->setText( 0, tr( "PARENT_MESH" ));
2547 nameItem->setText( 1, sobj->GetName().c_str() );
2552 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2553 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2555 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2556 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2557 gobjItem->setText( 1, sobj->GetName().c_str() );
2562 \brief Show group info
2563 \param grp mesh group object
2564 \param parent parent tree item
2566 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2568 bool isShort = parent->parent() != 0;
2570 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2571 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2572 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2576 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2578 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2579 nameItem->setText( 0, tr( "PARENT_MESH" ));
2580 nameItem->setText( 1, sobj->GetName().c_str() );
2584 // type : group on geometry, standalone group, group on filter
2585 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2586 typeItem->setText( 0, tr( "TYPE" ));
2587 if ( !CORBA::is_nil( aStdGroup )) {
2588 typeItem->setText( 1, tr( "STANDALONE_GROUP" ));
2590 else if ( !CORBA::is_nil( aGeomGroup )) {
2591 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ));
2592 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2593 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2595 QTreeWidgetItem* gobjItem = createItem( typeItem );
2596 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2597 gobjItem->setText( 1, sobj->GetName().c_str() );
2600 else if ( !CORBA::is_nil( aFltGroup )) {
2601 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ));
2606 QString etype = tr( "UNKNOWN" );
2607 switch( grp->GetType() ) {
2609 etype = tr( "NODE" );
2612 etype = tr( "EDGE" );
2615 etype = tr( "FACE" );
2618 etype = tr( "VOLUME" );
2621 etype = tr( "0DELEM" );
2624 etype = tr( "BALL" );
2629 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2630 etypeItem->setText( 0, tr( "ENTITY_TYPE" ));
2631 etypeItem->setText( 1, etype );
2634 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2635 bool meshLoaded = mesh->IsLoaded();
2637 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2639 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2640 groupSize = grp->Size();
2642 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2643 sizeItem->setText( 0, tr( "SIZE" ));
2644 if ( groupSize > -1 ) {
2645 sizeItem->setText( 1, QString::number( groupSize ));
2648 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2649 setItemWidget( sizeItem, 1, btn );
2650 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2651 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2652 myComputors.append( comp );
2654 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2658 SALOMEDS::Color color = grp->GetColor();
2659 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2660 colorItem->setText( 0, tr( "COLOR" ));
2661 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2663 // nb of underlying nodes
2664 if ( grp->GetType() != SMESH::NODE) {
2665 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2666 nodesItem->setText( 0, tr( "NB_NODES" ));
2667 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2668 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2669 if ( toShowNodes && meshLoaded ) {
2670 // already calculated and up-to-date
2671 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ));
2674 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2675 setItemWidget( nodesItem, 1, btn );
2676 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2677 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2678 myComputors.append( comp );
2680 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2685 void SMESHGUI_AddInfo::showGroups()
2687 myComputors.clear();
2689 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2690 if ( !parent ) return;
2692 int idx = property( "group_index" ).toInt();
2694 QTreeWidgetItem* itemGroups = 0;
2695 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2696 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2697 itemGroups = parent->child( i );
2698 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ));
2700 extra->updateControls( myGroups->length(), idx );
2701 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2705 QMap<int, QTreeWidgetItem*> grpItems;
2706 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2707 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2708 if ( CORBA::is_nil( grp )) continue;
2709 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2710 if ( !grpSObj ) continue;
2712 int grpType = grp->GetType();
2714 if ( !itemGroups ) {
2715 // create top-level groups container item
2716 itemGroups = createItem( parent, Bold | All );
2717 itemGroups->setText( 0, tr( "GROUPS" ));
2718 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2720 // total number of groups > 10, show extra widgets for info browsing
2721 if ((int) myGroups->length() > MAXITEMS ) {
2722 ExtraWidget* extra = new ExtraWidget( this, true );
2723 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ));
2724 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ));
2725 setItemWidget( itemGroups, 1, extra );
2726 extra->updateControls( myGroups->length(), idx );
2730 if ( grpItems.find( grpType ) == grpItems.end() ) {
2731 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2732 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ));
2733 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2737 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2738 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2741 groupInfo( grp.in(), grpNameItem );
2745 void SMESHGUI_AddInfo::showSubMeshes()
2747 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2748 if ( !parent ) return;
2750 int idx = property( "submesh_index" ).toInt();
2752 QTreeWidgetItem* itemSubMeshes = 0;
2753 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2754 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2755 itemSubMeshes = parent->child( i );
2756 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ));
2758 extra->updateControls( mySubMeshes->length(), idx );
2759 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2763 QMap<int, QTreeWidgetItem*> smItems;
2764 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2765 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2766 if ( CORBA::is_nil( sm )) continue;
2767 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2768 if ( !smSObj ) continue;
2770 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2771 if ( CORBA::is_nil(gobj )) continue;
2773 int smType = gobj->GetShapeType();
2774 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2776 if ( !itemSubMeshes ) {
2777 itemSubMeshes = createItem( parent, Bold | All );
2778 itemSubMeshes->setText( 0, tr( "SUBMESHES" ));
2779 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2781 // total number of sub-meshes > 10, show extra widgets for info browsing
2782 if ((int) mySubMeshes->length() > MAXITEMS ) {
2783 ExtraWidget* extra = new ExtraWidget( this, true );
2784 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ));
2785 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ));
2786 setItemWidget( itemSubMeshes, 1, extra );
2787 extra->updateControls( mySubMeshes->length(), idx );
2791 if ( smItems.find( smType ) == smItems.end() ) {
2792 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2793 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ));
2794 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2798 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2799 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2802 subMeshInfo( sm.in(), smNameItem );
2807 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2809 void SMESHGUI_AddInfo::changeLoadToCompute()
2811 for ( int i = 0; i < myComputors.count(); ++i )
2813 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2815 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 )) )
2816 btn->setText( tr("COMPUTE") );
2821 void SMESHGUI_AddInfo::showPreviousGroups()
2823 int idx = property( "group_index" ).toInt();
2824 setProperty( "group_index", idx-1 );
2828 void SMESHGUI_AddInfo::showNextGroups()
2830 int idx = property( "group_index" ).toInt();
2831 setProperty( "group_index", idx+1 );
2835 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2837 int idx = property( "submesh_index" ).toInt();
2838 setProperty( "submesh_index", idx-1 );
2842 void SMESHGUI_AddInfo::showNextSubMeshes()
2844 int idx = property( "submesh_index" ).toInt();
2845 setProperty( "submesh_index", idx+1 );
2849 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2851 out << QString( 15, '-') << "\n";
2852 out << tr( "ADDITIONAL_INFO" ) << "\n";
2853 out << QString( 15, '-' ) << "\n";
2854 QTreeWidgetItemIterator it( this );
2856 if ( !( ( *it )->text(0) ).isEmpty() ) {
2857 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2858 if ( ( *it )->text(0) == tr( "COLOR" )) {
2859 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2861 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2870 \class SMESHGUI_MeshInfoDlg
2871 \brief Mesh information dialog box
2876 \param parent parent widget
2877 \param page specifies the dialog page to be shown at the start-up
2879 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2880 : QDialog( parent ), myActor( 0 )
2883 setAttribute( Qt::WA_DeleteOnClose, true );
2884 setWindowTitle( tr( "MESH_INFO" ));
2885 setSizeGripEnabled( true );
2887 myTabWidget = new QTabWidget( this );
2891 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2892 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ));
2896 QWidget* w = new QWidget( myTabWidget );
2898 myMode = new QButtonGroup( this );
2899 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2900 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2901 myMode->button( NodeMode )->setChecked( true );
2902 myID = new QLineEdit( w );
2903 myID->setValidator( new SMESHGUI_IdValidator( this ));
2904 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
2905 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
2907 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2908 mode = qMin( 1, qMax( 0, mode ));
2911 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2913 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2915 QGridLayout* elemLayout = new QGridLayout( w );
2916 elemLayout->setMargin( MARGIN );
2917 elemLayout->setSpacing( SPACING );
2918 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2919 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2920 elemLayout->addWidget( myID, 0, 2 );
2921 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 );
2922 elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 );
2924 myTabWidget->addTab( w, tr( "ELEM_INFO" ));
2928 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2929 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ));
2933 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2934 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ));
2938 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2939 okBtn->setAutoDefault( true );
2940 okBtn->setDefault( true );
2942 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2943 dumpBtn->setAutoDefault( true );
2944 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2945 helpBtn->setAutoDefault( true );
2947 QHBoxLayout* btnLayout = new QHBoxLayout;
2948 btnLayout->setSpacing( SPACING );
2949 btnLayout->setMargin( 0 );
2951 btnLayout->addWidget( okBtn );
2952 btnLayout->addWidget( dumpBtn );
2953 btnLayout->addStretch( 10 );
2954 btnLayout->addWidget( helpBtn );
2956 QVBoxLayout* l = new QVBoxLayout ( this );
2957 l->setMargin( MARGIN );
2958 l->setSpacing( SPACING );
2959 l->addWidget( myTabWidget );
2960 l->addLayout( btnLayout );
2962 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page )));
2964 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
2965 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
2966 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
2967 connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() ));
2968 connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() ));
2969 connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() ));
2970 connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) ));
2971 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
2972 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
2973 connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int )));
2974 connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
2976 myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false ));
2984 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2990 \brief Show mesh information
2991 \param IO interactive object
2993 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2998 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2999 if ( !CORBA::is_nil( obj ))
3001 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
3002 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
3003 if ( myTabWidget->currentIndex() == CtrlInfo )
3004 myCtrlInfo->showInfo( obj );
3007 myActor = SMESH::FindActorByEntry( IO->getEntry() );
3008 SVTK_Selector* selector = SMESH::GetSelector();
3011 if ( myActor && selector ) {
3012 nb = myMode->checkedId() == NodeMode ?
3013 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
3014 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
3016 myElemInfo->setSource( myActor, obj ) ;
3018 myID->setText( ID.trimmed() );
3020 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
3021 foreach ( ID, idTxt )
3022 ids << ID.trimmed().toLong();
3023 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3027 myElemInfo->clear();
3034 \brief Perform clean-up actions on the dialog box closing.
3036 void SMESHGUI_MeshInfoDlg::reject()
3038 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3039 selMgr->clearFilters();
3040 SMESH::SetPointRepresentation( false );
3041 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3042 aViewWindow->SetSelectionMode( ActorSelection );
3044 myIDPreview->SetPointsLabeled(false);
3048 \brief Process keyboard event
3049 \param e key press event
3051 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3053 QDialog::keyPressEvent( e );
3054 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3061 \brief Reactivate dialog box, when mouse pointer goes into it.
3063 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3069 \brief Setup selection mode depending on the current dialog box state.
3071 void SMESHGUI_MeshInfoDlg::updateSelection()
3073 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3075 disconnect( selMgr, 0, this, 0 );
3076 selMgr->clearFilters();
3078 if ( myTabWidget->currentIndex() == BaseInfo ||
3079 myTabWidget->currentIndex() == AddInfo ||
3080 myTabWidget->currentIndex() == CtrlInfo ) {
3081 SMESH::SetPointRepresentation( false );
3082 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3083 aViewWindow->SetSelectionMode( ActorSelection );
3086 if ( myMode->checkedId() == NodeMode ) {
3087 SMESH::SetPointRepresentation( true );
3088 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3089 aViewWindow->SetSelectionMode( NodeSelection );
3092 SMESH::SetPointRepresentation( false );
3093 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3094 aViewWindow->SetSelectionMode( CellSelection );
3098 QString oldID = myID->text().trimmed();
3099 SMESH_Actor* oldActor = myActor;
3102 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3105 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3106 myID->setText( oldID );
3112 \brief Show help page
3114 void SMESHGUI_MeshInfoDlg::help()
3116 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3117 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3118 "mesh_infos_page.html#mesh_element_info_anchor" );
3122 \brief Show mesh information
3124 void SMESHGUI_MeshInfoDlg::updateInfo()
3126 SUIT_OverrideCursor wc;
3128 SALOME_ListIO selected;
3129 SMESHGUI::selectionMgr()->selectedObjects( selected );
3131 if ( selected.Extent() == 1 ) {
3132 Handle(SALOME_InteractiveObject) IO = selected.First();
3141 \brief Activate dialog box
3143 void SMESHGUI_MeshInfoDlg::activate()
3145 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3146 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3147 myTabWidget->setEnabled( true );
3152 \brief Deactivate dialog box
3154 void SMESHGUI_MeshInfoDlg::deactivate()
3156 myTabWidget->setEnabled( false );
3157 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3161 \brief Called when users switches between node / element modes.
3163 void SMESHGUI_MeshInfoDlg::modeChanged()
3170 \brief Called when users prints mesh element ID in the corresponding field.
3172 void SMESHGUI_MeshInfoDlg::idChanged()
3174 myIDPreview->SetPointsLabeled( false );
3176 SVTK_Selector* selector = SMESH::GetSelector();
3177 if ( myActor && selector ) {
3178 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3179 TColStd_MapOfInteger ID;
3181 std::vector<int> idVec;
3182 std::list< gp_XYZ > aGrCentersXYZ;
3183 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3184 foreach ( QString tid, idTxt ) {
3185 long id = tid.trimmed().toLong();
3186 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3187 myActor->GetObject()->GetMesh()->FindElement( id ) :
3188 myActor->GetObject()->GetMesh()->FindNode( id );
3192 if ( myMode->checkedId() == ElemMode )
3194 idVec.push_back( id );
3195 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ));
3199 selector->AddOrRemoveIndex( IO, ID, false );
3200 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3202 if ( myMode->checkedId() == NodeMode )
3203 myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID );
3205 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3207 bool showIDs = ( !ID.IsEmpty() &&
3208 myIDPreviewCheck->isChecked() &&
3209 myTabWidget->currentIndex() == ElemInfo );
3210 myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() );
3212 aViewWindow->highlight( IO, true, true );
3213 aViewWindow->Repaint();
3215 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3220 * \brief Show IDs clicked
3222 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3224 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3225 SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn );
3226 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3227 aViewWindow->Repaint();
3230 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3232 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) {
3233 myMode->button( NodeMode )->click();
3234 myID->setText( QString::number( id ));
3238 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3240 if ( !theStr.isEmpty() ) {
3241 myMode->button( ElemMode )->click();
3242 myID->setText( theStr );
3246 void SMESHGUI_MeshInfoDlg::dump()
3248 QStringList aFilters;
3249 aFilters.append( tr( "TEXT_FILES" ));
3251 bool anIsBase = true;
3252 bool anIsElem = true;
3253 bool anIsAdd = true;
3254 bool anIsCtrl = true;
3256 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3257 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3258 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3259 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3260 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3263 DumpFileDlg fd( this );
3264 fd.setWindowTitle( tr( "SAVE_INFO" ));
3265 fd.setNameFilters( aFilters );
3266 fd.myBaseChk->setChecked( anIsBase );
3267 fd.myElemChk->setChecked( anIsElem );
3268 fd.myAddChk ->setChecked( anIsAdd );
3269 fd.myCtrlChk->setChecked( anIsCtrl );
3270 if ( fd.exec() == QDialog::Accepted )
3272 QString aFileName = fd.selectedFile();
3274 bool toBase = fd.myBaseChk->isChecked();
3275 bool toElem = fd.myElemChk->isChecked();
3276 bool toAdd = fd.myAddChk->isChecked();
3277 bool toCtrl = fd.myCtrlChk->isChecked();
3279 if ( !aFileName.isEmpty() ) {
3280 QFileInfo aFileInfo( aFileName );
3281 if ( aFileInfo.isDir() )
3284 QFile aFile( aFileName );
3285 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3288 QTextStream out( &aFile );
3290 if ( toBase ) myBaseInfo->saveInfo( out );
3291 if ( toElem ) myElemInfo->saveInfo( out );
3292 if ( toAdd ) myAddInfo ->saveInfo( out );
3293 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3299 \class SMESHGUI_CtrlInfo
3300 \brief Class for the mesh controls information widget.
3305 \param parent parent widget
3307 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3308 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3310 setFrameStyle( StyledPanel | Sunken );
3312 myMainLayout = new QGridLayout( this );
3313 myMainLayout->setMargin( MARGIN );
3314 myMainLayout->setSpacing( SPACING );
3317 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3318 QLabel* aName = createField();
3319 aName->setMinimumWidth( 150 );
3322 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3323 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) );
3325 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3328 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3329 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3330 QLabel* aNodesFree = createField();
3331 myWidgets << aNodesFree;
3332 myPredicates << aFilterMgr->CreateFreeNodes();
3334 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3335 QLabel* aNodesNbConn = createField();
3336 myWidgets << aNodesNbConn;
3337 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3339 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3340 QLabel* aNodesDouble = createField();
3341 myWidgets << aNodesDouble;
3342 myPredicates << aFilterMgr->CreateEqualNodes();
3343 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3344 myToleranceWidget = new SMESHGUI_SpinBox( this );
3345 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3346 myToleranceWidget->setAcceptNames( false );
3347 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ));
3350 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3351 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3352 QLabel* anEdgesDouble = createField();
3353 myWidgets << anEdgesDouble;
3354 myPredicates << aFilterMgr->CreateEqualEdges();
3357 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3358 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3359 QLabel* aFacesDouble = createField();
3360 myWidgets << aFacesDouble;
3361 myPredicates << aFilterMgr->CreateEqualFaces();
3362 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3363 QLabel* aFacesOver = createField();
3364 myWidgets << aFacesOver;
3365 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3366 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3367 myPlot = createPlot( this );
3368 myAspectRatio = aFilterMgr->CreateAspectRatio();
3371 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3372 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3373 QLabel* aVolumesDouble = createField();
3374 myWidgets << aVolumesDouble;
3375 myPredicates << aFilterMgr->CreateEqualVolumes();
3376 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3377 QLabel* aVolumesOver = createField();
3378 myWidgets << aVolumesOver;
3379 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3380 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3381 myPlot3D = createPlot( this );
3382 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3384 QToolButton* aFreeNodesBtn = new QToolButton( this );
3385 aFreeNodesBtn->setIcon(aComputeIcon);
3386 myButtons << aFreeNodesBtn; //0
3388 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3389 aNodesNbConnBtn->setIcon(aComputeIcon);
3390 myButtons << aNodesNbConnBtn; //1
3392 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3393 aDoubleNodesBtn->setIcon(aComputeIcon);
3394 myButtons << aDoubleNodesBtn; //2
3396 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3397 aDoubleEdgesBtn->setIcon(aComputeIcon);
3398 myButtons << aDoubleEdgesBtn; //3
3400 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3401 aDoubleFacesBtn->setIcon(aComputeIcon);
3402 myButtons << aDoubleFacesBtn; //4
3404 QToolButton* aOverContFacesBtn = new QToolButton( this );
3405 aOverContFacesBtn->setIcon(aComputeIcon);
3406 myButtons << aOverContFacesBtn; //5
3408 QToolButton* aComputeFaceBtn = new QToolButton( this );
3409 aComputeFaceBtn->setIcon(aComputeIcon);
3410 myButtons << aComputeFaceBtn; //6
3412 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3413 aDoubleVolumesBtn->setIcon(aComputeIcon);
3414 myButtons << aDoubleVolumesBtn; //7
3416 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3417 aOverContVolumesBtn->setIcon(aComputeIcon);
3418 myButtons << aOverContVolumesBtn; //8
3420 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3421 aComputeVolumeBtn->setIcon(aComputeIcon);
3422 myButtons << aComputeVolumeBtn; //9
3424 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ));
3425 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ));
3426 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ));
3427 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ));
3428 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ));
3429 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ));
3430 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ));
3431 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ));
3432 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ));
3433 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ));
3434 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3436 setFontAttributes( aNameLab );
3437 setFontAttributes( aNodesLab );
3438 setFontAttributes( anEdgesLab );
3439 setFontAttributes( aFacesLab );
3440 setFontAttributes( aVolumesLab );
3442 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3443 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3444 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3445 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3446 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3447 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3448 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3449 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3450 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3451 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3452 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3453 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3454 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3455 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3456 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3457 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3458 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3459 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3460 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3461 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3462 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3463 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3464 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3465 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3466 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3467 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3468 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3469 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3470 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3471 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3472 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3473 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3474 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3475 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3476 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3477 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3478 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3479 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3481 myMainLayout->setColumnStretch( 0, 0 );
3482 myMainLayout->setColumnStretch( 1, 5 );
3483 myMainLayout->setRowStretch ( 11, 5 );
3484 myMainLayout->setRowStretch ( 16, 5 );
3485 myMainLayout->setRowStretch ( 17, 1 );
3493 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3497 \brief Change widget font attributes (bold, ...).
3499 \param attr font attributes (XORed flags)
3501 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3504 QFont f = w->font();
3511 \brief Create info field
3512 \return new info field
3514 QLabel* SMESHGUI_CtrlInfo::createField()
3516 QLabel* lab = new QLabel( this );
3517 lab->setFrameStyle( StyledPanel | Sunken );
3518 lab->setAlignment( Qt::AlignCenter );
3519 lab->setAutoFillBackground( true );
3520 QPalette pal = lab->palette();
3521 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
3522 lab->setPalette( pal );
3523 lab->setMinimumWidth( 60 );
3528 \brief Create QwtPlot
3531 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3533 QwtPlot* aPlot = new QwtPlot( parent );
3534 aPlot->setMinimumSize( 100, 100 );
3535 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3536 xFont.setPointSize( 5 );
3537 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3538 yFont.setPointSize( 5 );
3539 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3540 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3546 \brief Show controls information on the selected object
3548 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3552 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3553 if ( myObject->_is_nil() ) return;
3555 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3556 myWidgets[0]->setText( aSO->GetName().c_str() );
3558 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3559 if ( mesh->_is_nil() ) return;
3561 const bool meshLoaded = mesh->IsLoaded();
3562 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3563 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3564 for ( int i = 0; i < myButtons.count(); ++i )
3565 myButtons[i]->setEnabled( true );
3567 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3568 if ( ! &nbElemsByType.in() ) return;
3570 const CORBA::Long ctrlLimit =
3571 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3574 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3575 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3576 nbElemsByType[ SMESH::FACE ] +
3577 nbElemsByType[ SMESH::VOLUME ] );
3578 if ( nbNodes + nbElems > 0 ) {
3579 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3581 computeFreeNodesInfo();
3582 computeNodesNbConnInfo();
3584 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3585 computeDoubleNodesInfo();
3588 myButtons[0]->setEnabled( true );
3589 myButtons[1]->setEnabled( true );
3590 myButtons[2]->setEnabled( true );
3594 for( int i=2; i<=11; i++)
3595 myMainLayout->itemAt(i)->widget()->setVisible( false );
3599 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3601 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3602 computeDoubleEdgesInfo();
3604 myButtons[3]->setEnabled( true );
3607 for( int i=11; i<=14; i++)
3608 myMainLayout->itemAt(i)->widget()->setVisible( false );
3612 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3613 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3615 computeDoubleFacesInfo();
3616 // over constrained faces
3617 computeOverConstrainedFacesInfo();
3618 // aspect Ratio histogram
3619 computeAspectRatio();
3622 myButtons[4]->setEnabled( true );
3623 myButtons[5]->setEnabled( true );
3624 myButtons[6]->setEnabled( true );
3626 #ifdef DISABLE_PLOT2DVIEWER
3627 myMainLayout->setRowStretch(12,0);
3628 for( int i=25; i<=27; i++)
3629 myMainLayout->itemAt(i)->widget()->setVisible( false );
3633 myMainLayout->setRowStretch(12,0);
3634 for( int i=18; i<=27; i++)
3635 myMainLayout->itemAt(i)->widget()->setVisible( false );
3639 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3640 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3642 computeDoubleVolumesInfo();
3643 // over constrained volumes
3644 computeOverConstrainedVolumesInfo();
3645 // aspect Ratio 3D histogram
3646 computeAspectRatio3D();
3649 myButtons[7]->setEnabled( true );
3650 myButtons[8]->setEnabled( true );
3651 myButtons[9]->setEnabled( true );
3653 #ifdef DISABLE_PLOT2DVIEWER
3654 myMainLayout->setRowStretch(17,0);
3655 for( int i=35; i<=37; i++)
3656 myMainLayout->itemAt(i)->widget()->setVisible( false );
3660 myMainLayout->setRowStretch(17,0);
3661 for( int i=28; i<=37; i++)
3662 myMainLayout->itemAt(i)->widget()->setVisible( false );
3666 //================================================================================
3668 * \brief Computes and shows nb of elements satisfying a given predicate
3669 * \param [in] ft - a predicate type (SMESH::FunctorType)
3670 * \param [in] iBut - index of one of myButtons to disable
3671 * \param [in] iWdg - index of one of myWidgets to show the computed number
3673 //================================================================================
3675 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3677 myButtons[ iBut ]->setEnabled( false );
3678 myWidgets[ iWdg ]->setText( "" );
3679 if ( myObject->_is_nil() ) return;
3681 SUIT_OverrideCursor wc;
3683 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3684 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3687 this->showInfo( myObject ); // try to show all values
3688 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3689 return; // <ft> predicate already computed
3691 // look for a predicate of type <ft>
3692 for ( int i = 0; i < myPredicates.count(); ++i )
3693 if ( myPredicates[i]->GetFunctorType() == ft )
3695 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3696 myWidgets[ iWdg ]->setText( QString::number( nb ));
3700 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3702 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3705 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3707 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3710 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3712 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3715 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3717 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3720 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3722 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3725 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3727 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3730 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3732 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3735 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3737 myButtons[ 1 ]->setEnabled( false );
3738 myWidgets[ 2 ]->setText( "" );
3739 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3740 if ( mesh->_is_nil() ) return;
3741 if ( !mesh->IsLoaded() )
3744 this->showInfo( myObject ); // try to show all values
3745 if ( !myWidgets[ 2 ]->text().isEmpty() )
3746 return; // already computed
3748 myNodeConnFunctor->SetMesh( mesh );
3749 SMESH::Histogram_var histogram =
3750 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3752 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3755 void SMESHGUI_CtrlInfo::computeAspectRatio()
3757 #ifndef DISABLE_PLOT2DVIEWER
3758 myButtons[6]->setEnabled( false );
3760 if ( myObject->_is_nil() ) return;
3762 SUIT_OverrideCursor wc;
3764 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3765 if ( aHistogram && !aHistogram->isEmpty() ) {
3766 QwtPlotItem* anItem = aHistogram->createPlotItem();
3767 anItem->attach( myPlot );
3774 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3776 #ifndef DISABLE_PLOT2DVIEWER
3777 myButtons[9]->setEnabled( false );
3779 if ( myObject->_is_nil() ) return;
3781 SUIT_OverrideCursor wc;
3783 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3784 if ( aHistogram && !aHistogram->isEmpty() ) {
3785 QwtPlotItem* anItem = aHistogram->createPlotItem();
3786 anItem->attach( myPlot3D );
3794 \brief Internal clean-up (reset widget)
3796 void SMESHGUI_CtrlInfo::clearInternal()
3798 for( int i=0; i<=35; i++)
3799 myMainLayout->itemAt(i)->widget()->setVisible( true );
3800 for( int i=0; i<=9; i++)
3801 myButtons[i]->setEnabled( false );
3802 myPlot->detachItems();
3803 myPlot3D->detachItems();
3806 myWidgets[0]->setText( QString() );
3807 for ( int i = 1; i < myWidgets.count(); i++ )
3808 myWidgets[i]->setText( "" );
3809 myMainLayout->setRowStretch(11,5);
3810 myMainLayout->setRowStretch(16,5);
3813 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3815 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3816 myButtons[1]->setEnabled( true );
3817 myWidgets[2]->setText("");
3820 #ifndef DISABLE_PLOT2DVIEWER
3821 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3823 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3824 if ( mesh->_is_nil() ) return 0;
3825 if ( !mesh->IsLoaded() )
3827 aNumFun->SetMesh( mesh );
3829 CORBA::Long cprecision = 6;
3830 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
3831 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3832 aNumFun->SetPrecision( cprecision );
3834 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3836 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3837 /*isLogarithmic=*/false,
3839 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3840 aHistogram->setColor( palette().color( QPalette::Highlight ));
3841 if ( &histogramVar.in() )
3843 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3844 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3845 if ( histogramVar->length() >= 2 )
3846 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3852 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3853 out << QString( 20, '-' ) << "\n";
3854 out << tr( "CTRL_INFO" ) << "\n";
3855 out << QString( 20, '-' ) << "\n";
3856 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3857 out << tr( "NODES_INFO" ) << "\n";
3858 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3859 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3860 out << tr( "EDGES_INFO" ) << "\n";
3861 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3862 out << tr( "FACES_INFO" ) << "\n";
3863 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3864 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3865 out << tr( "VOLUMES_INFO" ) << "\n";
3866 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3867 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3871 \class SMESHGUI_CtrlInfoDlg
3872 \brief Controls information dialog box
3877 \param parent parent widget
3879 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3882 setAttribute( Qt::WA_DeleteOnClose, true );
3883 setWindowTitle( tr( "CTRL_INFO" ));
3884 setMinimumSize( 400, 600 );
3886 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3889 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3890 okBtn->setAutoDefault( true );
3891 okBtn->setDefault( true );
3893 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3894 dumpBtn->setAutoDefault( true );
3895 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3896 helpBtn->setAutoDefault( true );
3898 QHBoxLayout* btnLayout = new QHBoxLayout;
3899 btnLayout->setSpacing( SPACING );
3900 btnLayout->setMargin( 0 );
3902 btnLayout->addWidget( okBtn );
3903 btnLayout->addWidget( dumpBtn );
3904 btnLayout->addStretch( 10 );
3905 btnLayout->addWidget( helpBtn );
3907 QVBoxLayout* l = new QVBoxLayout ( this );
3908 l->setMargin( MARGIN );
3909 l->setSpacing( SPACING );
3910 l->addWidget( myCtrlInfo );
3911 l->addLayout( btnLayout );
3913 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
3914 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
3915 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
3916 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
3917 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
3925 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3930 \brief Show controls information
3931 \param IO interactive object
3933 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3935 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ))
3936 myCtrlInfo->showInfo( obj );
3940 \brief Perform clean-up actions on the dialog box closing.
3942 void SMESHGUI_CtrlInfoDlg::reject()
3944 SMESH::SetPointRepresentation( false );
3949 \brief Setup selection mode depending on the current dialog box state.
3951 void SMESHGUI_CtrlInfoDlg::updateSelection()
3953 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3954 disconnect( selMgr, 0, this, 0 );
3955 SMESH::SetPointRepresentation( false );
3956 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3961 \brief Show mesh information
3963 void SMESHGUI_CtrlInfoDlg::updateInfo()
3965 SUIT_OverrideCursor wc;
3967 SALOME_ListIO selected;
3968 SMESHGUI::selectionMgr()->selectedObjects( selected );
3970 if ( selected.Extent() == 1 ) {
3971 Handle(SALOME_InteractiveObject) IO = selected.First();
3977 \brief Activate dialog box
3979 void SMESHGUI_CtrlInfoDlg::activate()
3981 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3982 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3987 \brief Deactivate dialog box
3989 void SMESHGUI_CtrlInfoDlg::deactivate()
3991 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3995 * \brief Dump contents into a file
3997 void SMESHGUI_CtrlInfoDlg::dump()
3999 QStringList aFilters;
4000 aFilters.append( tr( "TEXT_FILES" ));
4002 DumpFileDlg fd( this );
4003 fd.setWindowTitle( tr( "SAVE_INFO" ));
4004 fd.setNameFilters( aFilters );
4005 fd.myBaseChk->hide();
4006 fd.myElemChk->hide();
4007 fd.myAddChk ->hide();
4008 fd.myCtrlChk->hide();
4009 if ( fd.exec() == QDialog::Accepted )
4011 QString aFileName = fd.selectedFile();
4012 if ( !aFileName.isEmpty() ) {
4013 QFileInfo aFileInfo( aFileName );
4014 if ( aFileInfo.isDir() )
4017 QFile aFile( aFileName );
4018 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
4021 QTextStream out( &aFile );
4022 myCtrlInfo->saveInfo( out );
4030 void SMESHGUI_CtrlInfoDlg::help()
4032 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");