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 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3221 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3222 if ( !appStudy ) return;
3223 _PTR( Study ) aStudy = appStudy->studyDS();
3225 QStringList aFilters;
3226 aFilters.append( tr( "TEXT_FILES" ));
3228 bool anIsBase = true;
3229 bool anIsElem = true;
3230 bool anIsAdd = true;
3231 bool anIsCtrl = true;
3233 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3234 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3235 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3236 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3237 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3240 DumpFileDlg fd( this );
3241 fd.setWindowTitle( tr( "SAVE_INFO" ));
3242 fd.setNameFilters( aFilters );
3243 fd.myBaseChk->setChecked( anIsBase );
3244 fd.myElemChk->setChecked( anIsElem );
3245 fd.myAddChk ->setChecked( anIsAdd );
3246 fd.myCtrlChk->setChecked( anIsCtrl );
3247 if ( fd.exec() == QDialog::Accepted )
3249 QString aFileName = fd.selectedFile();
3251 bool toBase = fd.myBaseChk->isChecked();
3252 bool toElem = fd.myElemChk->isChecked();
3253 bool toAdd = fd.myAddChk->isChecked();
3254 bool toCtrl = fd.myCtrlChk->isChecked();
3256 if ( !aFileName.isEmpty() ) {
3257 QFileInfo aFileInfo( aFileName );
3258 if ( aFileInfo.isDir() )
3261 QFile aFile( aFileName );
3262 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3265 QTextStream out( &aFile );
3267 if ( toBase ) myBaseInfo->saveInfo( out );
3268 if ( toElem ) myElemInfo->saveInfo( out );
3269 if ( toAdd ) myAddInfo ->saveInfo( out );
3270 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3276 \class SMESHGUI_CtrlInfo
3277 \brief Class for the mesh controls information widget.
3282 \param parent parent widget
3284 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3285 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3287 setFrameStyle( StyledPanel | Sunken );
3289 myMainLayout = new QGridLayout( this );
3290 myMainLayout->setMargin( MARGIN );
3291 myMainLayout->setSpacing( SPACING );
3294 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3295 QLabel* aName = createField();
3296 aName->setMinimumWidth( 150 );
3299 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3300 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) );
3302 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3305 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3306 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3307 QLabel* aNodesFree = createField();
3308 myWidgets << aNodesFree;
3309 myPredicates << aFilterMgr->CreateFreeNodes();
3311 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3312 QLabel* aNodesNbConn = createField();
3313 myWidgets << aNodesNbConn;
3314 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3316 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3317 QLabel* aNodesDouble = createField();
3318 myWidgets << aNodesDouble;
3319 myPredicates << aFilterMgr->CreateEqualNodes();
3320 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3321 myToleranceWidget = new SMESHGUI_SpinBox( this );
3322 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3323 myToleranceWidget->setAcceptNames( false );
3324 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ));
3327 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3328 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3329 QLabel* anEdgesDouble = createField();
3330 myWidgets << anEdgesDouble;
3331 myPredicates << aFilterMgr->CreateEqualEdges();
3334 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3335 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3336 QLabel* aFacesDouble = createField();
3337 myWidgets << aFacesDouble;
3338 myPredicates << aFilterMgr->CreateEqualFaces();
3339 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3340 QLabel* aFacesOver = createField();
3341 myWidgets << aFacesOver;
3342 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3343 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3344 myPlot = createPlot( this );
3345 myAspectRatio = aFilterMgr->CreateAspectRatio();
3348 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3349 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3350 QLabel* aVolumesDouble = createField();
3351 myWidgets << aVolumesDouble;
3352 myPredicates << aFilterMgr->CreateEqualVolumes();
3353 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3354 QLabel* aVolumesOver = createField();
3355 myWidgets << aVolumesOver;
3356 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3357 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3358 myPlot3D = createPlot( this );
3359 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3361 QToolButton* aFreeNodesBtn = new QToolButton( this );
3362 aFreeNodesBtn->setIcon(aComputeIcon);
3363 myButtons << aFreeNodesBtn; //0
3365 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3366 aNodesNbConnBtn->setIcon(aComputeIcon);
3367 myButtons << aNodesNbConnBtn; //1
3369 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3370 aDoubleNodesBtn->setIcon(aComputeIcon);
3371 myButtons << aDoubleNodesBtn; //2
3373 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3374 aDoubleEdgesBtn->setIcon(aComputeIcon);
3375 myButtons << aDoubleEdgesBtn; //3
3377 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3378 aDoubleFacesBtn->setIcon(aComputeIcon);
3379 myButtons << aDoubleFacesBtn; //4
3381 QToolButton* aOverContFacesBtn = new QToolButton( this );
3382 aOverContFacesBtn->setIcon(aComputeIcon);
3383 myButtons << aOverContFacesBtn; //5
3385 QToolButton* aComputeFaceBtn = new QToolButton( this );
3386 aComputeFaceBtn->setIcon(aComputeIcon);
3387 myButtons << aComputeFaceBtn; //6
3389 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3390 aDoubleVolumesBtn->setIcon(aComputeIcon);
3391 myButtons << aDoubleVolumesBtn; //7
3393 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3394 aOverContVolumesBtn->setIcon(aComputeIcon);
3395 myButtons << aOverContVolumesBtn; //8
3397 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3398 aComputeVolumeBtn->setIcon(aComputeIcon);
3399 myButtons << aComputeVolumeBtn; //9
3401 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ));
3402 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ));
3403 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ));
3404 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ));
3405 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ));
3406 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ));
3407 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ));
3408 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ));
3409 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ));
3410 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ));
3411 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3413 setFontAttributes( aNameLab );
3414 setFontAttributes( aNodesLab );
3415 setFontAttributes( anEdgesLab );
3416 setFontAttributes( aFacesLab );
3417 setFontAttributes( aVolumesLab );
3419 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3420 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3421 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3422 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3423 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3424 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3425 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3426 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3427 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3428 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3429 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3430 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3431 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3432 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3433 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3434 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3435 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3436 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3437 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3438 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3439 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3440 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3441 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3442 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3443 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3444 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3445 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3446 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3447 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3448 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3449 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3450 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3451 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3452 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3453 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3454 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3455 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3456 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3458 myMainLayout->setColumnStretch( 0, 0 );
3459 myMainLayout->setColumnStretch( 1, 5 );
3460 myMainLayout->setRowStretch ( 11, 5 );
3461 myMainLayout->setRowStretch ( 16, 5 );
3462 myMainLayout->setRowStretch ( 17, 1 );
3470 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3474 \brief Change widget font attributes (bold, ...).
3476 \param attr font attributes (XORed flags)
3478 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3481 QFont f = w->font();
3488 \brief Create info field
3489 \return new info field
3491 QLabel* SMESHGUI_CtrlInfo::createField()
3493 QLabel* lab = new QLabel( this );
3494 lab->setFrameStyle( StyledPanel | Sunken );
3495 lab->setAlignment( Qt::AlignCenter );
3496 lab->setAutoFillBackground( true );
3497 QPalette pal = lab->palette();
3498 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
3499 lab->setPalette( pal );
3500 lab->setMinimumWidth( 60 );
3505 \brief Create QwtPlot
3508 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3510 QwtPlot* aPlot = new QwtPlot( parent );
3511 aPlot->setMinimumSize( 100, 100 );
3512 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3513 xFont.setPointSize( 5 );
3514 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3515 yFont.setPointSize( 5 );
3516 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3517 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3523 \brief Show controls information on the selected object
3525 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3529 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3530 if ( myObject->_is_nil() ) return;
3532 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3533 myWidgets[0]->setText( aSO->GetName().c_str() );
3535 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3536 if ( mesh->_is_nil() ) return;
3538 const bool meshLoaded = mesh->IsLoaded();
3539 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3540 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3541 for ( int i = 0; i < myButtons.count(); ++i )
3542 myButtons[i]->setEnabled( true );
3544 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3545 if ( ! &nbElemsByType.in() ) return;
3547 const CORBA::Long ctrlLimit =
3548 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3551 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3552 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3553 nbElemsByType[ SMESH::FACE ] +
3554 nbElemsByType[ SMESH::VOLUME ] );
3555 if ( nbNodes + nbElems > 0 ) {
3556 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3558 computeFreeNodesInfo();
3559 computeNodesNbConnInfo();
3561 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3562 computeDoubleNodesInfo();
3565 myButtons[0]->setEnabled( true );
3566 myButtons[1]->setEnabled( true );
3567 myButtons[2]->setEnabled( true );
3571 for( int i=2; i<=11; i++)
3572 myMainLayout->itemAt(i)->widget()->setVisible( false );
3576 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3578 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3579 computeDoubleEdgesInfo();
3581 myButtons[3]->setEnabled( true );
3584 for( int i=11; i<=14; i++)
3585 myMainLayout->itemAt(i)->widget()->setVisible( false );
3589 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3590 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3592 computeDoubleFacesInfo();
3593 // over constrained faces
3594 computeOverConstrainedFacesInfo();
3595 // aspect Ratio histogram
3596 computeAspectRatio();
3599 myButtons[4]->setEnabled( true );
3600 myButtons[5]->setEnabled( true );
3601 myButtons[6]->setEnabled( true );
3603 #ifdef DISABLE_PLOT2DVIEWER
3604 myMainLayout->setRowStretch(12,0);
3605 for( int i=25; i<=27; i++)
3606 myMainLayout->itemAt(i)->widget()->setVisible( false );
3610 myMainLayout->setRowStretch(12,0);
3611 for( int i=18; i<=27; i++)
3612 myMainLayout->itemAt(i)->widget()->setVisible( false );
3616 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3617 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3619 computeDoubleVolumesInfo();
3620 // over constrained volumes
3621 computeOverConstrainedVolumesInfo();
3622 // aspect Ratio 3D histogram
3623 computeAspectRatio3D();
3626 myButtons[7]->setEnabled( true );
3627 myButtons[8]->setEnabled( true );
3628 myButtons[9]->setEnabled( true );
3630 #ifdef DISABLE_PLOT2DVIEWER
3631 myMainLayout->setRowStretch(17,0);
3632 for( int i=35; i<=37; i++)
3633 myMainLayout->itemAt(i)->widget()->setVisible( false );
3637 myMainLayout->setRowStretch(17,0);
3638 for( int i=28; i<=37; i++)
3639 myMainLayout->itemAt(i)->widget()->setVisible( false );
3643 //================================================================================
3645 * \brief Computes and shows nb of elements satisfying a given predicate
3646 * \param [in] ft - a predicate type (SMESH::FunctorType)
3647 * \param [in] iBut - index of one of myButtons to disable
3648 * \param [in] iWdg - index of one of myWidgets to show the computed number
3650 //================================================================================
3652 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3654 myButtons[ iBut ]->setEnabled( false );
3655 myWidgets[ iWdg ]->setText( "" );
3656 if ( myObject->_is_nil() ) return;
3658 SUIT_OverrideCursor wc;
3660 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3661 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3664 this->showInfo( myObject ); // try to show all values
3665 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3666 return; // <ft> predicate already computed
3668 // look for a predicate of type <ft>
3669 for ( int i = 0; i < myPredicates.count(); ++i )
3670 if ( myPredicates[i]->GetFunctorType() == ft )
3672 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3673 myWidgets[ iWdg ]->setText( QString::number( nb ));
3677 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3679 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3682 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3684 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3687 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3689 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3692 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3694 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3697 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3699 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3702 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3704 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3707 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3709 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3712 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3714 myButtons[ 1 ]->setEnabled( false );
3715 myWidgets[ 2 ]->setText( "" );
3716 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3717 if ( mesh->_is_nil() ) return;
3718 if ( !mesh->IsLoaded() )
3721 this->showInfo( myObject ); // try to show all values
3722 if ( !myWidgets[ 2 ]->text().isEmpty() )
3723 return; // already computed
3725 myNodeConnFunctor->SetMesh( mesh );
3726 SMESH::Histogram_var histogram =
3727 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3729 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3732 void SMESHGUI_CtrlInfo::computeAspectRatio()
3734 #ifndef DISABLE_PLOT2DVIEWER
3735 myButtons[6]->setEnabled( false );
3737 if ( myObject->_is_nil() ) return;
3739 SUIT_OverrideCursor wc;
3741 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3742 if ( aHistogram && !aHistogram->isEmpty() ) {
3743 QwtPlotItem* anItem = aHistogram->createPlotItem();
3744 anItem->attach( myPlot );
3751 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3753 #ifndef DISABLE_PLOT2DVIEWER
3754 myButtons[9]->setEnabled( false );
3756 if ( myObject->_is_nil() ) return;
3758 SUIT_OverrideCursor wc;
3760 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3761 if ( aHistogram && !aHistogram->isEmpty() ) {
3762 QwtPlotItem* anItem = aHistogram->createPlotItem();
3763 anItem->attach( myPlot3D );
3771 \brief Internal clean-up (reset widget)
3773 void SMESHGUI_CtrlInfo::clearInternal()
3775 for( int i=0; i<=35; i++)
3776 myMainLayout->itemAt(i)->widget()->setVisible( true );
3777 for( int i=0; i<=9; i++)
3778 myButtons[i]->setEnabled( false );
3779 myPlot->detachItems();
3780 myPlot3D->detachItems();
3783 myWidgets[0]->setText( QString() );
3784 for ( int i = 1; i < myWidgets.count(); i++ )
3785 myWidgets[i]->setText( "" );
3786 myMainLayout->setRowStretch(11,5);
3787 myMainLayout->setRowStretch(16,5);
3790 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3792 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3793 myButtons[1]->setEnabled( true );
3794 myWidgets[2]->setText("");
3797 #ifndef DISABLE_PLOT2DVIEWER
3798 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3800 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3801 if ( mesh->_is_nil() ) return 0;
3802 if ( !mesh->IsLoaded() )
3804 aNumFun->SetMesh( mesh );
3806 CORBA::Long cprecision = 6;
3807 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
3808 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3809 aNumFun->SetPrecision( cprecision );
3811 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3813 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3814 /*isLogarithmic=*/false,
3816 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3817 aHistogram->setColor( palette().color( QPalette::Highlight ));
3818 if ( &histogramVar.in() )
3820 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3821 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3822 if ( histogramVar->length() >= 2 )
3823 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3829 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3830 out << QString( 20, '-' ) << "\n";
3831 out << tr( "CTRL_INFO" ) << "\n";
3832 out << QString( 20, '-' ) << "\n";
3833 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3834 out << tr( "NODES_INFO" ) << "\n";
3835 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3836 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3837 out << tr( "EDGES_INFO" ) << "\n";
3838 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3839 out << tr( "FACES_INFO" ) << "\n";
3840 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3841 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3842 out << tr( "VOLUMES_INFO" ) << "\n";
3843 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3844 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3848 \class SMESHGUI_CtrlInfoDlg
3849 \brief Controls information dialog box
3854 \param parent parent widget
3856 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3859 setAttribute( Qt::WA_DeleteOnClose, true );
3860 setWindowTitle( tr( "CTRL_INFO" ));
3861 setMinimumSize( 400, 600 );
3863 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3866 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3867 okBtn->setAutoDefault( true );
3868 okBtn->setDefault( true );
3870 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3871 dumpBtn->setAutoDefault( true );
3872 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3873 helpBtn->setAutoDefault( true );
3875 QHBoxLayout* btnLayout = new QHBoxLayout;
3876 btnLayout->setSpacing( SPACING );
3877 btnLayout->setMargin( 0 );
3879 btnLayout->addWidget( okBtn );
3880 btnLayout->addWidget( dumpBtn );
3881 btnLayout->addStretch( 10 );
3882 btnLayout->addWidget( helpBtn );
3884 QVBoxLayout* l = new QVBoxLayout ( this );
3885 l->setMargin( MARGIN );
3886 l->setSpacing( SPACING );
3887 l->addWidget( myCtrlInfo );
3888 l->addLayout( btnLayout );
3890 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
3891 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
3892 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
3893 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
3894 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
3902 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3907 \brief Show controls information
3908 \param IO interactive object
3910 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3912 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ))
3913 myCtrlInfo->showInfo( obj );
3917 \brief Perform clean-up actions on the dialog box closing.
3919 void SMESHGUI_CtrlInfoDlg::reject()
3921 SMESH::SetPointRepresentation( false );
3926 \brief Setup selection mode depending on the current dialog box state.
3928 void SMESHGUI_CtrlInfoDlg::updateSelection()
3930 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3931 disconnect( selMgr, 0, this, 0 );
3932 SMESH::SetPointRepresentation( false );
3933 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3938 \brief Show mesh information
3940 void SMESHGUI_CtrlInfoDlg::updateInfo()
3942 SUIT_OverrideCursor wc;
3944 SALOME_ListIO selected;
3945 SMESHGUI::selectionMgr()->selectedObjects( selected );
3947 if ( selected.Extent() == 1 ) {
3948 Handle(SALOME_InteractiveObject) IO = selected.First();
3954 \brief Activate dialog box
3956 void SMESHGUI_CtrlInfoDlg::activate()
3958 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3959 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3964 \brief Deactivate dialog box
3966 void SMESHGUI_CtrlInfoDlg::deactivate()
3968 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3972 * \brief Dump contents into a file
3974 void SMESHGUI_CtrlInfoDlg::dump()
3976 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3978 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3979 if ( !appStudy ) return;
3980 _PTR( Study ) aStudy = appStudy->studyDS();
3982 QStringList aFilters;
3983 aFilters.append( tr( "TEXT_FILES" ));
3985 DumpFileDlg fd( this );
3986 fd.setWindowTitle( tr( "SAVE_INFO" ));
3987 fd.setNameFilters( aFilters );
3988 fd.myBaseChk->hide();
3989 fd.myElemChk->hide();
3990 fd.myAddChk ->hide();
3991 fd.myCtrlChk->hide();
3992 if ( fd.exec() == QDialog::Accepted )
3994 QString aFileName = fd.selectedFile();
3995 if ( !aFileName.isEmpty() ) {
3996 QFileInfo aFileInfo( aFileName );
3997 if ( aFileInfo.isDir() )
4000 QFile aFile( aFileName );
4001 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
4004 QTextStream out( &aFile );
4005 myCtrlInfo->saveInfo( out );
4013 void SMESHGUI_CtrlInfoDlg::help()
4015 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");