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* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
390 QLabel* a3DHexPriTotal = createField();
391 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
392 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
393 QLabel* a3DPolTotal = createField();
394 a3DPolTotal->setObjectName("nbPolyhedron");
395 myWidgets[ index++ ] << a3DLine;
396 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
397 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
398 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
399 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
400 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
401 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
402 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
404 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
405 myLoadBtn->setAutoDefault( true );
406 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ));
408 setFontAttributes( aNameLab, Bold );
409 setFontAttributes( aObjLab, Bold );
410 setFontAttributes( aNodesLab, Bold );
411 setFontAttributes( aElemLab, Bold );
412 setFontAttributes( aElemTotal, Italic );
413 setFontAttributes( aElemLin, Italic );
414 setFontAttributes( aElemQuad, Italic );
415 setFontAttributes( aElemBiQuad, Italic );
416 setFontAttributes( a0DLab, Bold );
417 setFontAttributes( aBallLab, Bold );
418 setFontAttributes( a1DLab, Bold );
419 setFontAttributes( a2DLab, Bold );
420 setFontAttributes( a3DLab, Bold );
422 l->addWidget( aNameLab, 0, 0 );
423 l->addWidget( aName, 0, 1, 1, 4 );
424 l->addWidget( aObjLab, 1, 0 );
425 l->addWidget( aObj, 1, 1, 1, 4 );
426 l->addWidget( aNodesLine, 2, 0, 1, 5 );
427 l->addWidget( aNodesLab, 3, 0 );
428 l->addWidget( aNodes, 3, 1 );
429 l->addWidget( aElemLine, 4, 0, 1, 5 );
430 l->addWidget( aElemLab, 5, 0 );
431 l->addWidget( aElemTotal, 5, 1 );
432 l->addWidget( aElemLin, 5, 2 );
433 l->addWidget( aElemQuad, 5, 3 );
434 l->addWidget( aElemBiQuad, 5, 4 );
435 l->addWidget( aNbLine, 6, 1, 1, 4 );
436 l->addWidget( aNbTotal, 7, 1 );
437 l->addWidget( aNbLin, 7, 2 );
438 l->addWidget( aNbQuad, 7, 3 );
439 l->addWidget( aNbBiQuad, 7, 4 );
440 l->addWidget( a0DLine, 8, 1, 1, 4 );
441 l->addWidget( a0DLab, 9, 0 );
442 l->addWidget( a0DTotal, 9, 1 );
443 l->addWidget( aBallLine, 10, 1, 1, 4 );
444 l->addWidget( aBallLab, 11, 0 );
445 l->addWidget( aBallTotal, 11, 1 );
446 l->addWidget( a1DLine, 12, 1, 1, 4 );
447 l->addWidget( a1DLab, 13, 0 );
448 l->addWidget( a1DTotal, 13, 1 );
449 l->addWidget( a1DLin, 13, 2 );
450 l->addWidget( a1DQuad, 13, 3 );
451 l->addWidget( a2DLine, 14, 1, 1, 4 );
452 l->addWidget( a2DLab, 15, 0 );
453 l->addWidget( a2DTotal, 15, 1 );
454 l->addWidget( a2DLin, 15, 2 );
455 l->addWidget( a2DQuad, 15, 3 );
456 l->addWidget( a2DBiQuad, 15, 4 );
457 l->addWidget( a2DTriLab, 16, 0 );
458 l->addWidget( a2DTriTotal, 16, 1 );
459 l->addWidget( a2DTriLin, 16, 2 );
460 l->addWidget( a2DTriQuad, 16, 3 );
461 l->addWidget( a2DTriBiQuad, 16, 4 );
462 l->addWidget( a2DQuaLab, 17, 0 );
463 l->addWidget( a2DQuaTotal, 17, 1 );
464 l->addWidget( a2DQuaLin, 17, 2 );
465 l->addWidget( a2DQuaQuad, 17, 3 );
466 l->addWidget( a2DQuaBiQuad, 17, 4 );
467 l->addWidget( a2DPolLab, 18, 0 );
468 l->addWidget( a2DPolTotal, 18, 1 );
469 l->addWidget( a2DPolLin, 18, 2 );
470 l->addWidget( a2DPolQuad, 18, 3 );
471 l->addWidget( a3DLine, 19, 1, 1, 4 );
472 l->addWidget( a3DLab, 20, 0 );
473 l->addWidget( a3DTotal, 20, 1 );
474 l->addWidget( a3DLin, 20, 2 );
475 l->addWidget( a3DQuad, 20, 3 );
476 l->addWidget( a3DBiQuad, 20, 4 );
477 l->addWidget( a3DTetLab, 21, 0 );
478 l->addWidget( a3DTetTotal, 21, 1 );
479 l->addWidget( a3DTetLin, 21, 2 );
480 l->addWidget( a3DTetQuad, 21, 3 );
481 l->addWidget( a3DHexLab, 22, 0 );
482 l->addWidget( a3DHexTotal, 22, 1 );
483 l->addWidget( a3DHexLin, 22, 2 );
484 l->addWidget( a3DHexQuad, 22, 3 );
485 l->addWidget( a3DHexBiQuad, 22, 4 );
486 l->addWidget( a3DPyrLab, 23, 0 );
487 l->addWidget( a3DPyrTotal, 23, 1 );
488 l->addWidget( a3DPyrLin, 23, 2 );
489 l->addWidget( a3DPyrQuad, 23, 3 );
490 l->addWidget( a3DPriLab, 24, 0 );
491 l->addWidget( a3DPriTotal, 24, 1 );
492 l->addWidget( a3DPriLin, 24, 2 );
493 l->addWidget( a3DPriQuad, 24, 3 );
494 l->addWidget( a3DHexPriLab, 25, 0 );
495 l->addWidget( a3DHexPriTotal, 25, 1 );
496 l->addWidget( a3DPolLab, 26, 0 );
497 l->addWidget( a3DPolTotal, 26, 1 );
498 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
500 l->setColumnStretch( 0, 0 );
501 l->setColumnStretch( 1, 5 );
502 l->setColumnStretch( 2, 5 );
503 l->setColumnStretch( 3, 5 );
504 l->setColumnStretch( 4, 5 );
505 l->setRowStretch( 27, 5 );
513 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
518 \brief Show information on the mesh object.
519 \param obj object being processed (mesh, sub-mesh, group, ID source)
521 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
524 if ( !CORBA::is_nil( obj )) {
525 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
527 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
528 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
529 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
530 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
531 if ( !aMesh->_is_nil() ) {
532 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ));
534 else if ( !aSubMesh->_is_nil() ) {
535 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ));
537 else if ( !aGroup->_is_nil() ) {
539 switch( aGroup->GetType() ) {
540 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
541 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
542 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
543 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
544 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
545 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
546 default: objType = tr( "OBJECT_GROUP" );break;
548 myWidgets[iObject][iSingle]->setProperty( "text", objType );
550 SMESH::long_array_var info = obj->GetMeshInfo();
551 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ));
552 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ));
553 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ));
554 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
555 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ));
556 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ));
557 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ));
558 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
559 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
560 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
561 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
562 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
563 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
564 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
566 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
567 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ));
568 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ));
569 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ));
570 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ));
571 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ));
572 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ));
573 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ));
574 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ));
575 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ));
576 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ));
577 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ));
578 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
579 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ));
580 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ));
581 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
582 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
583 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
584 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
585 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
586 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
587 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
588 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
589 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ));
590 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ));
591 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ));
592 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ));
593 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ));
594 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ));
595 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ));
596 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ));
597 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ));
598 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ));
599 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ));
600 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ));
601 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ));
602 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ));
603 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ));
604 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ));
605 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ));
606 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ));
607 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ));
608 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
609 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
610 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
611 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
612 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ));
613 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ));
614 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ));
615 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ));
616 // before full loading from study file, type of elements in a sub-mesh can't be defined
618 bool infoOK = obj->IsMeshInfoCorrect();
619 myLoadBtn->setVisible( !infoOK );
623 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
624 // 2. No info at all (for a group on geom or filter)
625 bool hasAnyInfo = false;
626 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
627 hasAnyInfo = info[i];
628 if ( hasAnyInfo ) // believe it is a sub-mesh
630 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
632 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
633 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
634 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
635 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
636 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
637 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
638 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
639 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
640 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
641 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
643 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
644 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
645 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
646 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
647 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
648 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
649 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
651 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
653 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
654 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
655 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
656 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
658 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
659 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
660 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
661 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
662 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
663 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
664 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
665 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
666 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
667 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
668 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
669 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
670 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
671 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
672 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
673 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
674 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
679 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
681 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
682 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
683 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
684 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
685 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
686 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
687 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
688 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
689 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
690 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
691 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
692 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
694 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
695 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
696 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
697 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
698 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
699 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
700 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
701 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
703 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
704 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
705 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
706 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
707 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
708 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
709 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
710 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
711 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
712 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
713 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
714 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
715 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
716 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
717 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
718 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
719 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
726 \brief Load mesh from a study file
728 void SMESHGUI_MeshInfo::loadMesh()
730 SUIT_OverrideCursor wc;
732 SALOME_ListIO selected;
733 SMESHGUI::selectionMgr()->selectedObjects( selected );
735 if ( selected.Extent() == 1 ) {
736 Handle(SALOME_InteractiveObject) IO = selected.First();
737 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
738 if ( !CORBA::is_nil( obj )) {
739 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
740 if ( !mesh->_is_nil() )
750 \brief Reset the widget to the initial state (nullify all fields).
752 void SMESHGUI_MeshInfo::clear()
754 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
755 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
756 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ));
757 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ));
758 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ));
759 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ));
760 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ));
761 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
762 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ));
763 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ));
764 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
765 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
766 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ));
767 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ));
768 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
769 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
770 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ));
771 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ));
772 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
773 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
774 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ));
775 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
776 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ));
777 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ));
778 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ));
779 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
780 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
781 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
782 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
783 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
784 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
785 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
786 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
787 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
788 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ));
789 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ));
790 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ));
791 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
792 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ));
793 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ));
794 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
795 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
796 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ));
797 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ));
798 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ));
799 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
803 \brief Create info field
804 \return new info field
806 QLabel* SMESHGUI_MeshInfo::createField()
808 QLabel* lab = new QLabel( this );
809 lab->setFrameStyle( StyledPanel | Sunken );
810 lab->setAlignment( Qt::AlignCenter );
811 lab->setAutoFillBackground( true );
812 QPalette pal = lab->palette();
813 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
814 lab->setPalette( pal );
815 lab->setMinimumWidth( 70 );
820 \brief Create horizontal rule.
821 \return new line object
823 QWidget* SMESHGUI_MeshInfo::createLine()
825 QFrame* line = new QFrame( this );
826 line->setFrameStyle( HLine | Sunken );
831 \brief Change widget font attributes (bold, italic, ...).
833 \param attr font attributes (XORed flags)
834 \param val value to be set to attributes
836 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
840 if ( attr & Bold ) f.setBold( val );
841 if ( attr & Italic ) f.setItalic( val );
847 \brief Show/hide group(s) of fields.
848 \param start beginning of the block
849 \param end end of the block
850 \param on visibility flag
852 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
854 start = qMax( 0, start );
855 end = qMin( end, (int)iElementsEnd );
856 for ( int i = start; i < end; i++ ) {
857 wlist wl = myWidgets[i];
858 foreach ( QWidget* w, wl ) w->setVisible( on );
862 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
864 out << QString( 9, '-' ) << "\n";
865 out << tr( "BASE_INFO" ) << "\n";
866 out << QString( 9, '-' ) << "\n";
867 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" )).toString() << "\n";
868 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" )).toString() << "\n";
869 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" )).toString() << "\n";
870 out << tr( "ELEMENTS_LAB" ) << "\n";
871 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" )).toString() << "\n";
872 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" )).toString() << "\n";
873 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" )).toString() << "\n";
874 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" )).toString() << "\n";
875 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
876 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" )).toString() << "\n";
877 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
878 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" )).toString() << "\n";
879 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
880 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" )).toString() << "\n";
881 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" )).toString() << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" )).toString() << "\n";
883 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" )).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" )).toString() << "\n";
886 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" )).toString() << "\n";
887 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" )).toString() << "\n";
888 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
889 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" )).toString() << "\n";
890 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" )).toString() << "\n";
891 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" )).toString() << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" )).toString() << "\n";
893 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" )).toString() << "\n";
895 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" )).toString() << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" )).toString() << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" )).toString() << "\n";
898 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
899 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" )).toString() << "\n";
900 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" )).toString() << "\n";
901 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" )).toString() << "\n";
902 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
903 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" )).toString() << "\n";
904 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" )).toString() << "\n";
905 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" )).toString() << "\n";
906 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" )).toString() << "\n";
907 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
908 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" )).toString() << "\n";
909 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" )).toString() << "\n";
910 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" )).toString() << "\n";
911 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" )).toString() << "\n";
913 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" )).toString() << "\n";
914 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" )).toString() << "\n";
915 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" )).toString() << "\n";
916 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
917 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" )).toString() << "\n";
918 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" )).toString() << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" )).toString() << "\n";
920 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
921 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" )).toString() << "\n";
922 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" )).toString() << "\n";
923 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" )).toString() << "\n";
924 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
925 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" )).toString() << "\n";
926 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
927 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" )).toString() << "\n" << "\n";
931 \class SMESHGUI_ElemInfo
932 \brief Base class for the mesh element information widget.
937 \param parent parent widget
939 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
940 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
942 myFrame = new QWidget( this );
943 myExtra = new ExtraWidget( this );
944 QVBoxLayout* vbl = new QVBoxLayout( this );
946 vbl->setSpacing( 0 );
947 vbl->addWidget( myFrame );
948 vbl->addWidget( myExtra );
949 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ));
950 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ));
957 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
962 \brief Set mesh data source (actor)
963 \param actor mesh object actor
965 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
967 if ( myActor != actor ) {
975 \brief Show mesh element information
976 \param id mesh node / element ID
977 \param isElem show mesh element information if \c true or mesh node information if \c false
979 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
983 showInfo( ids, isElem );
987 \brief Show mesh element information
988 \param ids mesh nodes / elements identifiers
989 \param isElem show mesh element information if \c true or mesh node information if \c false
991 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
993 QList<long> newIds = ids.toList();
995 if ( myIDs == newIds && myIsElement == isElem ) return;
998 myIsElement = isElem;
1001 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1005 \brief Clear mesh element information widget
1007 void SMESHGUI_ElemInfo::clear()
1016 \brief Get central area widget
1017 \return central widget
1019 QWidget* SMESHGUI_ElemInfo::frame() const
1026 \return actor being used
1028 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1034 \brief Get current info mode.
1035 \return \c true if mesh element information is shown or \c false if node information is shown
1037 bool SMESHGUI_ElemInfo::isElements() const
1043 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1044 \brief Show information on the specified nodes / elements
1046 This function is to be redefined in sub-classes.
1048 \param ids nodes / elements identifiers information is to be shown on
1052 \brief Internal clean-up (reset widget)
1054 void SMESHGUI_ElemInfo::clearInternal()
1059 \brief Get node connectivity
1060 \param node mesh node
1061 \return node connectivity map
1063 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1067 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1068 while ( it && it->more() ) {
1069 const SMDS_MeshElement* ne = it->next();
1070 elmap[ ne->GetType() ] << ne->GetID();
1077 \brief Format connectivity data to string representation
1078 \param connectivity connetivity map
1079 \param type element type
1080 \return string representation of the connectivity
1082 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1085 if ( connectivity.contains( type )) {
1086 QList<int> elements = connectivity[ type ];
1088 foreach( int id, elements )
1089 str << QString::number( id );
1091 return str.join( " " );
1095 \brief Calculate gravity center of the mesh element
1096 \param element mesh element
1098 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1102 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1103 while ( nodeIt->more() ) {
1104 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1105 xyz.add( node->X(), node->Y(), node->Z() );
1107 xyz.divide( element->NbNodes() );
1113 \brief Calculate normal vector to the mesh face
1114 \param element mesh face
1116 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1118 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ));
1119 return XYZ(n.X(), n.Y(), n.Z());
1123 \brief This slot is called from "Show Previous" button click.
1124 Shows information on the previous group of the items.
1126 void SMESHGUI_ElemInfo::showPrevious()
1128 myIndex = qMax( 0, myIndex-1 );
1130 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1134 \brief This slot is called from "Show Next" button click.
1135 Shows information on the next group of the items.
1137 void SMESHGUI_ElemInfo::showNext()
1139 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1141 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1145 \brief Update widgets state
1147 void SMESHGUI_ElemInfo::updateControls()
1149 myExtra->updateControls( myIDs.count(), myIndex );
1153 \class SMESHGUI_SimpleElemInfo
1154 \brief Represents mesh element information in the simple text area.
1159 \param parent parent widget
1161 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1162 : SMESHGUI_ElemInfo( parent )
1164 myInfo = new QTextBrowser( frame() );
1165 QVBoxLayout* l = new QVBoxLayout( frame() );
1167 l->addWidget( myInfo );
1171 \brief Show mesh element information
1172 \param ids mesh nodes / elements identifiers
1174 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1179 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1180 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1181 int cprecision = -1;
1182 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1183 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1184 foreach ( long id, ids ) {
1185 if ( !isElements() ) {
1189 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1190 if ( !node ) return;
1193 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id ));
1195 myInfo->append( "" );
1197 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1198 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1199 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1200 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1202 myInfo->append( "" );
1204 Connectivity connectivity = nodeConnectivity( node );
1205 if ( !connectivity.isEmpty() ) {
1206 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1207 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1208 if ( !con.isEmpty() )
1209 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1210 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1211 if ( !con.isEmpty() )
1212 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1213 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1214 if ( !con.isEmpty() )
1215 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con ));
1216 con = formatConnectivity( connectivity, SMDSAbs_Face );
1217 if ( !con.isEmpty() )
1218 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1219 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1220 if ( !con.isEmpty() )
1221 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1224 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1227 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1228 if ( !CORBA::is_nil( aMeshPtr )) {
1229 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1230 int shapeID = pos->shapeID;
1231 if ( shapeID > 0 ) {
1233 double u = 0, v = 0;
1234 switch ( pos->shapeType ) {
1236 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1237 if ( pos->params.length() == 1 )
1241 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1242 if ( pos->params.length() == 2 ) {
1248 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1251 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1255 myInfo->append( "" );
1256 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) );
1257 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ));
1258 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1259 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )).
1260 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1261 if ( pos->shapeType == GEOM::FACE ) {
1262 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )).
1263 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1268 // groups node belongs to
1269 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1270 if ( !CORBA::is_nil( aMesh )) {
1271 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1272 myInfo->append( "" ); // separator
1273 bool top_created = false;
1274 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1275 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1276 if ( CORBA::is_nil( aGrp )) continue;
1277 QString aName = aGrp->GetName();
1278 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1279 if ( !top_created ) {
1280 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1283 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1284 if ( grp_details ) {
1285 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1286 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1287 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1289 // type : group on geometry, standalone group, group on filter
1290 if ( !CORBA::is_nil( aStdGroup )) {
1291 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1292 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1294 else if ( !CORBA::is_nil( aGeomGroup )) {
1295 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1296 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1297 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1298 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1300 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1301 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1304 else if ( !CORBA::is_nil( aFltGroup )) {
1305 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1306 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1310 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1311 arg( QString::number( aGrp->Size() )) );
1314 SALOMEDS::Color color = aGrp->GetColor();
1315 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1316 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1324 // show element info
1326 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1327 SMESH::Controls::NumericalFunctorPtr afunctor;
1330 // Element ID && Type
1332 switch( e->GetType() ) {
1333 case SMDSAbs_0DElement:
1334 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1336 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1338 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1340 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1341 case SMDSAbs_Volume:
1342 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1346 if ( stype.isEmpty() ) return;
1347 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ));
1349 myInfo->append( "" );
1353 switch( e->GetEntityType() ) {
1354 case SMDSEntity_Triangle:
1355 case SMDSEntity_Quad_Triangle:
1356 case SMDSEntity_BiQuad_Triangle:
1357 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1358 case SMDSEntity_Quadrangle:
1359 case SMDSEntity_Quad_Quadrangle:
1360 case SMDSEntity_BiQuad_Quadrangle:
1361 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1362 case SMDSEntity_Polygon:
1363 case SMDSEntity_Quad_Polygon:
1364 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1365 case SMDSEntity_Tetra:
1366 case SMDSEntity_Quad_Tetra:
1367 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1368 case SMDSEntity_Pyramid:
1369 case SMDSEntity_Quad_Pyramid:
1370 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1371 case SMDSEntity_Hexa:
1372 case SMDSEntity_Quad_Hexa:
1373 case SMDSEntity_TriQuad_Hexa:
1374 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1375 case SMDSEntity_Penta:
1376 case SMDSEntity_Quad_Penta:
1377 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1378 case SMDSEntity_Hexagonal_Prism:
1379 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1380 case SMDSEntity_Polyhedra:
1381 case SMDSEntity_Quad_Polyhedra:
1382 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1386 if ( !gtype.isEmpty() )
1387 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype ));
1389 // Quadratic flag (any element except 0D)
1390 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1391 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) );
1393 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1395 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() ));
1398 myInfo->append( "" );
1401 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1402 for ( int idx = 1; nodeIt->more(); idx++ ) {
1403 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1404 // node number and ID
1405 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ));
1407 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1408 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1409 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1410 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1411 // node connectivity
1412 Connectivity connectivity = nodeConnectivity( node );
1413 if ( !connectivity.isEmpty() ) {
1414 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1415 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1416 if ( !con.isEmpty() )
1417 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1418 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1419 if ( !con.isEmpty() )
1420 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1421 con = formatConnectivity( connectivity, SMDSAbs_Face );
1422 if ( !con.isEmpty() )
1423 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1424 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1425 if ( !con.isEmpty() )
1426 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1429 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1433 myInfo->append( "" );
1436 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) );
1438 if ( e->GetType() == SMDSAbs_Edge ) {
1439 afunctor.reset( new SMESH::Controls::Length() );
1440 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1441 afunctor->SetPrecision( cprecision );
1442 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) );
1444 if( e->GetType() == SMDSAbs_Face ) {
1446 afunctor.reset( new SMESH::Controls::Area() );
1447 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1448 afunctor->SetPrecision( cprecision );
1449 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1451 afunctor.reset( new SMESH::Controls::Taper() );
1452 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1453 afunctor->SetPrecision( cprecision );
1454 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1456 afunctor.reset( new SMESH::Controls::AspectRatio() );
1457 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1458 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1460 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1461 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1462 afunctor->SetPrecision( cprecision );
1463 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1465 afunctor.reset( new SMESH::Controls::Warping() );
1466 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1467 afunctor->SetPrecision( cprecision );
1468 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1470 afunctor.reset( new SMESH::Controls::Skew() );
1471 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1472 afunctor->SetPrecision( cprecision );
1473 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1475 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1476 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1477 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) );
1479 if( e->GetType() == SMDSAbs_Volume ) {
1481 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1482 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1483 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1485 afunctor.reset( new SMESH::Controls::Volume() );
1486 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1487 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1489 afunctor.reset( new SMESH::Controls::Volume() );
1490 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1491 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) );
1494 myInfo->append( "" );
1497 XYZ gc = gravityCenter( e );
1498 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1501 if( e->GetType() == SMDSAbs_Face ) {
1502 XYZ gc = normal( e );
1503 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1507 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1508 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1509 if ( !CORBA::is_nil( aMesh )) {
1510 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1511 int shapeID = pos.shapeID;
1512 if ( shapeID > 0 ) {
1513 myInfo->append( "" ); // separator
1515 switch ( pos.shapeType ) {
1516 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1517 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1518 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1519 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1520 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1521 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1523 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID ));
1528 // Groups the element belongs to
1529 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1530 if ( !CORBA::is_nil( aMesh )) {
1531 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1532 myInfo->append( "" ); // separator
1533 bool top_created = false;
1534 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1535 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1536 if ( CORBA::is_nil( aGrp )) continue;
1537 QString aName = aGrp->GetName();
1538 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1539 if ( !top_created ) {
1540 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1543 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1544 if ( grp_details ) {
1545 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1546 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1547 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1549 // type : group on geometry, standalone group, group on filter
1550 if ( !CORBA::is_nil( aStdGroup )) {
1551 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1552 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1554 else if ( !CORBA::is_nil( aGeomGroup )) {
1555 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1556 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1557 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1558 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1560 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1561 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1564 else if ( !CORBA::is_nil( aFltGroup )) {
1565 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1566 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1569 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1570 arg( QString::number( aGrp->Size() )) );
1573 SALOMEDS::Color color = aGrp->GetColor();
1574 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1575 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1582 if ( ids.count() > 1 ) {
1583 myInfo->append( "" );
1584 myInfo->append( "------" );
1585 myInfo->append( "" );
1592 \brief Internal clean-up (reset widget)
1594 void SMESHGUI_SimpleElemInfo::clearInternal()
1599 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1601 out << QString( 12, '-' ) << "\n";
1602 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1603 out << QString( 12, '-' ) << "\n";
1604 out << myInfo->toPlainText();
1610 \class SMESHGUI_TreeElemInfo::ItemDelegate
1611 \brief Item delegate for tree mesh info widget
1614 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1617 ItemDelegate( QObject* );
1618 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1625 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1630 \brief Create item editor widget
1633 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1635 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1636 if ( qobject_cast<QLineEdit*>( w )) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1641 \class SMESHGUI_TreeElemInfo
1642 \brief Represents mesh element information in the tree-like form.
1647 \param parent parent widget
1649 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1650 : SMESHGUI_ElemInfo( parent )
1652 myInfo = new QTreeWidget( frame() );
1653 myInfo->setColumnCount( 2 );
1654 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ));
1655 myInfo->header()->setStretchLastSection( true );
1656 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1657 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1659 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1661 myInfo->setItemDelegate( new ItemDelegate( myInfo ));
1662 QVBoxLayout* l = new QVBoxLayout( frame() );
1664 l->addWidget( myInfo );
1665 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) );
1666 connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1667 connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1671 \brief Show mesh element information
1672 \param ids mesh nodes / elements identifiers
1674 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1679 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1680 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1681 int cprecision = -1;
1682 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1683 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1684 foreach ( long id, ids ) {
1685 if ( !isElements() ) {
1689 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1691 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1694 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1695 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ));
1696 nodeItem->setText( 1, QString( "#%1" ).arg( id ));
1698 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1699 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
1700 QTreeWidgetItem* xItem = createItem( coordItem );
1701 xItem->setText( 0, "X" );
1702 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1703 QTreeWidgetItem* yItem = createItem( coordItem );
1704 yItem->setText( 0, "Y" );
1705 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1706 QTreeWidgetItem* zItem = createItem( coordItem );
1707 zItem->setText( 0, "Z" );
1708 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1710 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1711 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1712 Connectivity connectivity = nodeConnectivity( node );
1713 if ( !connectivity.isEmpty() ) {
1714 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1715 if ( !con.isEmpty() ) {
1716 QTreeWidgetItem* i = createItem( conItem );
1717 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
1718 i->setText( 1, con );
1720 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1721 if ( !con.isEmpty() ) {
1722 QTreeWidgetItem* i = createItem( conItem );
1723 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
1724 i->setText( 1, con );
1725 i->setData( 1, TypeRole, NodeConnectivity );
1727 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1728 if ( !con.isEmpty() ) {
1729 QTreeWidgetItem* i = createItem( conItem );
1730 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
1731 i->setText( 1, con );
1732 i->setData( 1, TypeRole, NodeConnectivity );
1734 con = formatConnectivity( connectivity, SMDSAbs_Face );
1735 if ( !con.isEmpty() ) {
1736 QTreeWidgetItem* i = createItem( conItem );
1737 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
1738 i->setText( 1, con );
1739 i->setData( 1, TypeRole, NodeConnectivity );
1741 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1742 if ( !con.isEmpty() ) {
1743 QTreeWidgetItem* i = createItem( conItem );
1744 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
1745 i->setText( 1, con );
1746 i->setData( 1, TypeRole, NodeConnectivity );
1750 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ));
1753 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1754 if ( !CORBA::is_nil( aMeshPtr )) {
1755 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1756 int shapeID = pos->shapeID;
1757 if ( shapeID > 0 ) {
1759 double u = 0, v = 0;
1760 switch ( pos->shapeType ) {
1762 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1763 if ( pos->params.length() == 1 )
1767 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1768 if ( pos->params.length() == 2 ) {
1774 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1777 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1780 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1781 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1782 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1783 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1784 QTreeWidgetItem* uItem = createItem( posItem );
1785 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1786 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1787 if ( pos->shapeType == GEOM::FACE ) {
1788 QTreeWidgetItem* vItem = createItem( posItem );
1789 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1790 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1795 // groups node belongs to
1796 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1797 if ( !CORBA::is_nil( aMesh )) {
1798 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1799 QTreeWidgetItem* groupsItem = 0;
1800 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1801 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1802 if ( CORBA::is_nil( aGrp )) continue;
1803 QString aName = aGrp->GetName();
1804 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1805 if ( !groupsItem ) {
1806 groupsItem = createItem( nodeItem, Bold );
1807 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
1809 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1810 it->setText( 0, aName.trimmed() );
1811 if ( grp_details ) {
1812 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1813 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1814 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1816 // type : group on geometry, standalone group, group on filter
1817 QTreeWidgetItem* typeItem = createItem( it );
1818 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
1819 if ( !CORBA::is_nil( aStdGroup )) {
1820 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
1822 else if ( !CORBA::is_nil( aGeomGroup )) {
1823 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
1824 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1825 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1827 QTreeWidgetItem* gobjItem = createItem( typeItem );
1828 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
1829 gobjItem->setText( 1, sobj->GetName().c_str() );
1832 else if ( !CORBA::is_nil( aFltGroup )) {
1833 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
1837 QTreeWidgetItem* sizeItem = createItem( it );
1838 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
1839 sizeItem->setText( 1, QString::number( aGrp->Size() ));
1842 SALOMEDS::Color color = aGrp->GetColor();
1843 QTreeWidgetItem* colorItem = createItem( it );
1844 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
1845 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
1853 // show element info
1855 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1856 SMESH::Controls::NumericalFunctorPtr afunctor;
1859 // element ID && type
1861 switch( e->GetType() ) {
1862 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1863 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1864 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1865 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1866 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1869 if ( stype.isEmpty() ) return;
1870 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1871 elemItem->setText( 0, stype );
1872 elemItem->setText( 1, QString( "#%1" ).arg( id ));
1875 switch( e->GetEntityType() ) {
1876 case SMDSEntity_Triangle:
1877 case SMDSEntity_Quad_Triangle:
1878 case SMDSEntity_BiQuad_Triangle:
1879 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1880 case SMDSEntity_Quadrangle:
1881 case SMDSEntity_Quad_Quadrangle:
1882 case SMDSEntity_BiQuad_Quadrangle:
1883 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1884 case SMDSEntity_Polygon:
1885 case SMDSEntity_Quad_Polygon:
1886 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1887 case SMDSEntity_Tetra:
1888 case SMDSEntity_Quad_Tetra:
1889 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1890 case SMDSEntity_Pyramid:
1891 case SMDSEntity_Quad_Pyramid:
1892 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1893 case SMDSEntity_Hexa:
1894 case SMDSEntity_Quad_Hexa:
1895 case SMDSEntity_TriQuad_Hexa:
1896 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1897 case SMDSEntity_Penta:
1898 case SMDSEntity_Quad_Penta:
1899 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1900 case SMDSEntity_Hexagonal_Prism:
1901 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1902 case SMDSEntity_Polyhedra:
1903 case SMDSEntity_Quad_Polyhedra:
1904 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1908 if ( !gtype.isEmpty() ) {
1909 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1910 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ));
1911 typeItem->setText( 1, gtype );
1913 // quadratic flag (for edges, faces and volumes)
1914 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1916 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1917 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ));
1918 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ));
1920 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1922 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1923 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ));
1924 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1927 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1928 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1931 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1932 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1933 for ( int idx = 1; nodeIt->more(); idx++ ) {
1934 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1935 nodeInfo( node, idx, e->NbNodes(), conItem );
1939 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1940 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1941 QList<const SMDS_MeshElement*> uniqueNodes;
1942 while ( nodeIt->more() )
1943 uniqueNodes.append( nodeIt->next() );
1945 SMDS_VolumeTool vtool( e );
1946 const int nbFaces = vtool.NbFaces();
1947 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1948 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1949 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces ));
1950 faceItem->setExpanded( true );
1952 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1953 const int nbNodes = vtool.NbFaceNodes( face_id );
1954 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1955 const SMDS_MeshNode* node = aNodeIds[node_id];
1956 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1961 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1962 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ));
1964 if( e->GetType()==SMDSAbs_Edge){
1965 afunctor.reset( new SMESH::Controls::Length() );
1966 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1967 afunctor->SetPrecision( cprecision );
1968 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1969 lenItem->setText( 0, tr( "LENGTH_EDGES" ));
1970 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1972 if( e->GetType() == SMDSAbs_Face ) {
1974 afunctor.reset( new SMESH::Controls::Area() );
1975 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1976 afunctor->SetPrecision( cprecision );
1977 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1978 areaItem->setText( 0, tr( "AREA_ELEMENTS" ));
1979 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ));
1981 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1983 afunctor.reset( new SMESH::Controls::Taper() );
1984 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1985 afunctor->SetPrecision( cprecision );
1986 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1987 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ));
1988 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1990 afunctor.reset( new SMESH::Controls::Warping() );
1991 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1992 afunctor->SetPrecision( cprecision );
1993 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1994 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1995 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2000 afunctor.reset( new SMESH::Controls::AspectRatio() );
2001 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2002 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
2003 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2004 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2007 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2008 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2009 afunctor->SetPrecision( cprecision );
2010 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2011 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ));
2012 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2014 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2016 afunctor.reset( new SMESH::Controls::Skew() );
2017 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2018 afunctor->SetPrecision( cprecision );
2019 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2020 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ));
2021 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2026 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2027 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2028 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2029 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2030 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2033 if( e->GetType() == SMDSAbs_Volume ) {
2037 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2038 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2039 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2040 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ));
2041 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2044 afunctor.reset( new SMESH::Controls::Volume() );
2045 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2046 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2047 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ));
2048 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2050 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2051 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2052 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2053 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ));
2054 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2058 XYZ gc = gravityCenter( e );
2059 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2060 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ));
2061 QTreeWidgetItem* xItem = createItem( gcItem );
2062 xItem->setText( 0, "X" );
2063 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2064 QTreeWidgetItem* yItem = createItem( gcItem );
2065 yItem->setText( 0, "Y" );
2066 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2067 QTreeWidgetItem* zItem = createItem( gcItem );
2068 zItem->setText( 0, "Z" );
2069 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2072 if( e->GetType() == SMDSAbs_Face ) {
2073 XYZ gc = normal( e );
2074 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2075 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ));
2076 QTreeWidgetItem* xItem = createItem( nItem );
2077 xItem->setText( 0, "X" );
2078 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2079 QTreeWidgetItem* yItem = createItem( nItem );
2080 yItem->setText( 0, "Y" );
2081 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2082 QTreeWidgetItem* zItem = createItem( nItem );
2083 zItem->setText( 0, "Z" );
2084 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2088 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2089 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2090 if ( !CORBA::is_nil( aMesh )) {
2091 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2092 int shapeID = pos.shapeID;
2093 if ( shapeID > 0 ) {
2094 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2096 switch ( pos.shapeType ) {
2097 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2098 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2099 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2100 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2101 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2102 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2104 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ));
2105 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ));
2109 // groups element belongs to
2110 if ( !CORBA::is_nil( aMesh )) {
2111 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2112 QTreeWidgetItem* groupsItem = 0;
2113 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2114 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2115 if ( CORBA::is_nil( aGrp )) continue;
2116 QString aName = aGrp->GetName();
2117 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
2118 if ( !groupsItem ) {
2119 groupsItem = createItem( elemItem, Bold );
2120 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
2122 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2123 it->setText( 0, aName.trimmed() );
2124 if ( grp_details ) {
2125 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2126 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2127 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2129 // type : group on geometry, standalone group, group on filter
2130 QTreeWidgetItem* typeItem = createItem( it );
2131 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
2132 if ( !CORBA::is_nil( aStdGroup )) {
2133 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
2135 else if ( !CORBA::is_nil( aGeomGroup )) {
2136 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
2137 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2138 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2140 QTreeWidgetItem* gobjItem = createItem( typeItem );
2141 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2142 gobjItem->setText( 1, sobj->GetName().c_str() );
2145 else if ( !CORBA::is_nil( aFltGroup )) {
2146 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2150 QTreeWidgetItem* sizeItem = createItem( it );
2151 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2152 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2155 SALOMEDS::Color color = aGrp->GetColor();
2156 QTreeWidgetItem* colorItem = createItem( it );
2157 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2158 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2169 \brief Show node information
2170 \param node mesh node for showing
2171 \param index index of current node
2172 \param nbNodes number of unique nodes in element
2173 \param parentItem parent item of tree
2175 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2176 int nbNodes, QTreeWidgetItem* parentItem )
2178 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2179 // node number and ID
2180 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2181 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2182 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2183 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2184 nodeItem->setData( 1, IdRole, node->GetID() );
2185 nodeItem->setExpanded( false );
2187 QTreeWidgetItem* coordItem = createItem( nodeItem );
2188 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2189 QTreeWidgetItem* xItem = createItem( coordItem );
2190 xItem->setText( 0, "X" );
2191 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2192 QTreeWidgetItem* yItem = createItem( coordItem );
2193 yItem->setText( 0, "Y" );
2194 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2195 QTreeWidgetItem* zItem = createItem( coordItem );
2196 zItem->setText( 0, "Z" );
2197 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2198 // node connectivity
2199 QTreeWidgetItem* nconItem = createItem( nodeItem );
2200 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2201 Connectivity connectivity = nodeConnectivity( node );
2202 if ( !connectivity.isEmpty() ) {
2203 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2204 if ( !con.isEmpty() ) {
2205 QTreeWidgetItem* i = createItem( nconItem );
2206 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2207 i->setText( 1, con );
2209 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2210 if ( !con.isEmpty() ) {
2211 QTreeWidgetItem* i = createItem( nconItem );
2212 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2213 i->setText( 1, con );
2214 i->setData( 1, TypeRole, NodeConnectivity );
2216 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2217 if ( !con.isEmpty() ) {
2218 QTreeWidgetItem* i = createItem( nconItem );
2219 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2220 i->setText( 1, con );
2221 i->setData( 1, TypeRole, NodeConnectivity );
2223 con = formatConnectivity( connectivity, SMDSAbs_Face );
2224 if ( !con.isEmpty() ) {
2225 QTreeWidgetItem* i = createItem( nconItem );
2226 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2227 i->setText( 1, con );
2228 i->setData( 1, TypeRole, NodeConnectivity );
2230 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2231 if ( !con.isEmpty() ) {
2232 QTreeWidgetItem* i = createItem( nconItem );
2233 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2234 i->setText( 1, con );
2235 i->setData( 1, TypeRole, NodeConnectivity );
2240 \brief Internal clean-up (reset widget)
2242 void SMESHGUI_TreeElemInfo::clearInternal()
2249 \brief Create new tree item.
2250 \param parent parent tree widget item
2251 \param flags item flag
2252 \return new tree widget item
2254 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2256 QTreeWidgetItem* item;
2258 item = new QTreeWidgetItem( parent );
2260 item = new QTreeWidgetItem( myInfo );
2262 item->setFlags( item->flags() | Qt::ItemIsEditable );
2264 QFont f = item->font( 0 );
2266 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2267 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2268 item->setFont( i, f );
2271 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2273 QString resName = expandedResource( parent );
2274 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2277 item->setExpanded( true );
2281 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2283 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2284 if ( widgets.isEmpty() ) return;
2285 QTreeWidgetItem* aTreeItem = widgets.first();
2286 int type = aTreeItem->data( 1, TypeRole ).toInt();
2287 int id = aTreeItem->data( 1, IdRole ).toInt();
2289 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2290 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2291 emit( itemInfo( id ));
2292 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2293 emit( itemInfo( aTreeItem->text( 1 )) );
2296 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2299 int type = theItem->data( 1, TypeRole ).toInt();
2300 int id = theItem->data( 1, IdRole ).toInt();
2301 if ( type == ElemConnectivity && id > 0 )
2302 emit( itemInfo( id ));
2303 else if ( type == NodeConnectivity )
2304 emit( itemInfo( theItem->text( 1 )) );
2308 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2311 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2314 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2316 return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0);
2319 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2321 out << QString( 12, '-' ) << "\n";
2322 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2323 out << QString( 12, '-' ) << "\n";
2325 QTreeWidgetItemIterator it( myInfo );
2327 if ( !( *it )->text(0).isEmpty() ) {
2328 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2329 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2339 \brief Mesh information computer
2342 The class is created for different computation operation. Currently it is used
2343 to compute number of underlying nodes for the groups.
2349 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2350 QTreeWidgetItem* item,
2353 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2355 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2359 \brief Compute function
2361 void GrpComputor::compute()
2363 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2364 SUIT_OverrideCursor wc;
2365 QTreeWidgetItem* item = myItem;
2367 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2368 item->treeWidget()->removeItemWidget( item, 1 );
2369 item->setText( 1, QString::number( nb ));
2374 \class SMESHGUI_AddInfo
2375 \brief The wigdet shows additional information on the mesh object.
2380 \param parent parent widget
2382 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2383 : QTreeWidget( parent )
2385 setColumnCount( 2 );
2386 header()->setStretchLastSection( true );
2387 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2388 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2390 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2398 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2403 \brief Show additional information on the selected object
2404 \param obj object being processed (mesh, sub-mesh, group, ID source)
2406 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2408 setProperty( "group_index", 0 );
2409 setProperty( "submesh_index", 0 );
2410 myComputors.clear();
2413 if ( CORBA::is_nil( obj )) return;
2415 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2416 if ( !sobj ) return;
2419 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2420 nameItem->setText( 0, tr( "NAME" ));
2421 nameItem->setText( 1, sobj->GetName().c_str() );
2423 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2424 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2425 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2427 if ( !aMesh->_is_nil() )
2428 meshInfo( aMesh, nameItem );
2429 else if ( !aSubMesh->_is_nil() )
2430 subMeshInfo( aSubMesh, nameItem );
2431 else if ( !aGroup->_is_nil() )
2432 groupInfo( aGroup.in(), nameItem );
2436 \brief Create new tree item.
2437 \param parent parent tree widget item
2438 \param flags item flag
2439 \return new tree widget item
2441 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2443 QTreeWidgetItem* item;
2446 item = new QTreeWidgetItem( parent );
2448 item = new QTreeWidgetItem( this );
2450 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2452 QFont f = item->font( 0 );
2454 for ( int i = 0; i < columnCount(); i++ ) {
2455 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2456 item->setFont( i, f );
2459 item->setExpanded( true );
2464 \brief Show mesh info
2465 \param mesh mesh object
2466 \param parent parent tree item
2468 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2471 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2472 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2473 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2474 typeItem->setText( 0, tr( "TYPE" ));
2475 if ( !CORBA::is_nil( shape )) {
2476 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ));
2477 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2479 QTreeWidgetItem* gobjItem = createItem( typeItem );
2480 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2481 gobjItem->setText( 1, sobj->GetName().c_str() );
2484 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2485 typeItem->setText( 1, tr( "MESH_FROM_FILE" ));
2486 QTreeWidgetItem* fileItem = createItem( typeItem );
2487 fileItem->setText( 0, tr( "FILE_NAME" ));
2488 fileItem->setText( 1, (char*)inf->fileName );
2491 typeItem->setText( 1, tr( "STANDALONE_MESH" ));
2495 myGroups = mesh->GetGroups();
2499 mySubMeshes = mesh->GetSubMeshes();
2504 \brief Show sub-mesh info
2505 \param subMesh sub-mesh object
2506 \param parent parent tree item
2508 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2510 bool isShort = parent->parent() != 0;
2514 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2516 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2517 nameItem->setText( 0, tr( "PARENT_MESH" ));
2518 nameItem->setText( 1, sobj->GetName().c_str() );
2523 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2524 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2526 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2527 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2528 gobjItem->setText( 1, sobj->GetName().c_str() );
2533 \brief Show group info
2534 \param grp mesh group object
2535 \param parent parent tree item
2537 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2539 bool isShort = parent->parent() != 0;
2541 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2542 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2543 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2547 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2549 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2550 nameItem->setText( 0, tr( "PARENT_MESH" ));
2551 nameItem->setText( 1, sobj->GetName().c_str() );
2555 // type : group on geometry, standalone group, group on filter
2556 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2557 typeItem->setText( 0, tr( "TYPE" ));
2558 if ( !CORBA::is_nil( aStdGroup )) {
2559 typeItem->setText( 1, tr( "STANDALONE_GROUP" ));
2561 else if ( !CORBA::is_nil( aGeomGroup )) {
2562 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ));
2563 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2564 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2566 QTreeWidgetItem* gobjItem = createItem( typeItem );
2567 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2568 gobjItem->setText( 1, sobj->GetName().c_str() );
2571 else if ( !CORBA::is_nil( aFltGroup )) {
2572 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ));
2577 QString etype = tr( "UNKNOWN" );
2578 switch( grp->GetType() ) {
2580 etype = tr( "NODE" );
2583 etype = tr( "EDGE" );
2586 etype = tr( "FACE" );
2589 etype = tr( "VOLUME" );
2592 etype = tr( "0DELEM" );
2595 etype = tr( "BALL" );
2600 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2601 etypeItem->setText( 0, tr( "ENTITY_TYPE" ));
2602 etypeItem->setText( 1, etype );
2605 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2606 bool meshLoaded = mesh->IsLoaded();
2608 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2610 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2611 groupSize = grp->Size();
2613 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2614 sizeItem->setText( 0, tr( "SIZE" ));
2615 if ( groupSize > -1 ) {
2616 sizeItem->setText( 1, QString::number( groupSize ));
2619 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2620 setItemWidget( sizeItem, 1, btn );
2621 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2622 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2623 myComputors.append( comp );
2625 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2629 SALOMEDS::Color color = grp->GetColor();
2630 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2631 colorItem->setText( 0, tr( "COLOR" ));
2632 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2634 // nb of underlying nodes
2635 if ( grp->GetType() != SMESH::NODE) {
2636 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2637 nodesItem->setText( 0, tr( "NB_NODES" ));
2638 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2639 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2640 if ( toShowNodes && meshLoaded ) {
2641 // already calculated and up-to-date
2642 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ));
2645 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2646 setItemWidget( nodesItem, 1, btn );
2647 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2648 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2649 myComputors.append( comp );
2651 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2656 void SMESHGUI_AddInfo::showGroups()
2658 myComputors.clear();
2660 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2661 if ( !parent ) return;
2663 int idx = property( "group_index" ).toInt();
2665 QTreeWidgetItem* itemGroups = 0;
2666 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2667 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2668 itemGroups = parent->child( i );
2669 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ));
2671 extra->updateControls( myGroups->length(), idx );
2672 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2676 QMap<int, QTreeWidgetItem*> grpItems;
2677 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2678 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2679 if ( CORBA::is_nil( grp )) continue;
2680 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2681 if ( !grpSObj ) continue;
2683 int grpType = grp->GetType();
2685 if ( !itemGroups ) {
2686 // create top-level groups container item
2687 itemGroups = createItem( parent, Bold | All );
2688 itemGroups->setText( 0, tr( "GROUPS" ));
2689 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2691 // total number of groups > 10, show extra widgets for info browsing
2692 if ((int) myGroups->length() > MAXITEMS ) {
2693 ExtraWidget* extra = new ExtraWidget( this, true );
2694 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ));
2695 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ));
2696 setItemWidget( itemGroups, 1, extra );
2697 extra->updateControls( myGroups->length(), idx );
2701 if ( grpItems.find( grpType ) == grpItems.end() ) {
2702 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2703 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ));
2704 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2708 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2709 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2712 groupInfo( grp.in(), grpNameItem );
2716 void SMESHGUI_AddInfo::showSubMeshes()
2718 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2719 if ( !parent ) return;
2721 int idx = property( "submesh_index" ).toInt();
2723 QTreeWidgetItem* itemSubMeshes = 0;
2724 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2725 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2726 itemSubMeshes = parent->child( i );
2727 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ));
2729 extra->updateControls( mySubMeshes->length(), idx );
2730 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2734 QMap<int, QTreeWidgetItem*> smItems;
2735 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2736 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2737 if ( CORBA::is_nil( sm )) continue;
2738 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2739 if ( !smSObj ) continue;
2741 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2742 if ( CORBA::is_nil(gobj )) continue;
2744 int smType = gobj->GetShapeType();
2745 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2747 if ( !itemSubMeshes ) {
2748 itemSubMeshes = createItem( parent, Bold | All );
2749 itemSubMeshes->setText( 0, tr( "SUBMESHES" ));
2750 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2752 // total number of sub-meshes > 10, show extra widgets for info browsing
2753 if ((int) mySubMeshes->length() > MAXITEMS ) {
2754 ExtraWidget* extra = new ExtraWidget( this, true );
2755 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ));
2756 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ));
2757 setItemWidget( itemSubMeshes, 1, extra );
2758 extra->updateControls( mySubMeshes->length(), idx );
2762 if ( smItems.find( smType ) == smItems.end() ) {
2763 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2764 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ));
2765 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2769 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2770 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2773 subMeshInfo( sm.in(), smNameItem );
2778 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2780 void SMESHGUI_AddInfo::changeLoadToCompute()
2782 for ( int i = 0; i < myComputors.count(); ++i )
2784 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2786 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 )) )
2787 btn->setText( tr("COMPUTE") );
2792 void SMESHGUI_AddInfo::showPreviousGroups()
2794 int idx = property( "group_index" ).toInt();
2795 setProperty( "group_index", idx-1 );
2799 void SMESHGUI_AddInfo::showNextGroups()
2801 int idx = property( "group_index" ).toInt();
2802 setProperty( "group_index", idx+1 );
2806 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2808 int idx = property( "submesh_index" ).toInt();
2809 setProperty( "submesh_index", idx-1 );
2813 void SMESHGUI_AddInfo::showNextSubMeshes()
2815 int idx = property( "submesh_index" ).toInt();
2816 setProperty( "submesh_index", idx+1 );
2820 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2822 out << QString( 15, '-') << "\n";
2823 out << tr( "ADDITIONAL_INFO" ) << "\n";
2824 out << QString( 15, '-' ) << "\n";
2825 QTreeWidgetItemIterator it( this );
2827 if ( !( ( *it )->text(0) ).isEmpty() ) {
2828 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2829 if ( ( *it )->text(0) == tr( "COLOR" )) {
2830 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2832 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2841 \class SMESHGUI_MeshInfoDlg
2842 \brief Mesh information dialog box
2847 \param parent parent widget
2848 \param page specifies the dialog page to be shown at the start-up
2850 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2851 : QDialog( parent ), myActor( 0 )
2854 setAttribute( Qt::WA_DeleteOnClose, true );
2855 setWindowTitle( tr( "MESH_INFO" ));
2856 setSizeGripEnabled( true );
2858 myTabWidget = new QTabWidget( this );
2862 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2863 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ));
2867 QWidget* w = new QWidget( myTabWidget );
2869 myMode = new QButtonGroup( this );
2870 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2871 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2872 myMode->button( NodeMode )->setChecked( true );
2873 myID = new QLineEdit( w );
2874 myID->setValidator( new SMESHGUI_IdValidator( this ));
2875 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
2876 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
2878 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2879 mode = qMin( 1, qMax( 0, mode ));
2882 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2884 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2886 QGridLayout* elemLayout = new QGridLayout( w );
2887 elemLayout->setMargin( MARGIN );
2888 elemLayout->setSpacing( SPACING );
2889 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2890 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2891 elemLayout->addWidget( myID, 0, 2 );
2892 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 );
2893 elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 );
2895 myTabWidget->addTab( w, tr( "ELEM_INFO" ));
2899 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2900 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ));
2904 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2905 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ));
2909 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2910 okBtn->setAutoDefault( true );
2911 okBtn->setDefault( true );
2913 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2914 dumpBtn->setAutoDefault( true );
2915 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2916 helpBtn->setAutoDefault( true );
2918 QHBoxLayout* btnLayout = new QHBoxLayout;
2919 btnLayout->setSpacing( SPACING );
2920 btnLayout->setMargin( 0 );
2922 btnLayout->addWidget( okBtn );
2923 btnLayout->addWidget( dumpBtn );
2924 btnLayout->addStretch( 10 );
2925 btnLayout->addWidget( helpBtn );
2927 QVBoxLayout* l = new QVBoxLayout ( this );
2928 l->setMargin( MARGIN );
2929 l->setSpacing( SPACING );
2930 l->addWidget( myTabWidget );
2931 l->addLayout( btnLayout );
2933 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page )));
2935 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
2936 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
2937 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
2938 connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() ));
2939 connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() ));
2940 connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() ));
2941 connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) ));
2942 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
2943 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
2944 connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int )));
2945 connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
2947 myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false ));
2955 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2961 \brief Show mesh information
2962 \param IO interactive object
2964 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2969 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2970 if ( !CORBA::is_nil( obj ))
2972 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2973 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2974 if ( myTabWidget->currentIndex() == CtrlInfo )
2975 myCtrlInfo->showInfo( obj );
2978 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2979 SVTK_Selector* selector = SMESH::GetSelector();
2982 if ( myActor && selector ) {
2983 nb = myMode->checkedId() == NodeMode ?
2984 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2985 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2987 myElemInfo->setSource( myActor ) ;
2989 myID->setText( ID.trimmed() );
2991 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2992 foreach ( ID, idTxt )
2993 ids << ID.trimmed().toLong();
2994 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2998 myElemInfo->clear();
3005 \brief Perform clean-up actions on the dialog box closing.
3007 void SMESHGUI_MeshInfoDlg::reject()
3009 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3010 selMgr->clearFilters();
3011 SMESH::SetPointRepresentation( false );
3012 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3013 aViewWindow->SetSelectionMode( ActorSelection );
3015 myIDPreview->SetPointsLabeled(false);
3019 \brief Process keyboard event
3020 \param e key press event
3022 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3024 QDialog::keyPressEvent( e );
3025 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3032 \brief Reactivate dialog box, when mouse pointer goes into it.
3034 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3040 \brief Setup selection mode depending on the current dialog box state.
3042 void SMESHGUI_MeshInfoDlg::updateSelection()
3044 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3046 disconnect( selMgr, 0, this, 0 );
3047 selMgr->clearFilters();
3049 if ( myTabWidget->currentIndex() == BaseInfo ||
3050 myTabWidget->currentIndex() == AddInfo ||
3051 myTabWidget->currentIndex() == CtrlInfo ) {
3052 SMESH::SetPointRepresentation( false );
3053 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3054 aViewWindow->SetSelectionMode( ActorSelection );
3057 if ( myMode->checkedId() == NodeMode ) {
3058 SMESH::SetPointRepresentation( true );
3059 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3060 aViewWindow->SetSelectionMode( NodeSelection );
3063 SMESH::SetPointRepresentation( false );
3064 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3065 aViewWindow->SetSelectionMode( CellSelection );
3069 QString oldID = myID->text().trimmed();
3070 SMESH_Actor* oldActor = myActor;
3073 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3076 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3077 myID->setText( oldID );
3083 \brief Show help page
3085 void SMESHGUI_MeshInfoDlg::help()
3087 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3088 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3089 "mesh_infos_page.html#mesh_element_info_anchor" );
3093 \brief Show mesh information
3095 void SMESHGUI_MeshInfoDlg::updateInfo()
3097 SUIT_OverrideCursor wc;
3099 SALOME_ListIO selected;
3100 SMESHGUI::selectionMgr()->selectedObjects( selected );
3102 if ( selected.Extent() == 1 ) {
3103 Handle(SALOME_InteractiveObject) IO = selected.First();
3112 \brief Activate dialog box
3114 void SMESHGUI_MeshInfoDlg::activate()
3116 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3117 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3118 myTabWidget->setEnabled( true );
3123 \brief Deactivate dialog box
3125 void SMESHGUI_MeshInfoDlg::deactivate()
3127 myTabWidget->setEnabled( false );
3128 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3132 \brief Called when users switches between node / element modes.
3134 void SMESHGUI_MeshInfoDlg::modeChanged()
3141 \brief Called when users prints mesh element ID in the corresponding field.
3143 void SMESHGUI_MeshInfoDlg::idChanged()
3145 myIDPreview->SetPointsLabeled( false );
3147 SVTK_Selector* selector = SMESH::GetSelector();
3148 if ( myActor && selector ) {
3149 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3150 TColStd_MapOfInteger ID;
3152 std::vector<int> idVec;
3153 std::list< gp_XYZ > aGrCentersXYZ;
3154 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3155 foreach ( QString tid, idTxt ) {
3156 long id = tid.trimmed().toLong();
3157 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3158 myActor->GetObject()->GetMesh()->FindElement( id ) :
3159 myActor->GetObject()->GetMesh()->FindNode( id );
3163 if ( myMode->checkedId() == ElemMode )
3165 idVec.push_back( id );
3166 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ));
3170 selector->AddOrRemoveIndex( IO, ID, false );
3171 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3173 if ( myMode->checkedId() == NodeMode )
3174 myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID );
3176 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3178 bool showIDs = ( !ID.IsEmpty() &&
3179 myIDPreviewCheck->isChecked() &&
3180 myTabWidget->currentIndex() == ElemInfo );
3181 myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() );
3183 aViewWindow->highlight( IO, true, true );
3184 aViewWindow->Repaint();
3186 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3191 * \brief Show IDs clicked
3193 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3195 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3196 SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn );
3197 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3198 aViewWindow->Repaint();
3201 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3203 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) {
3204 myMode->button( NodeMode )->click();
3205 myID->setText( QString::number( id ));
3209 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3211 if ( !theStr.isEmpty() ) {
3212 myMode->button( ElemMode )->click();
3213 myID->setText( theStr );
3217 void SMESHGUI_MeshInfoDlg::dump()
3219 QStringList aFilters;
3220 aFilters.append( tr( "TEXT_FILES" ));
3222 bool anIsBase = true;
3223 bool anIsElem = true;
3224 bool anIsAdd = true;
3225 bool anIsCtrl = true;
3227 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3228 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3229 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3230 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3231 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3234 DumpFileDlg fd( this );
3235 fd.setWindowTitle( tr( "SAVE_INFO" ));
3236 fd.setNameFilters( aFilters );
3237 fd.myBaseChk->setChecked( anIsBase );
3238 fd.myElemChk->setChecked( anIsElem );
3239 fd.myAddChk ->setChecked( anIsAdd );
3240 fd.myCtrlChk->setChecked( anIsCtrl );
3241 if ( fd.exec() == QDialog::Accepted )
3243 QString aFileName = fd.selectedFile();
3245 bool toBase = fd.myBaseChk->isChecked();
3246 bool toElem = fd.myElemChk->isChecked();
3247 bool toAdd = fd.myAddChk->isChecked();
3248 bool toCtrl = fd.myCtrlChk->isChecked();
3250 if ( !aFileName.isEmpty() ) {
3251 QFileInfo aFileInfo( aFileName );
3252 if ( aFileInfo.isDir() )
3255 QFile aFile( aFileName );
3256 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3259 QTextStream out( &aFile );
3261 if ( toBase ) myBaseInfo->saveInfo( out );
3262 if ( toElem ) myElemInfo->saveInfo( out );
3263 if ( toAdd ) myAddInfo ->saveInfo( out );
3264 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3270 \class SMESHGUI_CtrlInfo
3271 \brief Class for the mesh controls information widget.
3276 \param parent parent widget
3278 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3279 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3281 setFrameStyle( StyledPanel | Sunken );
3283 myMainLayout = new QGridLayout( this );
3284 myMainLayout->setMargin( MARGIN );
3285 myMainLayout->setSpacing( SPACING );
3288 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3289 QLabel* aName = createField();
3290 aName->setMinimumWidth( 150 );
3293 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3294 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) );
3296 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3299 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3300 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3301 QLabel* aNodesFree = createField();
3302 myWidgets << aNodesFree;
3303 myPredicates << aFilterMgr->CreateFreeNodes();
3305 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3306 QLabel* aNodesNbConn = createField();
3307 myWidgets << aNodesNbConn;
3308 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3310 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3311 QLabel* aNodesDouble = createField();
3312 myWidgets << aNodesDouble;
3313 myPredicates << aFilterMgr->CreateEqualNodes();
3314 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3315 myToleranceWidget = new SMESHGUI_SpinBox( this );
3316 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3317 myToleranceWidget->setAcceptNames( false );
3318 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ));
3321 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3322 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3323 QLabel* anEdgesDouble = createField();
3324 myWidgets << anEdgesDouble;
3325 myPredicates << aFilterMgr->CreateEqualEdges();
3328 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3329 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3330 QLabel* aFacesDouble = createField();
3331 myWidgets << aFacesDouble;
3332 myPredicates << aFilterMgr->CreateEqualFaces();
3333 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3334 QLabel* aFacesOver = createField();
3335 myWidgets << aFacesOver;
3336 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3337 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3338 myPlot = createPlot( this );
3339 myAspectRatio = aFilterMgr->CreateAspectRatio();
3342 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3343 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3344 QLabel* aVolumesDouble = createField();
3345 myWidgets << aVolumesDouble;
3346 myPredicates << aFilterMgr->CreateEqualVolumes();
3347 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3348 QLabel* aVolumesOver = createField();
3349 myWidgets << aVolumesOver;
3350 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3351 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3352 myPlot3D = createPlot( this );
3353 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3355 QToolButton* aFreeNodesBtn = new QToolButton( this );
3356 aFreeNodesBtn->setIcon(aComputeIcon);
3357 myButtons << aFreeNodesBtn; //0
3359 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3360 aNodesNbConnBtn->setIcon(aComputeIcon);
3361 myButtons << aNodesNbConnBtn; //1
3363 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3364 aDoubleNodesBtn->setIcon(aComputeIcon);
3365 myButtons << aDoubleNodesBtn; //2
3367 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3368 aDoubleEdgesBtn->setIcon(aComputeIcon);
3369 myButtons << aDoubleEdgesBtn; //3
3371 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3372 aDoubleFacesBtn->setIcon(aComputeIcon);
3373 myButtons << aDoubleFacesBtn; //4
3375 QToolButton* aOverContFacesBtn = new QToolButton( this );
3376 aOverContFacesBtn->setIcon(aComputeIcon);
3377 myButtons << aOverContFacesBtn; //5
3379 QToolButton* aComputeFaceBtn = new QToolButton( this );
3380 aComputeFaceBtn->setIcon(aComputeIcon);
3381 myButtons << aComputeFaceBtn; //6
3383 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3384 aDoubleVolumesBtn->setIcon(aComputeIcon);
3385 myButtons << aDoubleVolumesBtn; //7
3387 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3388 aOverContVolumesBtn->setIcon(aComputeIcon);
3389 myButtons << aOverContVolumesBtn; //8
3391 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3392 aComputeVolumeBtn->setIcon(aComputeIcon);
3393 myButtons << aComputeVolumeBtn; //9
3395 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ));
3396 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ));
3397 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ));
3398 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ));
3399 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ));
3400 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ));
3401 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ));
3402 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ));
3403 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ));
3404 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ));
3405 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3407 setFontAttributes( aNameLab );
3408 setFontAttributes( aNodesLab );
3409 setFontAttributes( anEdgesLab );
3410 setFontAttributes( aFacesLab );
3411 setFontAttributes( aVolumesLab );
3413 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3414 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3415 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3416 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3417 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3418 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3419 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3420 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3421 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3422 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3423 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3424 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3425 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3426 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3427 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3428 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3429 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3430 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3431 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3432 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3433 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3434 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3435 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3436 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3437 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3438 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3439 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3440 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3441 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3442 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3443 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3444 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3445 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3446 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3447 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3448 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3449 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3450 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3452 myMainLayout->setColumnStretch( 0, 0 );
3453 myMainLayout->setColumnStretch( 1, 5 );
3454 myMainLayout->setRowStretch ( 11, 5 );
3455 myMainLayout->setRowStretch ( 16, 5 );
3456 myMainLayout->setRowStretch ( 17, 1 );
3464 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3468 \brief Change widget font attributes (bold, ...).
3470 \param attr font attributes (XORed flags)
3472 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3475 QFont f = w->font();
3482 \brief Create info field
3483 \return new info field
3485 QLabel* SMESHGUI_CtrlInfo::createField()
3487 QLabel* lab = new QLabel( this );
3488 lab->setFrameStyle( StyledPanel | Sunken );
3489 lab->setAlignment( Qt::AlignCenter );
3490 lab->setAutoFillBackground( true );
3491 QPalette pal = lab->palette();
3492 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
3493 lab->setPalette( pal );
3494 lab->setMinimumWidth( 60 );
3499 \brief Create QwtPlot
3502 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3504 QwtPlot* aPlot = new QwtPlot( parent );
3505 aPlot->setMinimumSize( 100, 100 );
3506 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3507 xFont.setPointSize( 5 );
3508 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3509 yFont.setPointSize( 5 );
3510 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3511 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3517 \brief Show controls information on the selected object
3519 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3523 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3524 if ( myObject->_is_nil() ) return;
3526 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3527 myWidgets[0]->setText( aSO->GetName().c_str() );
3529 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3530 if ( mesh->_is_nil() ) return;
3532 const bool meshLoaded = mesh->IsLoaded();
3533 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3534 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3535 for ( int i = 0; i < myButtons.count(); ++i )
3536 myButtons[i]->setEnabled( true );
3538 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3539 if ( ! &nbElemsByType.in() ) return;
3541 const CORBA::Long ctrlLimit =
3542 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3545 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3546 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3547 nbElemsByType[ SMESH::FACE ] +
3548 nbElemsByType[ SMESH::VOLUME ] );
3549 if ( nbNodes + nbElems > 0 ) {
3550 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3552 computeFreeNodesInfo();
3553 computeNodesNbConnInfo();
3555 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3556 computeDoubleNodesInfo();
3559 myButtons[0]->setEnabled( true );
3560 myButtons[1]->setEnabled( true );
3561 myButtons[2]->setEnabled( true );
3565 for( int i=2; i<=11; i++)
3566 myMainLayout->itemAt(i)->widget()->setVisible( false );
3570 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3572 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3573 computeDoubleEdgesInfo();
3575 myButtons[3]->setEnabled( true );
3578 for( int i=11; i<=14; i++)
3579 myMainLayout->itemAt(i)->widget()->setVisible( false );
3583 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3584 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3586 computeDoubleFacesInfo();
3587 // over constrained faces
3588 computeOverConstrainedFacesInfo();
3589 // aspect Ratio histogram
3590 computeAspectRatio();
3593 myButtons[4]->setEnabled( true );
3594 myButtons[5]->setEnabled( true );
3595 myButtons[6]->setEnabled( true );
3597 #ifdef DISABLE_PLOT2DVIEWER
3598 myMainLayout->setRowStretch(12,0);
3599 for( int i=25; i<=27; i++)
3600 myMainLayout->itemAt(i)->widget()->setVisible( false );
3604 myMainLayout->setRowStretch(12,0);
3605 for( int i=18; i<=27; i++)
3606 myMainLayout->itemAt(i)->widget()->setVisible( false );
3610 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3611 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3613 computeDoubleVolumesInfo();
3614 // over constrained volumes
3615 computeOverConstrainedVolumesInfo();
3616 // aspect Ratio 3D histogram
3617 computeAspectRatio3D();
3620 myButtons[7]->setEnabled( true );
3621 myButtons[8]->setEnabled( true );
3622 myButtons[9]->setEnabled( true );
3624 #ifdef DISABLE_PLOT2DVIEWER
3625 myMainLayout->setRowStretch(17,0);
3626 for( int i=35; i<=37; i++)
3627 myMainLayout->itemAt(i)->widget()->setVisible( false );
3631 myMainLayout->setRowStretch(17,0);
3632 for( int i=28; i<=37; i++)
3633 myMainLayout->itemAt(i)->widget()->setVisible( false );
3637 //================================================================================
3639 * \brief Computes and shows nb of elements satisfying a given predicate
3640 * \param [in] ft - a predicate type (SMESH::FunctorType)
3641 * \param [in] iBut - index of one of myButtons to disable
3642 * \param [in] iWdg - index of one of myWidgets to show the computed number
3644 //================================================================================
3646 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3648 myButtons[ iBut ]->setEnabled( false );
3649 myWidgets[ iWdg ]->setText( "" );
3650 if ( myObject->_is_nil() ) return;
3652 SUIT_OverrideCursor wc;
3654 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3655 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3658 this->showInfo( myObject ); // try to show all values
3659 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3660 return; // <ft> predicate already computed
3662 // look for a predicate of type <ft>
3663 for ( int i = 0; i < myPredicates.count(); ++i )
3664 if ( myPredicates[i]->GetFunctorType() == ft )
3666 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3667 myWidgets[ iWdg ]->setText( QString::number( nb ));
3671 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3673 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3676 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3678 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3681 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3683 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3686 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3688 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3691 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3693 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3696 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3698 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3701 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3703 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3706 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3708 myButtons[ 1 ]->setEnabled( false );
3709 myWidgets[ 2 ]->setText( "" );
3710 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3711 if ( mesh->_is_nil() ) return;
3712 if ( !mesh->IsLoaded() )
3715 this->showInfo( myObject ); // try to show all values
3716 if ( !myWidgets[ 2 ]->text().isEmpty() )
3717 return; // already computed
3719 myNodeConnFunctor->SetMesh( mesh );
3720 SMESH::Histogram_var histogram =
3721 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3723 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3726 void SMESHGUI_CtrlInfo::computeAspectRatio()
3728 #ifndef DISABLE_PLOT2DVIEWER
3729 myButtons[6]->setEnabled( false );
3731 if ( myObject->_is_nil() ) return;
3733 SUIT_OverrideCursor wc;
3735 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3736 if ( aHistogram && !aHistogram->isEmpty() ) {
3737 QwtPlotItem* anItem = aHistogram->createPlotItem();
3738 anItem->attach( myPlot );
3745 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3747 #ifndef DISABLE_PLOT2DVIEWER
3748 myButtons[9]->setEnabled( false );
3750 if ( myObject->_is_nil() ) return;
3752 SUIT_OverrideCursor wc;
3754 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3755 if ( aHistogram && !aHistogram->isEmpty() ) {
3756 QwtPlotItem* anItem = aHistogram->createPlotItem();
3757 anItem->attach( myPlot3D );
3765 \brief Internal clean-up (reset widget)
3767 void SMESHGUI_CtrlInfo::clearInternal()
3769 for( int i=0; i<=35; i++)
3770 myMainLayout->itemAt(i)->widget()->setVisible( true );
3771 for( int i=0; i<=9; i++)
3772 myButtons[i]->setEnabled( false );
3773 myPlot->detachItems();
3774 myPlot3D->detachItems();
3777 myWidgets[0]->setText( QString() );
3778 for ( int i = 1; i < myWidgets.count(); i++ )
3779 myWidgets[i]->setText( "" );
3780 myMainLayout->setRowStretch(11,5);
3781 myMainLayout->setRowStretch(16,5);
3784 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3786 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3787 myButtons[1]->setEnabled( true );
3788 myWidgets[2]->setText("");
3791 #ifndef DISABLE_PLOT2DVIEWER
3792 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3794 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3795 if ( mesh->_is_nil() ) return 0;
3796 if ( !mesh->IsLoaded() )
3798 aNumFun->SetMesh( mesh );
3800 CORBA::Long cprecision = 6;
3801 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
3802 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3803 aNumFun->SetPrecision( cprecision );
3805 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3807 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3808 /*isLogarithmic=*/false,
3810 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3811 aHistogram->setColor( palette().color( QPalette::Highlight ));
3812 if ( &histogramVar.in() )
3814 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3815 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3816 if ( histogramVar->length() >= 2 )
3817 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3823 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3824 out << QString( 20, '-' ) << "\n";
3825 out << tr( "CTRL_INFO" ) << "\n";
3826 out << QString( 20, '-' ) << "\n";
3827 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3828 out << tr( "NODES_INFO" ) << "\n";
3829 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3830 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3831 out << tr( "EDGES_INFO" ) << "\n";
3832 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3833 out << tr( "FACES_INFO" ) << "\n";
3834 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3835 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3836 out << tr( "VOLUMES_INFO" ) << "\n";
3837 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3838 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3842 \class SMESHGUI_CtrlInfoDlg
3843 \brief Controls information dialog box
3848 \param parent parent widget
3850 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3853 setAttribute( Qt::WA_DeleteOnClose, true );
3854 setWindowTitle( tr( "CTRL_INFO" ));
3855 setMinimumSize( 400, 600 );
3857 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3860 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3861 okBtn->setAutoDefault( true );
3862 okBtn->setDefault( true );
3864 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3865 dumpBtn->setAutoDefault( true );
3866 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3867 helpBtn->setAutoDefault( true );
3869 QHBoxLayout* btnLayout = new QHBoxLayout;
3870 btnLayout->setSpacing( SPACING );
3871 btnLayout->setMargin( 0 );
3873 btnLayout->addWidget( okBtn );
3874 btnLayout->addWidget( dumpBtn );
3875 btnLayout->addStretch( 10 );
3876 btnLayout->addWidget( helpBtn );
3878 QVBoxLayout* l = new QVBoxLayout ( this );
3879 l->setMargin( MARGIN );
3880 l->setSpacing( SPACING );
3881 l->addWidget( myCtrlInfo );
3882 l->addLayout( btnLayout );
3884 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
3885 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
3886 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
3887 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
3888 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
3896 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3901 \brief Show controls information
3902 \param IO interactive object
3904 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3906 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ))
3907 myCtrlInfo->showInfo( obj );
3911 \brief Perform clean-up actions on the dialog box closing.
3913 void SMESHGUI_CtrlInfoDlg::reject()
3915 SMESH::SetPointRepresentation( false );
3920 \brief Setup selection mode depending on the current dialog box state.
3922 void SMESHGUI_CtrlInfoDlg::updateSelection()
3924 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3925 disconnect( selMgr, 0, this, 0 );
3926 SMESH::SetPointRepresentation( false );
3927 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3932 \brief Show mesh information
3934 void SMESHGUI_CtrlInfoDlg::updateInfo()
3936 SUIT_OverrideCursor wc;
3938 SALOME_ListIO selected;
3939 SMESHGUI::selectionMgr()->selectedObjects( selected );
3941 if ( selected.Extent() == 1 ) {
3942 Handle(SALOME_InteractiveObject) IO = selected.First();
3948 \brief Activate dialog box
3950 void SMESHGUI_CtrlInfoDlg::activate()
3952 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3953 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3958 \brief Deactivate dialog box
3960 void SMESHGUI_CtrlInfoDlg::deactivate()
3962 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3966 * \brief Dump contents into a file
3968 void SMESHGUI_CtrlInfoDlg::dump()
3970 QStringList aFilters;
3971 aFilters.append( tr( "TEXT_FILES" ));
3973 DumpFileDlg fd( this );
3974 fd.setWindowTitle( tr( "SAVE_INFO" ));
3975 fd.setNameFilters( aFilters );
3976 fd.myBaseChk->hide();
3977 fd.myElemChk->hide();
3978 fd.myAddChk ->hide();
3979 fd.myCtrlChk->hide();
3980 if ( fd.exec() == QDialog::Accepted )
3982 QString aFileName = fd.selectedFile();
3983 if ( !aFileName.isEmpty() ) {
3984 QFileInfo aFileInfo( aFileName );
3985 if ( aFileInfo.isDir() )
3988 QFile aFile( aFileName );
3989 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3992 QTextStream out( &aFile );
3993 myCtrlInfo->saveInfo( out );
4001 void SMESHGUI_CtrlInfoDlg::help()
4003 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");