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;
88 TypeRole = Qt::UserRole + 10,
93 NodeConnectivity = 100,
102 class ExtraWidget : public QWidget
105 ExtraWidget( QWidget*, bool = false );
108 void updateControls( int, int, int = MAXITEMS );
117 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
119 current = new QLabel( this );
120 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
121 prev = new QPushButton( tr( "<<" ), this );
122 next = new QPushButton( tr( ">>" ), this );
123 QHBoxLayout* hbl = new QHBoxLayout( this );
124 hbl->setContentsMargins( 0, SPACING, 0, 0 );
125 hbl->setSpacing( SPACING );
127 hbl->addWidget( current );
128 hbl->addWidget( prev );
129 hbl->addWidget( next );
132 ExtraWidget::~ExtraWidget()
136 void ExtraWidget::updateControls( int total, int index, int blockSize )
138 setVisible( total > blockSize );
139 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
140 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total )).arg( total ));
141 prev->setEnabled( index > 0 );
142 next->setEnabled( (index+1)*blockSize < total );
147 \brief Customization of standard "Save file" dialog box for dump info operation
151 class DumpFileDlg : public SUIT_FileDlg
154 DumpFileDlg( QWidget* parent );
156 QCheckBox* myBaseChk;
157 QCheckBox* myElemChk;
159 QCheckBox* myCtrlChk;
166 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
168 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
170 QWidget* hB = new QWidget( this );
171 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
172 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
173 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
174 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
176 QGridLayout* layout = new QGridLayout( hB );
177 layout->addWidget( myBaseChk, 0, 0 );
178 layout->addWidget( myElemChk, 0, 1 );
179 layout->addWidget( myAddChk, 1, 0 );
180 layout->addWidget( myCtrlChk, 1, 1 );
182 QPushButton* pb = new QPushButton( this );
184 int row = grid->rowCount();
185 grid->addWidget( new QLabel( "", this ), row, 0 );
186 grid->addWidget( hB, row, 1, 1, 3 );
187 grid->addWidget( pb, row, 5 );
194 \brief Get depth of the tree item
196 \param theItem tree widget item
197 \return item's depth in tree widget (where top-level items have zero depth)
199 static int itemDepth( QTreeWidgetItem* item )
202 QTreeWidgetItem* p = item->parent();
211 \class SMESHGUI_MeshInfo
212 \brief Base mesh information widget
214 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
219 \param parent parent widget
221 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
222 : QFrame( parent ), myWidgets( iElementsEnd )
224 setFrameStyle( StyledPanel | Sunken );
226 QGridLayout* l = new QGridLayout( this );
227 l->setMargin( MARGIN );
228 l->setSpacing( SPACING );
233 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
234 QLabel* aName = createField();
235 aName->setObjectName("meshName");
236 aName->setMinimumWidth( 150 );
237 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
238 QLabel* aObj = createField();
239 aObj->setObjectName("meshType");
240 aObj->setMinimumWidth( 150 );
241 myWidgets[ index++ ] << aNameLab << aName;
242 myWidgets[ index++ ] << aObjLab << aObj;
245 QWidget* aNodesLine = createLine();
246 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
247 QLabel* aNodes = createField();
248 aNodes->setObjectName("nbNodes");
249 myWidgets[ index++ ] << aNodesLine;
250 myWidgets[ index++ ] << aNodesLab << aNodes;
253 QWidget* aElemLine = createLine();
254 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
255 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
256 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
257 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
258 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
259 myWidgets[ index++ ] << aElemLine;
260 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
262 // ... Number elements
263 QWidget* aNbLine = createLine();
264 QLabel* aNbTotal = createField();
265 aNbTotal->setObjectName("totalNbElems");
266 QLabel* aNbLin = createField();
267 aNbLin->setObjectName("totalNbLinearElems");
268 QLabel* aNbQuad = createField();
269 aNbQuad->setObjectName("totalNbQuadraticElems");
270 QLabel* aNbBiQuad = createField();
271 aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
272 myWidgets[ index++ ] << aNbLine;
273 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
276 QWidget* a0DLine = createLine();
277 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
278 QLabel* a0DTotal = createField();
279 a0DTotal->setObjectName("nb0D");
281 myWidgets[ index++ ] << a0DLine;
282 myWidgets[ index++ ] << a0DLab << a0DTotal;
285 QWidget* aBallLine = createLine();
286 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
287 QLabel* aBallTotal = createField();
288 aBallTotal->setObjectName("nbBall");
289 myWidgets[ index++ ] << aBallLine;
290 myWidgets[ index++ ] << aBallLab << aBallTotal;
293 QWidget* a1DLine = createLine();
294 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
295 QLabel* a1DTotal = createField();
296 a1DTotal->setObjectName("nb1D");
297 QLabel* a1DLin = createField();
298 a1DLin->setObjectName("nbLinear1D");
299 QLabel* a1DQuad = createField();
300 a1DQuad->setObjectName("nbQuadratic1D");
301 myWidgets[ index++ ] << a1DLine;
302 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
305 QWidget* a2DLine = createLine();
306 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
307 QLabel* a2DTotal = createField();
308 a2DTotal->setObjectName("nb2D");
309 QLabel* a2DLin = createField();
310 a2DLin->setObjectName("nbLinear2D");
311 QLabel* a2DQuad = createField();
312 a2DQuad->setObjectName("nbQuadratic2D");
313 QLabel* a2DBiQuad = createField();
314 a2DBiQuad->setObjectName("nbBiQuadratic2D");
315 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
316 QLabel* a2DTriTotal = createField();
317 a2DTriTotal->setObjectName("nbTriangle");
318 QLabel* a2DTriLin = createField();
319 a2DTriLin->setObjectName("nbLinearTriangle");
320 QLabel* a2DTriQuad = createField();
321 a2DTriQuad->setObjectName("nbQuadraticTriangle");
322 QLabel* a2DTriBiQuad = createField();
323 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
324 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
325 QLabel* a2DQuaTotal = createField();
326 a2DQuaTotal->setObjectName("nbQuadrangle");
327 QLabel* a2DQuaLin = createField();
328 a2DQuaLin->setObjectName("nbLinearQuadrangle");
329 QLabel* a2DQuaQuad = createField();
330 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
331 QLabel* a2DQuaBiQuad = createField();
332 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
333 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
334 QLabel* a2DPolTotal = createField();
335 a2DPolTotal->setObjectName("nbPolygon");
336 QLabel* a2DPolLin = createField();
337 a2DPolLin->setObjectName("nbLinearPolygon");
338 QLabel* a2DPolQuad = createField();
339 a2DPolQuad->setObjectName("nbQuadraticPolygon");
340 myWidgets[ index++ ] << a2DLine;
341 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
342 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
343 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
344 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
347 QWidget* a3DLine = createLine();
348 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
349 QLabel* a3DTotal = createField();
350 a3DTotal->setObjectName("nb3D");
351 QLabel* a3DLin = createField();
352 a3DLin->setObjectName("nbLinear3D");
353 QLabel* a3DQuad = createField();
354 a3DQuad->setObjectName("nbQuadratic3D");
355 QLabel* a3DBiQuad = createField();
356 a3DBiQuad->setObjectName("nbBiQuadratic3D");
357 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
358 QLabel* a3DTetTotal = createField();
359 a3DTetTotal->setObjectName("nbTetrahedron");
360 QLabel* a3DTetLin = createField();
361 a3DTetLin->setObjectName("nbLinearTetrahedron");
362 QLabel* a3DTetQuad = createField();
363 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
364 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
365 QLabel* a3DHexTotal = createField();
366 a3DHexTotal->setObjectName("nbHexahedron");
367 QLabel* a3DHexLin = createField();
368 a3DHexLin->setObjectName("nbLinearHexahedron");
369 QLabel* a3DHexQuad = createField();
370 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
371 QLabel* a3DHexBiQuad = createField();
372 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
373 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
374 QLabel* a3DPyrTotal = createField();
375 a3DPyrTotal->setObjectName("nbPyramid");
376 QLabel* a3DPyrLin = createField();
377 a3DPyrLin->setObjectName("nbLinearPyramid");
378 QLabel* a3DPyrQuad = createField();
379 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
380 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
381 QLabel* a3DPriTotal = createField();
382 a3DPriTotal->setObjectName("nbPrism");
383 QLabel* a3DPriLin = createField();
384 a3DPriLin->setObjectName("nbLinearPrism");
385 QLabel* a3DPriQuad = createField();
386 a3DPriQuad->setObjectName("nbQuadraticPrism");
387 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
388 QLabel* a3DHexPriTotal = createField();
389 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
390 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
391 QLabel* a3DPolTotal = createField();
392 a3DPolTotal->setObjectName("nbPolyhedron");
393 myWidgets[ index++ ] << a3DLine;
394 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
395 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
396 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
397 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
398 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
399 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
400 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
402 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
403 myLoadBtn->setAutoDefault( true );
404 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ));
406 setFontAttributes( aNameLab, Bold );
407 setFontAttributes( aObjLab, Bold );
408 setFontAttributes( aNodesLab, Bold );
409 setFontAttributes( aElemLab, Bold );
410 setFontAttributes( aElemTotal, Italic );
411 setFontAttributes( aElemLin, Italic );
412 setFontAttributes( aElemQuad, Italic );
413 setFontAttributes( aElemBiQuad, Italic );
414 setFontAttributes( a0DLab, Bold );
415 setFontAttributes( aBallLab, Bold );
416 setFontAttributes( a1DLab, Bold );
417 setFontAttributes( a2DLab, Bold );
418 setFontAttributes( a3DLab, Bold );
420 l->addWidget( aNameLab, 0, 0 );
421 l->addWidget( aName, 0, 1, 1, 4 );
422 l->addWidget( aObjLab, 1, 0 );
423 l->addWidget( aObj, 1, 1, 1, 4 );
424 l->addWidget( aNodesLine, 2, 0, 1, 5 );
425 l->addWidget( aNodesLab, 3, 0 );
426 l->addWidget( aNodes, 3, 1 );
427 l->addWidget( aElemLine, 4, 0, 1, 5 );
428 l->addWidget( aElemLab, 5, 0 );
429 l->addWidget( aElemTotal, 5, 1 );
430 l->addWidget( aElemLin, 5, 2 );
431 l->addWidget( aElemQuad, 5, 3 );
432 l->addWidget( aElemBiQuad, 5, 4 );
433 l->addWidget( aNbLine, 6, 1, 1, 4 );
434 l->addWidget( aNbTotal, 7, 1 );
435 l->addWidget( aNbLin, 7, 2 );
436 l->addWidget( aNbQuad, 7, 3 );
437 l->addWidget( aNbBiQuad, 7, 4 );
438 l->addWidget( a0DLine, 8, 1, 1, 4 );
439 l->addWidget( a0DLab, 9, 0 );
440 l->addWidget( a0DTotal, 9, 1 );
441 l->addWidget( aBallLine, 10, 1, 1, 4 );
442 l->addWidget( aBallLab, 11, 0 );
443 l->addWidget( aBallTotal, 11, 1 );
444 l->addWidget( a1DLine, 12, 1, 1, 4 );
445 l->addWidget( a1DLab, 13, 0 );
446 l->addWidget( a1DTotal, 13, 1 );
447 l->addWidget( a1DLin, 13, 2 );
448 l->addWidget( a1DQuad, 13, 3 );
449 l->addWidget( a2DLine, 14, 1, 1, 4 );
450 l->addWidget( a2DLab, 15, 0 );
451 l->addWidget( a2DTotal, 15, 1 );
452 l->addWidget( a2DLin, 15, 2 );
453 l->addWidget( a2DQuad, 15, 3 );
454 l->addWidget( a2DBiQuad, 15, 4 );
455 l->addWidget( a2DTriLab, 16, 0 );
456 l->addWidget( a2DTriTotal, 16, 1 );
457 l->addWidget( a2DTriLin, 16, 2 );
458 l->addWidget( a2DTriQuad, 16, 3 );
459 l->addWidget( a2DTriBiQuad, 16, 4 );
460 l->addWidget( a2DQuaLab, 17, 0 );
461 l->addWidget( a2DQuaTotal, 17, 1 );
462 l->addWidget( a2DQuaLin, 17, 2 );
463 l->addWidget( a2DQuaQuad, 17, 3 );
464 l->addWidget( a2DQuaBiQuad, 17, 4 );
465 l->addWidget( a2DPolLab, 18, 0 );
466 l->addWidget( a2DPolTotal, 18, 1 );
467 l->addWidget( a2DPolLin, 18, 2 );
468 l->addWidget( a2DPolQuad, 18, 3 );
469 l->addWidget( a3DLine, 19, 1, 1, 4 );
470 l->addWidget( a3DLab, 20, 0 );
471 l->addWidget( a3DTotal, 20, 1 );
472 l->addWidget( a3DLin, 20, 2 );
473 l->addWidget( a3DQuad, 20, 3 );
474 l->addWidget( a3DBiQuad, 20, 4 );
475 l->addWidget( a3DTetLab, 21, 0 );
476 l->addWidget( a3DTetTotal, 21, 1 );
477 l->addWidget( a3DTetLin, 21, 2 );
478 l->addWidget( a3DTetQuad, 21, 3 );
479 l->addWidget( a3DHexLab, 22, 0 );
480 l->addWidget( a3DHexTotal, 22, 1 );
481 l->addWidget( a3DHexLin, 22, 2 );
482 l->addWidget( a3DHexQuad, 22, 3 );
483 l->addWidget( a3DHexBiQuad, 22, 4 );
484 l->addWidget( a3DPyrLab, 23, 0 );
485 l->addWidget( a3DPyrTotal, 23, 1 );
486 l->addWidget( a3DPyrLin, 23, 2 );
487 l->addWidget( a3DPyrQuad, 23, 3 );
488 l->addWidget( a3DPriLab, 24, 0 );
489 l->addWidget( a3DPriTotal, 24, 1 );
490 l->addWidget( a3DPriLin, 24, 2 );
491 l->addWidget( a3DPriQuad, 24, 3 );
492 l->addWidget( a3DHexPriLab, 25, 0 );
493 l->addWidget( a3DHexPriTotal, 25, 1 );
494 l->addWidget( a3DPolLab, 26, 0 );
495 l->addWidget( a3DPolTotal, 26, 1 );
496 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
498 l->setColumnStretch( 0, 0 );
499 l->setColumnStretch( 1, 5 );
500 l->setColumnStretch( 2, 5 );
501 l->setColumnStretch( 3, 5 );
502 l->setColumnStretch( 4, 5 );
503 l->setRowStretch( 27, 5 );
511 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
516 \brief Show information on the mesh object.
517 \param obj object being processed (mesh, sub-mesh, group, ID source)
519 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
522 if ( !CORBA::is_nil( obj )) {
523 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
525 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
526 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
527 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
528 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
529 if ( !aMesh->_is_nil() ) {
530 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ));
532 else if ( !aSubMesh->_is_nil() ) {
533 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ));
535 else if ( !aGroup->_is_nil() ) {
537 switch( aGroup->GetType() ) {
538 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
539 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
540 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
541 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
542 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
543 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
544 default: objType = tr( "OBJECT_GROUP" );break;
546 myWidgets[iObject][iSingle]->setProperty( "text", objType );
548 SMESH::long_array_var info = obj->GetMeshInfo();
549 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ));
550 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ));
551 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ));
552 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
553 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ));
554 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ));
555 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ));
556 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
557 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
558 long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
559 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
560 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
561 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
562 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
564 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
565 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ));
566 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ));
567 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ));
568 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ));
569 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ));
570 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ));
571 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ));
572 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ));
573 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ));
574 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ));
575 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ));
576 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
577 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ));
578 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ));
579 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
580 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
581 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
582 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
583 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
584 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
585 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
586 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
587 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ));
588 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ));
589 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ));
590 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ));
591 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ));
592 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ));
593 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ));
594 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ));
595 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ));
596 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ));
597 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ));
598 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ));
599 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ));
600 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ));
601 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ));
602 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ));
603 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ));
604 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ));
605 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ));
606 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
607 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
608 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
609 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
610 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ));
611 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ));
612 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ));
613 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ));
614 // before full loading from study file, type of elements in a sub-mesh can't be defined
616 bool infoOK = obj->IsMeshInfoCorrect();
617 myLoadBtn->setVisible( !infoOK );
621 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
622 // 2. No info at all (for a group on geom or filter)
623 bool hasAnyInfo = false;
624 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
625 hasAnyInfo = info[i];
626 if ( hasAnyInfo ) // believe it is a sub-mesh
628 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
630 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
631 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
632 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
633 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
634 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
635 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
636 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
637 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
638 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
639 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
640 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
641 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
642 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
643 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
644 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
645 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
646 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
647 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
649 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
651 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
652 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
653 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
654 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
655 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
656 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
657 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
658 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
659 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
660 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
661 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
662 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
663 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
664 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
665 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
666 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
667 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
668 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
669 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
670 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
671 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
672 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
677 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
678 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
679 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
681 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
682 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
683 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
684 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
685 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
686 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
687 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
688 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
689 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
690 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
691 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
692 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
693 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
694 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
695 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
696 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
697 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
698 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
699 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
700 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
701 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
702 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
703 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
704 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
705 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
706 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
707 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
708 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
709 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
710 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
711 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
712 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
713 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
714 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
715 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
716 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
717 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
724 \brief Load mesh from a study file
726 void SMESHGUI_MeshInfo::loadMesh()
728 SUIT_OverrideCursor wc;
730 SALOME_ListIO selected;
731 SMESHGUI::selectionMgr()->selectedObjects( selected );
733 if ( selected.Extent() == 1 ) {
734 Handle(SALOME_InteractiveObject) IO = selected.First();
735 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
736 if ( !CORBA::is_nil( obj )) {
737 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
738 if ( !mesh->_is_nil() )
748 \brief Reset the widget to the initial state (nullify all fields).
750 void SMESHGUI_MeshInfo::clear()
752 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
753 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
754 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ));
755 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ));
756 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ));
757 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ));
758 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ));
759 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
760 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ));
761 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ));
762 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
763 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
764 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ));
765 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ));
766 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
767 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
768 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ));
769 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ));
770 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ));
771 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
772 myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ));
773 myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
774 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ));
775 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ));
776 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ));
777 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ));
778 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
779 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
780 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
781 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
782 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
783 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ));
784 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ));
785 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
786 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ));
787 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ));
788 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ));
789 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
790 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ));
791 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ));
792 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ));
793 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ));
794 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ));
795 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ));
796 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ));
797 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ));
801 \brief Create info field
802 \return new info field
804 QLabel* SMESHGUI_MeshInfo::createField()
806 QLabel* lab = new QLabel( this );
807 lab->setFrameStyle( StyledPanel | Sunken );
808 lab->setAlignment( Qt::AlignCenter );
809 lab->setAutoFillBackground( true );
810 QPalette pal = lab->palette();
811 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
812 lab->setPalette( pal );
813 lab->setMinimumWidth( 70 );
818 \brief Create horizontal rule.
819 \return new line object
821 QWidget* SMESHGUI_MeshInfo::createLine()
823 QFrame* line = new QFrame( this );
824 line->setFrameStyle( HLine | Sunken );
829 \brief Change widget font attributes (bold, italic, ...).
831 \param attr font attributes (XORed flags)
832 \param val value to be set to attributes
834 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
838 if ( attr & Bold ) f.setBold( val );
839 if ( attr & Italic ) f.setItalic( val );
845 \brief Show/hide group(s) of fields.
846 \param start beginning of the block
847 \param end end of the block
848 \param on visibility flag
850 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
852 start = qMax( 0, start );
853 end = qMin( end, (int)iElementsEnd );
854 for ( int i = start; i < end; i++ ) {
855 wlist wl = myWidgets[i];
856 foreach ( QWidget* w, wl ) w->setVisible( on );
860 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
862 out << QString( 9, '-' ) << "\n";
863 out << tr( "BASE_INFO" ) << "\n";
864 out << QString( 9, '-' ) << "\n";
865 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" )).toString() << "\n";
866 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" )).toString() << "\n";
867 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" )).toString() << "\n";
868 out << tr( "ELEMENTS_LAB" ) << "\n";
869 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" )).toString() << "\n";
870 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" )).toString() << "\n";
871 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" )).toString() << "\n";
872 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" )).toString() << "\n";
873 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
874 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" )).toString() << "\n";
875 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
876 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" )).toString() << "\n";
877 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
878 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" )).toString() << "\n";
879 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" )).toString() << "\n";
880 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" )).toString() << "\n";
881 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" )).toString() << "\n";
883 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" )).toString() << "\n";
884 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" )).toString() << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" )).toString() << "\n";
886 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
887 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" )).toString() << "\n";
888 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" )).toString() << "\n";
889 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" )).toString() << "\n";
890 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" )).toString() << "\n";
891 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" )).toString() << "\n";
893 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" )).toString() << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" )).toString() << "\n";
895 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" )).toString() << "\n";
896 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" )).toString() << "\n";
898 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" )).toString() << "\n";
899 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" )).toString() << "\n";
900 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
901 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" )).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" )).toString() << "\n";
903 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" )).toString() << "\n";
904 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" )).toString() << "\n";
905 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
906 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" )).toString() << "\n";
907 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" )).toString() << "\n";
908 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" )).toString() << "\n";
909 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
910 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" )).toString() << "\n";
911 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" )).toString() << "\n";
912 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" )).toString() << "\n";
913 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" )).toString() << "\n";
914 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
915 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" )).toString() << "\n";
916 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" )).toString() << "\n";
917 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" )).toString() << "\n";
918 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
919 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" )).toString() << "\n";
920 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" )).toString() << "\n";
921 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" )).toString() << "\n";
922 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
923 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" )).toString() << "\n";
924 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
925 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" )).toString() << "\n" << "\n";
929 \class SMESHGUI_ElemInfo
930 \brief Base class for the mesh element information widget.
935 \param parent parent widget
937 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
938 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
940 myFrame = new QWidget( this );
941 myExtra = new ExtraWidget( this );
942 QVBoxLayout* vbl = new QVBoxLayout( this );
944 vbl->setSpacing( 0 );
945 vbl->addWidget( myFrame );
946 vbl->addWidget( myExtra );
947 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ));
948 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ));
955 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
960 \brief Set mesh data source (actor)
961 \param actor mesh object actor
963 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
965 if ( myActor != actor ) {
973 \brief Show mesh element information
974 \param id mesh node / element ID
975 \param isElem show mesh element information if \c true or mesh node information if \c false
977 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
981 showInfo( ids, isElem );
985 \brief Show mesh element information
986 \param ids mesh nodes / elements identifiers
987 \param isElem show mesh element information if \c true or mesh node information if \c false
989 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
991 QList<long> newIds = ids.toList();
993 if ( myIDs == newIds && myIsElement == isElem ) return;
996 myIsElement = isElem;
999 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1003 \brief Clear mesh element information widget
1005 void SMESHGUI_ElemInfo::clear()
1014 \brief Get central area widget
1015 \return central widget
1017 QWidget* SMESHGUI_ElemInfo::frame() const
1024 \return actor being used
1026 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1032 \brief Get current info mode.
1033 \return \c true if mesh element information is shown or \c false if node information is shown
1035 bool SMESHGUI_ElemInfo::isElements() const
1041 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1042 \brief Show information on the specified nodes / elements
1044 This function is to be redefined in sub-classes.
1046 \param ids nodes / elements identifiers information is to be shown on
1050 \brief Internal clean-up (reset widget)
1052 void SMESHGUI_ElemInfo::clearInternal()
1057 \brief Get node connectivity
1058 \param node mesh node
1059 \return node connectivity map
1061 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1065 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1066 while ( it && it->more() ) {
1067 const SMDS_MeshElement* ne = it->next();
1068 elmap[ ne->GetType() ] << ne->GetID();
1075 \brief Format connectivity data to string representation
1076 \param connectivity connetivity map
1077 \param type element type
1078 \return string representation of the connectivity
1080 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1083 if ( connectivity.contains( type )) {
1084 QList<int> elements = connectivity[ type ];
1086 foreach( int id, elements )
1087 str << QString::number( id );
1089 return str.join( " " );
1093 \brief Calculate gravity center of the mesh element
1094 \param element mesh element
1096 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1100 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1101 while ( nodeIt->more() ) {
1102 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1103 xyz.add( node->X(), node->Y(), node->Z() );
1105 xyz.divide( element->NbNodes() );
1111 \brief Calculate normal vector to the mesh face
1112 \param element mesh face
1114 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1116 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ));
1117 return XYZ(n.X(), n.Y(), n.Z());
1121 \brief This slot is called from "Show Previous" button click.
1122 Shows information on the previous group of the items.
1124 void SMESHGUI_ElemInfo::showPrevious()
1126 myIndex = qMax( 0, myIndex-1 );
1128 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1132 \brief This slot is called from "Show Next" button click.
1133 Shows information on the next group of the items.
1135 void SMESHGUI_ElemInfo::showNext()
1137 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1139 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ));
1143 \brief Update widgets state
1145 void SMESHGUI_ElemInfo::updateControls()
1147 myExtra->updateControls( myIDs.count(), myIndex );
1151 \class SMESHGUI_SimpleElemInfo
1152 \brief Represents mesh element information in the simple text area.
1157 \param parent parent widget
1159 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1160 : SMESHGUI_ElemInfo( parent )
1162 myInfo = new QTextBrowser( frame() );
1163 QVBoxLayout* l = new QVBoxLayout( frame() );
1165 l->addWidget( myInfo );
1169 \brief Show mesh element information
1170 \param ids mesh nodes / elements identifiers
1172 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1177 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1178 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1179 int cprecision = -1;
1180 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1181 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1182 foreach ( long id, ids ) {
1183 if ( !isElements() ) {
1187 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1188 if ( !node ) return;
1191 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id ));
1193 myInfo->append( "" );
1195 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1196 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1197 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1198 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1200 myInfo->append( "" );
1202 Connectivity connectivity = nodeConnectivity( node );
1203 if ( !connectivity.isEmpty() ) {
1204 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1205 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1206 if ( !con.isEmpty() )
1207 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1208 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1209 if ( !con.isEmpty() )
1210 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1211 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1212 if ( !con.isEmpty() )
1213 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con ));
1214 con = formatConnectivity( connectivity, SMDSAbs_Face );
1215 if ( !con.isEmpty() )
1216 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1217 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1218 if ( !con.isEmpty() )
1219 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1222 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1225 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1226 if ( !CORBA::is_nil( aMeshPtr )) {
1227 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1228 int shapeID = pos->shapeID;
1229 if ( shapeID > 0 ) {
1231 double u = 0, v = 0;
1232 switch ( pos->shapeType ) {
1234 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1235 if ( pos->params.length() == 1 )
1239 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1240 if ( pos->params.length() == 2 ) {
1246 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1249 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1253 myInfo->append( "" );
1254 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) );
1255 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ));
1256 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1257 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )).
1258 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1259 if ( pos->shapeType == GEOM::FACE ) {
1260 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )).
1261 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ));
1266 // groups node belongs to
1267 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1268 if ( !CORBA::is_nil( aMesh )) {
1269 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1270 myInfo->append( "" ); // separator
1271 bool top_created = false;
1272 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1273 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1274 if ( CORBA::is_nil( aGrp )) continue;
1275 QString aName = aGrp->GetName();
1276 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1277 if ( !top_created ) {
1278 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1281 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1282 if ( grp_details ) {
1283 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1284 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1285 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1287 // type : group on geometry, standalone group, group on filter
1288 if ( !CORBA::is_nil( aStdGroup )) {
1289 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1290 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1292 else if ( !CORBA::is_nil( aGeomGroup )) {
1293 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1294 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1295 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1296 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1298 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1299 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1302 else if ( !CORBA::is_nil( aFltGroup )) {
1303 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1304 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1308 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1309 arg( QString::number( aGrp->Size() )) );
1312 SALOMEDS::Color color = aGrp->GetColor();
1313 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1314 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1322 // show element info
1324 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1325 SMESH::Controls::NumericalFunctorPtr afunctor;
1328 // Element ID && Type
1330 switch( e->GetType() ) {
1331 case SMDSAbs_0DElement:
1332 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1334 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1336 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1338 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1339 case SMDSAbs_Volume:
1340 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1344 if ( stype.isEmpty() ) return;
1345 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ));
1347 myInfo->append( "" );
1351 switch( e->GetEntityType() ) {
1352 case SMDSEntity_Triangle:
1353 case SMDSEntity_Quad_Triangle:
1354 case SMDSEntity_BiQuad_Triangle:
1355 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1356 case SMDSEntity_Quadrangle:
1357 case SMDSEntity_Quad_Quadrangle:
1358 case SMDSEntity_BiQuad_Quadrangle:
1359 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1360 case SMDSEntity_Polygon:
1361 case SMDSEntity_Quad_Polygon:
1362 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1363 case SMDSEntity_Tetra:
1364 case SMDSEntity_Quad_Tetra:
1365 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1366 case SMDSEntity_Pyramid:
1367 case SMDSEntity_Quad_Pyramid:
1368 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1369 case SMDSEntity_Hexa:
1370 case SMDSEntity_Quad_Hexa:
1371 case SMDSEntity_TriQuad_Hexa:
1372 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1373 case SMDSEntity_Penta:
1374 case SMDSEntity_Quad_Penta:
1375 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1376 case SMDSEntity_Hexagonal_Prism:
1377 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1378 case SMDSEntity_Polyhedra:
1379 case SMDSEntity_Quad_Polyhedra:
1380 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1384 if ( !gtype.isEmpty() )
1385 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype ));
1387 // Quadratic flag (any element except 0D)
1388 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1389 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) );
1391 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1393 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() ));
1396 myInfo->append( "" );
1399 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1400 for ( int idx = 1; nodeIt->more(); idx++ ) {
1401 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1402 // node number and ID
1403 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ));
1405 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )).
1406 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1407 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )).
1408 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) );
1409 // node connectivity
1410 Connectivity connectivity = nodeConnectivity( node );
1411 if ( !connectivity.isEmpty() ) {
1412 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) );
1413 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1414 if ( !con.isEmpty() )
1415 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con ));
1416 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1417 if ( !con.isEmpty() )
1418 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con ));
1419 con = formatConnectivity( connectivity, SMDSAbs_Face );
1420 if ( !con.isEmpty() )
1421 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con ));
1422 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1423 if ( !con.isEmpty() )
1424 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con ));
1427 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id ));
1431 myInfo->append( "" );
1434 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) );
1436 if ( e->GetType() == SMDSAbs_Edge ) {
1437 afunctor.reset( new SMESH::Controls::Length() );
1438 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1439 afunctor->SetPrecision( cprecision );
1440 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) );
1442 if( e->GetType() == SMDSAbs_Face ) {
1444 afunctor.reset( new SMESH::Controls::Area() );
1445 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1446 afunctor->SetPrecision( cprecision );
1447 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1449 afunctor.reset( new SMESH::Controls::Taper() );
1450 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1451 afunctor->SetPrecision( cprecision );
1452 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1454 afunctor.reset( new SMESH::Controls::AspectRatio() );
1455 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1456 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1458 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1459 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1460 afunctor->SetPrecision( cprecision );
1461 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1463 afunctor.reset( new SMESH::Controls::Warping() );
1464 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1465 afunctor->SetPrecision( cprecision );
1466 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1468 afunctor.reset( new SMESH::Controls::Skew() );
1469 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1470 afunctor->SetPrecision( cprecision );
1471 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1473 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1474 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1475 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) );
1477 if( e->GetType() == SMDSAbs_Volume ) {
1479 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1480 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1481 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1483 afunctor.reset( new SMESH::Controls::Volume() );
1484 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1485 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) );
1487 afunctor.reset( new SMESH::Controls::Volume() );
1488 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1489 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) );
1492 myInfo->append( "" );
1495 XYZ gc = gravityCenter( e );
1496 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1499 if( e->GetType() == SMDSAbs_Face ) {
1500 XYZ gc = normal( e );
1501 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ));
1505 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1506 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1507 if ( !CORBA::is_nil( aMesh )) {
1508 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1509 int shapeID = pos.shapeID;
1510 if ( shapeID > 0 ) {
1511 myInfo->append( "" ); // separator
1513 switch ( pos.shapeType ) {
1514 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1515 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1516 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1517 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1518 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1519 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1521 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID ));
1526 // Groups the element belongs to
1527 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1528 if ( !CORBA::is_nil( aMesh )) {
1529 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1530 myInfo->append( "" ); // separator
1531 bool top_created = false;
1532 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1533 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1534 if ( CORBA::is_nil( aGrp )) continue;
1535 QString aName = aGrp->GetName();
1536 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1537 if ( !top_created ) {
1538 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) );
1541 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ));
1542 if ( grp_details ) {
1543 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1544 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1545 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1547 // type : group on geometry, standalone group, group on filter
1548 if ( !CORBA::is_nil( aStdGroup )) {
1549 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1550 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) );
1552 else if ( !CORBA::is_nil( aGeomGroup )) {
1553 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1554 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) );
1555 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1556 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1558 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1559 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() ));
1562 else if ( !CORBA::is_nil( aFltGroup )) {
1563 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )).
1564 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) );
1567 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )).
1568 arg( QString::number( aGrp->Size() )) );
1571 SALOMEDS::Color color = aGrp->GetColor();
1572 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )).
1573 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ));
1580 if ( ids.count() > 1 ) {
1581 myInfo->append( "" );
1582 myInfo->append( "------" );
1583 myInfo->append( "" );
1590 \brief Internal clean-up (reset widget)
1592 void SMESHGUI_SimpleElemInfo::clearInternal()
1597 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1599 out << QString( 12, '-' ) << "\n";
1600 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1601 out << QString( 12, '-' ) << "\n";
1602 out << myInfo->toPlainText();
1608 \class SMESHGUI_TreeElemInfo::ItemDelegate
1609 \brief Item delegate for tree mesh info widget
1612 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1615 ItemDelegate( QObject* );
1616 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1623 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1628 \brief Create item editor widget
1631 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1633 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1634 if ( qobject_cast<QLineEdit*>( w )) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1639 \class SMESHGUI_TreeElemInfo
1640 \brief Represents mesh element information in the tree-like form.
1645 \param parent parent widget
1647 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1648 : SMESHGUI_ElemInfo( parent )
1650 myInfo = new QTreeWidget( frame() );
1651 myInfo->setColumnCount( 2 );
1652 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ));
1653 myInfo->header()->setStretchLastSection( true );
1654 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1655 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1657 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
1659 myInfo->setItemDelegate( new ItemDelegate( myInfo ));
1660 QVBoxLayout* l = new QVBoxLayout( frame() );
1662 l->addWidget( myInfo );
1663 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) );
1664 connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1665 connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
1669 \brief Show mesh element information
1670 \param ids mesh nodes / elements identifiers
1672 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1677 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1678 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1679 int cprecision = -1;
1680 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
1681 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1682 foreach ( long id, ids ) {
1683 if ( !isElements() ) {
1687 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1689 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1692 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1693 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ));
1694 nodeItem->setText( 1, QString( "#%1" ).arg( id ));
1696 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1697 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
1698 QTreeWidgetItem* xItem = createItem( coordItem );
1699 xItem->setText( 0, "X" );
1700 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1701 QTreeWidgetItem* yItem = createItem( coordItem );
1702 yItem->setText( 0, "Y" );
1703 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1704 QTreeWidgetItem* zItem = createItem( coordItem );
1705 zItem->setText( 0, "Z" );
1706 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
1708 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1709 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1710 Connectivity connectivity = nodeConnectivity( node );
1711 if ( !connectivity.isEmpty() ) {
1712 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1713 if ( !con.isEmpty() ) {
1714 QTreeWidgetItem* i = createItem( conItem );
1715 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
1716 i->setText( 1, con );
1718 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1719 if ( !con.isEmpty() ) {
1720 QTreeWidgetItem* i = createItem( conItem );
1721 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
1722 i->setText( 1, con );
1723 i->setData( 1, TypeRole, NodeConnectivity );
1725 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1726 if ( !con.isEmpty() ) {
1727 QTreeWidgetItem* i = createItem( conItem );
1728 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
1729 i->setText( 1, con );
1730 i->setData( 1, TypeRole, NodeConnectivity );
1732 con = formatConnectivity( connectivity, SMDSAbs_Face );
1733 if ( !con.isEmpty() ) {
1734 QTreeWidgetItem* i = createItem( conItem );
1735 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
1736 i->setText( 1, con );
1737 i->setData( 1, TypeRole, NodeConnectivity );
1739 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1740 if ( !con.isEmpty() ) {
1741 QTreeWidgetItem* i = createItem( conItem );
1742 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
1743 i->setText( 1, con );
1744 i->setData( 1, TypeRole, NodeConnectivity );
1748 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ));
1751 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1752 if ( !CORBA::is_nil( aMeshPtr )) {
1753 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1754 int shapeID = pos->shapeID;
1755 if ( shapeID > 0 ) {
1757 double u = 0, v = 0;
1758 switch ( pos->shapeType ) {
1760 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1761 if ( pos->params.length() == 1 )
1765 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1766 if ( pos->params.length() == 2 ) {
1772 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1775 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1778 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1779 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1780 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1781 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1782 QTreeWidgetItem* uItem = createItem( posItem );
1783 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1784 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1785 if ( pos->shapeType == GEOM::FACE ) {
1786 QTreeWidgetItem* vItem = createItem( posItem );
1787 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1788 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1793 // groups node belongs to
1794 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1795 if ( !CORBA::is_nil( aMesh )) {
1796 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1797 QTreeWidgetItem* groupsItem = 0;
1798 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1799 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1800 if ( CORBA::is_nil( aGrp )) continue;
1801 QString aName = aGrp->GetName();
1802 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
1803 if ( !groupsItem ) {
1804 groupsItem = createItem( nodeItem, Bold );
1805 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
1807 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1808 it->setText( 0, aName.trimmed() );
1809 if ( grp_details ) {
1810 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1811 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1812 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1814 // type : group on geometry, standalone group, group on filter
1815 QTreeWidgetItem* typeItem = createItem( it );
1816 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
1817 if ( !CORBA::is_nil( aStdGroup )) {
1818 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
1820 else if ( !CORBA::is_nil( aGeomGroup )) {
1821 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
1822 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1823 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1825 QTreeWidgetItem* gobjItem = createItem( typeItem );
1826 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
1827 gobjItem->setText( 1, sobj->GetName().c_str() );
1830 else if ( !CORBA::is_nil( aFltGroup )) {
1831 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
1835 QTreeWidgetItem* sizeItem = createItem( it );
1836 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
1837 sizeItem->setText( 1, QString::number( aGrp->Size() ));
1840 SALOMEDS::Color color = aGrp->GetColor();
1841 QTreeWidgetItem* colorItem = createItem( it );
1842 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
1843 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
1851 // show element info
1853 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1854 SMESH::Controls::NumericalFunctorPtr afunctor;
1857 // element ID && type
1859 switch( e->GetType() ) {
1860 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1861 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1862 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1863 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1864 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1867 if ( stype.isEmpty() ) return;
1868 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1869 elemItem->setText( 0, stype );
1870 elemItem->setText( 1, QString( "#%1" ).arg( id ));
1873 switch( e->GetEntityType() ) {
1874 case SMDSEntity_Triangle:
1875 case SMDSEntity_Quad_Triangle:
1876 case SMDSEntity_BiQuad_Triangle:
1877 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1878 case SMDSEntity_Quadrangle:
1879 case SMDSEntity_Quad_Quadrangle:
1880 case SMDSEntity_BiQuad_Quadrangle:
1881 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1882 case SMDSEntity_Polygon:
1883 case SMDSEntity_Quad_Polygon:
1884 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1885 case SMDSEntity_Tetra:
1886 case SMDSEntity_Quad_Tetra:
1887 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1888 case SMDSEntity_Pyramid:
1889 case SMDSEntity_Quad_Pyramid:
1890 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1891 case SMDSEntity_Hexa:
1892 case SMDSEntity_Quad_Hexa:
1893 case SMDSEntity_TriQuad_Hexa:
1894 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1895 case SMDSEntity_Penta:
1896 case SMDSEntity_Quad_Penta:
1897 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1898 case SMDSEntity_Hexagonal_Prism:
1899 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1900 case SMDSEntity_Polyhedra:
1901 case SMDSEntity_Quad_Polyhedra:
1902 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1906 if ( !gtype.isEmpty() ) {
1907 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1908 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ));
1909 typeItem->setText( 1, gtype );
1911 // quadratic flag (for edges, faces and volumes)
1912 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1914 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1915 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ));
1916 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ));
1918 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1920 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1921 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ));
1922 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1925 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1926 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
1929 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1930 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1931 for ( int idx = 1; nodeIt->more(); idx++ ) {
1932 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1933 nodeInfo( node, idx, e->NbNodes(), conItem );
1937 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1938 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1939 QList<const SMDS_MeshElement*> uniqueNodes;
1940 while ( nodeIt->more() )
1941 uniqueNodes.append( nodeIt->next() );
1943 SMDS_VolumeTool vtool( e );
1944 const int nbFaces = vtool.NbFaces();
1945 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1946 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1947 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces ));
1948 faceItem->setExpanded( true );
1950 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1951 const int nbNodes = vtool.NbFaceNodes( face_id );
1952 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1953 const SMDS_MeshNode* node = aNodeIds[node_id];
1954 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1959 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1960 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ));
1962 if( e->GetType()==SMDSAbs_Edge){
1963 afunctor.reset( new SMESH::Controls::Length() );
1964 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1965 afunctor->SetPrecision( cprecision );
1966 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1967 lenItem->setText( 0, tr( "LENGTH_EDGES" ));
1968 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1970 if( e->GetType() == SMDSAbs_Face ) {
1972 afunctor.reset( new SMESH::Controls::Area() );
1973 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1974 afunctor->SetPrecision( cprecision );
1975 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1976 areaItem->setText( 0, tr( "AREA_ELEMENTS" ));
1977 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ));
1979 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1981 afunctor.reset( new SMESH::Controls::Taper() );
1982 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1983 afunctor->SetPrecision( cprecision );
1984 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1985 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ));
1986 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1988 afunctor.reset( new SMESH::Controls::Warping() );
1989 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1990 afunctor->SetPrecision( cprecision );
1991 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1992 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1993 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
1998 afunctor.reset( new SMESH::Controls::AspectRatio() );
1999 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2000 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
2001 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2002 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2005 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2006 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2007 afunctor->SetPrecision( cprecision );
2008 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2009 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ));
2010 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2012 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2014 afunctor.reset( new SMESH::Controls::Skew() );
2015 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2016 afunctor->SetPrecision( cprecision );
2017 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2018 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ));
2019 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2024 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2025 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2026 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2027 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2028 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2031 if( e->GetType() == SMDSAbs_Volume ) {
2035 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2036 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2037 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2038 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ));
2039 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2042 afunctor.reset( new SMESH::Controls::Volume() );
2043 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2044 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2045 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ));
2046 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2048 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2049 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2050 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2051 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ));
2052 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) );
2056 XYZ gc = gravityCenter( e );
2057 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2058 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ));
2059 QTreeWidgetItem* xItem = createItem( gcItem );
2060 xItem->setText( 0, "X" );
2061 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2062 QTreeWidgetItem* yItem = createItem( gcItem );
2063 yItem->setText( 0, "Y" );
2064 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2065 QTreeWidgetItem* zItem = createItem( gcItem );
2066 zItem->setText( 0, "Z" );
2067 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2070 if( e->GetType() == SMDSAbs_Face ) {
2071 XYZ gc = normal( e );
2072 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2073 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ));
2074 QTreeWidgetItem* xItem = createItem( nItem );
2075 xItem->setText( 0, "X" );
2076 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2077 QTreeWidgetItem* yItem = createItem( nItem );
2078 yItem->setText( 0, "Y" );
2079 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2080 QTreeWidgetItem* zItem = createItem( nItem );
2081 zItem->setText( 0, "Z" );
2082 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2086 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2087 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2088 if ( !CORBA::is_nil( aMesh )) {
2089 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2090 int shapeID = pos.shapeID;
2091 if ( shapeID > 0 ) {
2092 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2094 switch ( pos.shapeType ) {
2095 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2096 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2097 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2098 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2099 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2100 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2102 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ));
2103 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ));
2107 // groups element belongs to
2108 if ( !CORBA::is_nil( aMesh )) {
2109 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2110 QTreeWidgetItem* groupsItem = 0;
2111 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2112 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2113 if ( CORBA::is_nil( aGrp )) continue;
2114 QString aName = aGrp->GetName();
2115 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) {
2116 if ( !groupsItem ) {
2117 groupsItem = createItem( elemItem, Bold );
2118 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ));
2120 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2121 it->setText( 0, aName.trimmed() );
2122 if ( grp_details ) {
2123 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2124 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2125 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2127 // type : group on geometry, standalone group, group on filter
2128 QTreeWidgetItem* typeItem = createItem( it );
2129 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ));
2130 if ( !CORBA::is_nil( aStdGroup )) {
2131 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ));
2133 else if ( !CORBA::is_nil( aGeomGroup )) {
2134 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ));
2135 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2136 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2138 QTreeWidgetItem* gobjItem = createItem( typeItem );
2139 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ));
2140 gobjItem->setText( 1, sobj->GetName().c_str() );
2143 else if ( !CORBA::is_nil( aFltGroup )) {
2144 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ));
2148 QTreeWidgetItem* sizeItem = createItem( it );
2149 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ));
2150 sizeItem->setText( 1, QString::number( aGrp->Size() ));
2153 SALOMEDS::Color color = aGrp->GetColor();
2154 QTreeWidgetItem* colorItem = createItem( it );
2155 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ));
2156 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2167 \brief Show node information
2168 \param node mesh node for showing
2169 \param index index of current node
2170 \param nbNodes number of unique nodes in element
2171 \param parentItem parent item of tree
2173 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2174 int nbNodes, QTreeWidgetItem* parentItem )
2176 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2177 // node number and ID
2178 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2179 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2180 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2181 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2182 nodeItem->setData( 1, IdRole, node->GetID() );
2183 nodeItem->setExpanded( false );
2185 QTreeWidgetItem* coordItem = createItem( nodeItem );
2186 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2187 QTreeWidgetItem* xItem = createItem( coordItem );
2188 xItem->setText( 0, "X" );
2189 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2190 QTreeWidgetItem* yItem = createItem( coordItem );
2191 yItem->setText( 0, "Y" );
2192 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2193 QTreeWidgetItem* zItem = createItem( coordItem );
2194 zItem->setText( 0, "Z" );
2195 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2196 // node connectivity
2197 QTreeWidgetItem* nconItem = createItem( nodeItem );
2198 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2199 Connectivity connectivity = nodeConnectivity( node );
2200 if ( !connectivity.isEmpty() ) {
2201 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2202 if ( !con.isEmpty() ) {
2203 QTreeWidgetItem* i = createItem( nconItem );
2204 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2205 i->setText( 1, con );
2207 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2208 if ( !con.isEmpty() ) {
2209 QTreeWidgetItem* i = createItem( nconItem );
2210 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2211 i->setText( 1, con );
2212 i->setData( 1, TypeRole, NodeConnectivity );
2214 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2215 if ( !con.isEmpty() ) {
2216 QTreeWidgetItem* i = createItem( nconItem );
2217 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2218 i->setText( 1, con );
2219 i->setData( 1, TypeRole, NodeConnectivity );
2221 con = formatConnectivity( connectivity, SMDSAbs_Face );
2222 if ( !con.isEmpty() ) {
2223 QTreeWidgetItem* i = createItem( nconItem );
2224 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2225 i->setText( 1, con );
2226 i->setData( 1, TypeRole, NodeConnectivity );
2228 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2229 if ( !con.isEmpty() ) {
2230 QTreeWidgetItem* i = createItem( nconItem );
2231 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2232 i->setText( 1, con );
2233 i->setData( 1, TypeRole, NodeConnectivity );
2238 \brief Internal clean-up (reset widget)
2240 void SMESHGUI_TreeElemInfo::clearInternal()
2247 \brief Create new tree item.
2248 \param parent parent tree widget item
2249 \param flags item flag
2250 \return new tree widget item
2252 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2254 QTreeWidgetItem* item;
2256 item = new QTreeWidgetItem( parent );
2258 item = new QTreeWidgetItem( myInfo );
2260 item->setFlags( item->flags() | Qt::ItemIsEditable );
2262 QFont f = item->font( 0 );
2264 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2265 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2266 item->setFont( i, f );
2269 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2271 QString resName = expandedResource( parent );
2272 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2275 item->setExpanded( true );
2279 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2281 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2282 if ( widgets.isEmpty() ) return;
2283 QTreeWidgetItem* aTreeItem = widgets.first();
2284 int type = aTreeItem->data( 1, TypeRole ).toInt();
2285 int id = aTreeItem->data( 1, IdRole ).toInt();
2287 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2288 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2289 emit( itemInfo( id ));
2290 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2291 emit( itemInfo( aTreeItem->text( 1 )) );
2294 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2297 int type = theItem->data( 1, TypeRole ).toInt();
2298 int id = theItem->data( 1, IdRole ).toInt();
2299 if ( type == ElemConnectivity && id > 0 )
2300 emit( itemInfo( id ));
2301 else if ( type == NodeConnectivity )
2302 emit( itemInfo( theItem->text( 1 )) );
2306 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2309 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2312 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2314 return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0);
2317 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2319 out << QString( 12, '-' ) << "\n";
2320 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2321 out << QString( 12, '-' ) << "\n";
2323 QTreeWidgetItemIterator it( myInfo );
2325 if ( !( *it )->text(0).isEmpty() ) {
2326 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2327 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2337 \brief Mesh information computer
2340 The class is created for different computation operation. Currently it is used
2341 to compute number of underlying nodes for the groups.
2347 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2348 QTreeWidgetItem* item,
2351 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2353 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2357 \brief Compute function
2359 void GrpComputor::compute()
2361 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2362 SUIT_OverrideCursor wc;
2363 QTreeWidgetItem* item = myItem;
2365 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2366 item->treeWidget()->removeItemWidget( item, 1 );
2367 item->setText( 1, QString::number( nb ));
2372 \class SMESHGUI_AddInfo
2373 \brief The wigdet shows additional information on the mesh object.
2378 \param parent parent widget
2380 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2381 : QTreeWidget( parent )
2383 setColumnCount( 2 );
2384 header()->setStretchLastSection( true );
2385 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2386 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2388 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2396 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2401 \brief Show additional information on the selected object
2402 \param obj object being processed (mesh, sub-mesh, group, ID source)
2404 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2406 setProperty( "group_index", 0 );
2407 setProperty( "submesh_index", 0 );
2408 myComputors.clear();
2411 if ( CORBA::is_nil( obj )) return;
2413 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2414 if ( !sobj ) return;
2417 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2418 nameItem->setText( 0, tr( "NAME" ));
2419 nameItem->setText( 1, sobj->GetName().c_str() );
2421 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2422 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2423 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2425 if ( !aMesh->_is_nil() )
2426 meshInfo( aMesh, nameItem );
2427 else if ( !aSubMesh->_is_nil() )
2428 subMeshInfo( aSubMesh, nameItem );
2429 else if ( !aGroup->_is_nil() )
2430 groupInfo( aGroup.in(), nameItem );
2434 \brief Create new tree item.
2435 \param parent parent tree widget item
2436 \param flags item flag
2437 \return new tree widget item
2439 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2441 QTreeWidgetItem* item;
2444 item = new QTreeWidgetItem( parent );
2446 item = new QTreeWidgetItem( this );
2448 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2450 QFont f = item->font( 0 );
2452 for ( int i = 0; i < columnCount(); i++ ) {
2453 if ( ( flags & Bold ) && ( i == 0 || flags & All ))
2454 item->setFont( i, f );
2457 item->setExpanded( true );
2462 \brief Show mesh info
2463 \param mesh mesh object
2464 \param parent parent tree item
2466 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2469 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2470 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2471 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2472 typeItem->setText( 0, tr( "TYPE" ));
2473 if ( !CORBA::is_nil( shape )) {
2474 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ));
2475 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2477 QTreeWidgetItem* gobjItem = createItem( typeItem );
2478 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2479 gobjItem->setText( 1, sobj->GetName().c_str() );
2482 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2483 typeItem->setText( 1, tr( "MESH_FROM_FILE" ));
2484 QTreeWidgetItem* fileItem = createItem( typeItem );
2485 fileItem->setText( 0, tr( "FILE_NAME" ));
2486 fileItem->setText( 1, (char*)inf->fileName );
2489 typeItem->setText( 1, tr( "STANDALONE_MESH" ));
2493 myGroups = mesh->GetGroups();
2497 mySubMeshes = mesh->GetSubMeshes();
2502 \brief Show sub-mesh info
2503 \param subMesh sub-mesh object
2504 \param parent parent tree item
2506 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2508 bool isShort = parent->parent() != 0;
2512 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2514 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2515 nameItem->setText( 0, tr( "PARENT_MESH" ));
2516 nameItem->setText( 1, sobj->GetName().c_str() );
2521 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2522 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2524 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2525 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2526 gobjItem->setText( 1, sobj->GetName().c_str() );
2531 \brief Show group info
2532 \param grp mesh group object
2533 \param parent parent tree item
2535 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2537 bool isShort = parent->parent() != 0;
2539 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2540 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2541 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2545 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2547 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2548 nameItem->setText( 0, tr( "PARENT_MESH" ));
2549 nameItem->setText( 1, sobj->GetName().c_str() );
2553 // type : group on geometry, standalone group, group on filter
2554 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2555 typeItem->setText( 0, tr( "TYPE" ));
2556 if ( !CORBA::is_nil( aStdGroup )) {
2557 typeItem->setText( 1, tr( "STANDALONE_GROUP" ));
2559 else if ( !CORBA::is_nil( aGeomGroup )) {
2560 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ));
2561 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2562 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2564 QTreeWidgetItem* gobjItem = createItem( typeItem );
2565 gobjItem->setText( 0, tr( "GEOM_OBJECT" ));
2566 gobjItem->setText( 1, sobj->GetName().c_str() );
2569 else if ( !CORBA::is_nil( aFltGroup )) {
2570 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ));
2575 QString etype = tr( "UNKNOWN" );
2576 switch( grp->GetType() ) {
2578 etype = tr( "NODE" );
2581 etype = tr( "EDGE" );
2584 etype = tr( "FACE" );
2587 etype = tr( "VOLUME" );
2590 etype = tr( "0DELEM" );
2593 etype = tr( "BALL" );
2598 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2599 etypeItem->setText( 0, tr( "ENTITY_TYPE" ));
2600 etypeItem->setText( 1, etype );
2603 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2604 bool meshLoaded = mesh->IsLoaded();
2606 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2608 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2609 groupSize = grp->Size();
2611 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2612 sizeItem->setText( 0, tr( "SIZE" ));
2613 if ( groupSize > -1 ) {
2614 sizeItem->setText( 1, QString::number( groupSize ));
2617 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2618 setItemWidget( sizeItem, 1, btn );
2619 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2620 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2621 myComputors.append( comp );
2623 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2627 SALOMEDS::Color color = grp->GetColor();
2628 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2629 colorItem->setText( 0, tr( "COLOR" ));
2630 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ));
2632 // nb of underlying nodes
2633 if ( grp->GetType() != SMESH::NODE) {
2634 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2635 nodesItem->setText( 0, tr( "NB_NODES" ));
2636 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2637 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2638 if ( toShowNodes && meshLoaded ) {
2639 // already calculated and up-to-date
2640 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ));
2643 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2644 setItemWidget( nodesItem, 1, btn );
2645 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2646 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ));
2647 myComputors.append( comp );
2649 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ));
2654 void SMESHGUI_AddInfo::showGroups()
2656 myComputors.clear();
2658 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2659 if ( !parent ) return;
2661 int idx = property( "group_index" ).toInt();
2663 QTreeWidgetItem* itemGroups = 0;
2664 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2665 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2666 itemGroups = parent->child( i );
2667 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ));
2669 extra->updateControls( myGroups->length(), idx );
2670 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2674 QMap<int, QTreeWidgetItem*> grpItems;
2675 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2676 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2677 if ( CORBA::is_nil( grp )) continue;
2678 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2679 if ( !grpSObj ) continue;
2681 int grpType = grp->GetType();
2683 if ( !itemGroups ) {
2684 // create top-level groups container item
2685 itemGroups = createItem( parent, Bold | All );
2686 itemGroups->setText( 0, tr( "GROUPS" ));
2687 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2689 // total number of groups > 10, show extra widgets for info browsing
2690 if ((int) myGroups->length() > MAXITEMS ) {
2691 ExtraWidget* extra = new ExtraWidget( this, true );
2692 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ));
2693 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ));
2694 setItemWidget( itemGroups, 1, extra );
2695 extra->updateControls( myGroups->length(), idx );
2699 if ( grpItems.find( grpType ) == grpItems.end() ) {
2700 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2701 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ));
2702 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2706 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2707 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2710 groupInfo( grp.in(), grpNameItem );
2714 void SMESHGUI_AddInfo::showSubMeshes()
2716 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2717 if ( !parent ) return;
2719 int idx = property( "submesh_index" ).toInt();
2721 QTreeWidgetItem* itemSubMeshes = 0;
2722 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2723 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2724 itemSubMeshes = parent->child( i );
2725 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ));
2727 extra->updateControls( mySubMeshes->length(), idx );
2728 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2732 QMap<int, QTreeWidgetItem*> smItems;
2733 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2734 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2735 if ( CORBA::is_nil( sm )) continue;
2736 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2737 if ( !smSObj ) continue;
2739 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2740 if ( CORBA::is_nil(gobj )) continue;
2742 int smType = gobj->GetShapeType();
2743 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2745 if ( !itemSubMeshes ) {
2746 itemSubMeshes = createItem( parent, Bold | All );
2747 itemSubMeshes->setText( 0, tr( "SUBMESHES" ));
2748 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2750 // total number of sub-meshes > 10, show extra widgets for info browsing
2751 if ((int) mySubMeshes->length() > MAXITEMS ) {
2752 ExtraWidget* extra = new ExtraWidget( this, true );
2753 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ));
2754 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ));
2755 setItemWidget( itemSubMeshes, 1, extra );
2756 extra->updateControls( mySubMeshes->length(), idx );
2760 if ( smItems.find( smType ) == smItems.end() ) {
2761 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2762 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ));
2763 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2767 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2768 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2771 subMeshInfo( sm.in(), smNameItem );
2776 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2778 void SMESHGUI_AddInfo::changeLoadToCompute()
2780 for ( int i = 0; i < myComputors.count(); ++i )
2782 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2784 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 )) )
2785 btn->setText( tr("COMPUTE") );
2790 void SMESHGUI_AddInfo::showPreviousGroups()
2792 int idx = property( "group_index" ).toInt();
2793 setProperty( "group_index", idx-1 );
2797 void SMESHGUI_AddInfo::showNextGroups()
2799 int idx = property( "group_index" ).toInt();
2800 setProperty( "group_index", idx+1 );
2804 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2806 int idx = property( "submesh_index" ).toInt();
2807 setProperty( "submesh_index", idx-1 );
2811 void SMESHGUI_AddInfo::showNextSubMeshes()
2813 int idx = property( "submesh_index" ).toInt();
2814 setProperty( "submesh_index", idx+1 );
2818 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2820 out << QString( 15, '-') << "\n";
2821 out << tr( "ADDITIONAL_INFO" ) << "\n";
2822 out << QString( 15, '-' ) << "\n";
2823 QTreeWidgetItemIterator it( this );
2825 if ( !( ( *it )->text(0) ).isEmpty() ) {
2826 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2827 if ( ( *it )->text(0) == tr( "COLOR" )) {
2828 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2830 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2839 \class SMESHGUI_MeshInfoDlg
2840 \brief Mesh information dialog box
2845 \param parent parent widget
2846 \param page specifies the dialog page to be shown at the start-up
2848 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2849 : QDialog( parent ), myActor( 0 )
2852 setAttribute( Qt::WA_DeleteOnClose, true );
2853 setWindowTitle( tr( "MESH_INFO" ));
2854 setSizeGripEnabled( true );
2856 myTabWidget = new QTabWidget( this );
2860 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2861 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ));
2865 QWidget* w = new QWidget( myTabWidget );
2867 myMode = new QButtonGroup( this );
2868 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2869 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2870 myMode->button( NodeMode )->setChecked( true );
2871 myID = new QLineEdit( w );
2872 myID->setValidator( new SMESHGUI_IdValidator( this ));
2873 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
2874 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
2876 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2877 mode = qMin( 1, qMax( 0, mode ));
2880 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2882 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2884 QGridLayout* elemLayout = new QGridLayout( w );
2885 elemLayout->setMargin( MARGIN );
2886 elemLayout->setSpacing( SPACING );
2887 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2888 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2889 elemLayout->addWidget( myID, 0, 2 );
2890 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 );
2891 elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 );
2893 myTabWidget->addTab( w, tr( "ELEM_INFO" ));
2897 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2898 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ));
2902 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2903 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ));
2907 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2908 okBtn->setAutoDefault( true );
2909 okBtn->setDefault( true );
2911 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2912 dumpBtn->setAutoDefault( true );
2913 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2914 helpBtn->setAutoDefault( true );
2916 QHBoxLayout* btnLayout = new QHBoxLayout;
2917 btnLayout->setSpacing( SPACING );
2918 btnLayout->setMargin( 0 );
2920 btnLayout->addWidget( okBtn );
2921 btnLayout->addWidget( dumpBtn );
2922 btnLayout->addStretch( 10 );
2923 btnLayout->addWidget( helpBtn );
2925 QVBoxLayout* l = new QVBoxLayout ( this );
2926 l->setMargin( MARGIN );
2927 l->setSpacing( SPACING );
2928 l->addWidget( myTabWidget );
2929 l->addLayout( btnLayout );
2931 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page )));
2933 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
2934 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
2935 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
2936 connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() ));
2937 connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() ));
2938 connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() ));
2939 connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) ));
2940 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
2941 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
2942 connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int )));
2943 connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
2951 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2957 \brief Show mesh information
2958 \param IO interactive object
2960 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2965 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2966 if ( !CORBA::is_nil( obj ))
2968 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2969 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2970 if ( myTabWidget->currentIndex() == CtrlInfo )
2971 myCtrlInfo->showInfo( obj );
2974 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2975 SVTK_Selector* selector = SMESH::GetSelector();
2978 if ( myActor && selector ) {
2979 nb = myMode->checkedId() == NodeMode ?
2980 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2981 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2983 myElemInfo->setSource( myActor ) ;
2985 myID->setText( ID.trimmed() );
2987 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2988 foreach ( ID, idTxt )
2989 ids << ID.trimmed().toLong();
2990 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2994 myElemInfo->clear();
3001 \brief Perform clean-up actions on the dialog box closing.
3003 void SMESHGUI_MeshInfoDlg::reject()
3005 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3006 selMgr->clearFilters();
3007 SMESH::SetPointRepresentation( false );
3008 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3009 aViewWindow->SetSelectionMode( ActorSelection );
3011 myIDPreview->SetPointsLabeled(false);
3015 \brief Process keyboard event
3016 \param e key press event
3018 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3020 QDialog::keyPressEvent( e );
3021 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3028 \brief Reactivate dialog box, when mouse pointer goes into it.
3030 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3036 \brief Setup selection mode depending on the current dialog box state.
3038 void SMESHGUI_MeshInfoDlg::updateSelection()
3040 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3042 disconnect( selMgr, 0, this, 0 );
3043 selMgr->clearFilters();
3045 if ( myTabWidget->currentIndex() == BaseInfo ||
3046 myTabWidget->currentIndex() == AddInfo ||
3047 myTabWidget->currentIndex() == CtrlInfo ) {
3048 SMESH::SetPointRepresentation( false );
3049 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3050 aViewWindow->SetSelectionMode( ActorSelection );
3053 if ( myMode->checkedId() == NodeMode ) {
3054 SMESH::SetPointRepresentation( true );
3055 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3056 aViewWindow->SetSelectionMode( NodeSelection );
3059 SMESH::SetPointRepresentation( false );
3060 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3061 aViewWindow->SetSelectionMode( CellSelection );
3065 QString oldID = myID->text().trimmed();
3066 SMESH_Actor* oldActor = myActor;
3069 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3072 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3073 myID->setText( oldID );
3079 \brief Show help page
3081 void SMESHGUI_MeshInfoDlg::help()
3083 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3084 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3085 "mesh_infos_page.html#mesh_element_info_anchor" );
3089 \brief Show mesh information
3091 void SMESHGUI_MeshInfoDlg::updateInfo()
3093 SUIT_OverrideCursor wc;
3095 SALOME_ListIO selected;
3096 SMESHGUI::selectionMgr()->selectedObjects( selected );
3098 if ( selected.Extent() == 1 ) {
3099 Handle(SALOME_InteractiveObject) IO = selected.First();
3108 \brief Activate dialog box
3110 void SMESHGUI_MeshInfoDlg::activate()
3112 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3113 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3114 myTabWidget->setEnabled( true );
3119 \brief Deactivate dialog box
3121 void SMESHGUI_MeshInfoDlg::deactivate()
3123 myTabWidget->setEnabled( false );
3124 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3128 \brief Called when users switches between node / element modes.
3130 void SMESHGUI_MeshInfoDlg::modeChanged()
3137 \brief Called when users prints mesh element ID in the corresponding field.
3139 void SMESHGUI_MeshInfoDlg::idChanged()
3141 myIDPreview->SetPointsLabeled( false );
3143 SVTK_Selector* selector = SMESH::GetSelector();
3144 if ( myActor && selector ) {
3145 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3146 TColStd_MapOfInteger ID;
3148 std::vector<int> idVec;
3149 std::list< gp_XYZ > aGrCentersXYZ;
3150 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3151 foreach ( QString tid, idTxt ) {
3152 long id = tid.trimmed().toLong();
3153 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3154 myActor->GetObject()->GetMesh()->FindElement( id ) :
3155 myActor->GetObject()->GetMesh()->FindNode( id );
3159 if ( myMode->checkedId() == ElemMode )
3161 idVec.push_back( id );
3162 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ));
3166 selector->AddOrRemoveIndex( IO, ID, false );
3167 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3169 if ( myMode->checkedId() == NodeMode )
3170 myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID );
3172 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3174 bool showIDs = ( !ID.IsEmpty() &&
3175 myIDPreviewCheck->isChecked() &&
3176 myTabWidget->currentIndex() == ElemInfo );
3177 myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() );
3179 aViewWindow->highlight( IO, true, true );
3180 aViewWindow->Repaint();
3182 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3187 * \brief Show IDs clicked
3189 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3191 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3192 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3193 aViewWindow->Repaint();
3196 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3198 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) {
3199 myMode->button( NodeMode )->click();
3200 myID->setText( QString::number( id ));
3204 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3206 if ( !theStr.isEmpty() ) {
3207 myMode->button( ElemMode )->click();
3208 myID->setText( theStr );
3212 void SMESHGUI_MeshInfoDlg::dump()
3214 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3216 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3217 if ( !appStudy ) return;
3218 _PTR( Study ) aStudy = appStudy->studyDS();
3220 QStringList aFilters;
3221 aFilters.append( tr( "TEXT_FILES" ));
3223 bool anIsBase = true;
3224 bool anIsElem = true;
3225 bool anIsAdd = true;
3226 bool anIsCtrl = true;
3228 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3229 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3230 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3231 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3232 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3235 DumpFileDlg fd( this );
3236 fd.setWindowTitle( tr( "SAVE_INFO" ));
3237 fd.setNameFilters( aFilters );
3238 fd.myBaseChk->setChecked( anIsBase );
3239 fd.myElemChk->setChecked( anIsElem );
3240 fd.myAddChk ->setChecked( anIsAdd );
3241 fd.myCtrlChk->setChecked( anIsCtrl );
3242 if ( fd.exec() == QDialog::Accepted )
3244 QString aFileName = fd.selectedFile();
3246 bool toBase = fd.myBaseChk->isChecked();
3247 bool toElem = fd.myElemChk->isChecked();
3248 bool toAdd = fd.myAddChk->isChecked();
3249 bool toCtrl = fd.myCtrlChk->isChecked();
3251 if ( !aFileName.isEmpty() ) {
3252 QFileInfo aFileInfo( aFileName );
3253 if ( aFileInfo.isDir() )
3256 QFile aFile( aFileName );
3257 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3260 QTextStream out( &aFile );
3262 if ( toBase ) myBaseInfo->saveInfo( out );
3263 if ( toElem ) myElemInfo->saveInfo( out );
3264 if ( toAdd ) myAddInfo ->saveInfo( out );
3265 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3271 \class SMESHGUI_CtrlInfo
3272 \brief Class for the mesh controls information widget.
3277 \param parent parent widget
3279 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3280 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3282 setFrameStyle( StyledPanel | Sunken );
3284 myMainLayout = new QGridLayout( this );
3285 myMainLayout->setMargin( MARGIN );
3286 myMainLayout->setSpacing( SPACING );
3289 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3290 QLabel* aName = createField();
3291 aName->setMinimumWidth( 150 );
3294 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3295 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) );
3297 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3300 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3301 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3302 QLabel* aNodesFree = createField();
3303 myWidgets << aNodesFree;
3304 myPredicates << aFilterMgr->CreateFreeNodes();
3306 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3307 QLabel* aNodesNbConn = createField();
3308 myWidgets << aNodesNbConn;
3309 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3311 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3312 QLabel* aNodesDouble = createField();
3313 myWidgets << aNodesDouble;
3314 myPredicates << aFilterMgr->CreateEqualNodes();
3315 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3316 myToleranceWidget = new SMESHGUI_SpinBox( this );
3317 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3318 myToleranceWidget->setAcceptNames( false );
3319 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ));
3322 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3323 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3324 QLabel* anEdgesDouble = createField();
3325 myWidgets << anEdgesDouble;
3326 myPredicates << aFilterMgr->CreateEqualEdges();
3329 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3330 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3331 QLabel* aFacesDouble = createField();
3332 myWidgets << aFacesDouble;
3333 myPredicates << aFilterMgr->CreateEqualFaces();
3334 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3335 QLabel* aFacesOver = createField();
3336 myWidgets << aFacesOver;
3337 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3338 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3339 myPlot = createPlot( this );
3340 myAspectRatio = aFilterMgr->CreateAspectRatio();
3343 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3344 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3345 QLabel* aVolumesDouble = createField();
3346 myWidgets << aVolumesDouble;
3347 myPredicates << aFilterMgr->CreateEqualVolumes();
3348 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3349 QLabel* aVolumesOver = createField();
3350 myWidgets << aVolumesOver;
3351 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3352 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3353 myPlot3D = createPlot( this );
3354 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3356 QToolButton* aFreeNodesBtn = new QToolButton( this );
3357 aFreeNodesBtn->setIcon(aComputeIcon);
3358 myButtons << aFreeNodesBtn; //0
3360 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3361 aNodesNbConnBtn->setIcon(aComputeIcon);
3362 myButtons << aNodesNbConnBtn; //1
3364 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3365 aDoubleNodesBtn->setIcon(aComputeIcon);
3366 myButtons << aDoubleNodesBtn; //2
3368 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3369 aDoubleEdgesBtn->setIcon(aComputeIcon);
3370 myButtons << aDoubleEdgesBtn; //3
3372 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3373 aDoubleFacesBtn->setIcon(aComputeIcon);
3374 myButtons << aDoubleFacesBtn; //4
3376 QToolButton* aOverContFacesBtn = new QToolButton( this );
3377 aOverContFacesBtn->setIcon(aComputeIcon);
3378 myButtons << aOverContFacesBtn; //5
3380 QToolButton* aComputeFaceBtn = new QToolButton( this );
3381 aComputeFaceBtn->setIcon(aComputeIcon);
3382 myButtons << aComputeFaceBtn; //6
3384 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3385 aDoubleVolumesBtn->setIcon(aComputeIcon);
3386 myButtons << aDoubleVolumesBtn; //7
3388 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3389 aOverContVolumesBtn->setIcon(aComputeIcon);
3390 myButtons << aOverContVolumesBtn; //8
3392 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3393 aComputeVolumeBtn->setIcon(aComputeIcon);
3394 myButtons << aComputeVolumeBtn; //9
3396 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ));
3397 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ));
3398 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ));
3399 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ));
3400 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ));
3401 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ));
3402 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ));
3403 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ));
3404 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ));
3405 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ));
3406 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3408 setFontAttributes( aNameLab );
3409 setFontAttributes( aNodesLab );
3410 setFontAttributes( anEdgesLab );
3411 setFontAttributes( aFacesLab );
3412 setFontAttributes( aVolumesLab );
3414 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3415 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3416 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3417 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3418 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3419 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3420 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3421 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3422 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3423 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3424 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3425 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3426 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3427 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3428 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3429 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3430 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3431 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3432 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3433 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3434 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3435 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3436 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3437 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3438 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3439 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3440 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3441 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3442 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3443 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3444 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3445 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3446 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3447 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3448 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3449 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3450 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3451 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3453 myMainLayout->setColumnStretch( 0, 0 );
3454 myMainLayout->setColumnStretch( 1, 5 );
3455 myMainLayout->setRowStretch ( 11, 5 );
3456 myMainLayout->setRowStretch ( 16, 5 );
3457 myMainLayout->setRowStretch ( 17, 1 );
3465 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3469 \brief Change widget font attributes (bold, ...).
3471 \param attr font attributes (XORed flags)
3473 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3476 QFont f = w->font();
3483 \brief Create info field
3484 \return new info field
3486 QLabel* SMESHGUI_CtrlInfo::createField()
3488 QLabel* lab = new QLabel( this );
3489 lab->setFrameStyle( StyledPanel | Sunken );
3490 lab->setAlignment( Qt::AlignCenter );
3491 lab->setAutoFillBackground( true );
3492 QPalette pal = lab->palette();
3493 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ));
3494 lab->setPalette( pal );
3495 lab->setMinimumWidth( 60 );
3500 \brief Create QwtPlot
3503 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3505 QwtPlot* aPlot = new QwtPlot( parent );
3506 aPlot->setMinimumSize( 100, 100 );
3507 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3508 xFont.setPointSize( 5 );
3509 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3510 yFont.setPointSize( 5 );
3511 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3512 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3518 \brief Show controls information on the selected object
3520 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3524 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3525 if ( myObject->_is_nil() ) return;
3527 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3528 myWidgets[0]->setText( aSO->GetName().c_str() );
3530 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3531 if ( mesh->_is_nil() ) return;
3533 const bool meshLoaded = mesh->IsLoaded();
3534 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3535 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3536 for ( int i = 0; i < myButtons.count(); ++i )
3537 myButtons[i]->setEnabled( true );
3539 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3540 if ( ! &nbElemsByType.in() ) return;
3542 const CORBA::Long ctrlLimit =
3543 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3546 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3547 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3548 nbElemsByType[ SMESH::FACE ] +
3549 nbElemsByType[ SMESH::VOLUME ] );
3550 if ( nbNodes + nbElems > 0 ) {
3551 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3553 computeFreeNodesInfo();
3554 computeNodesNbConnInfo();
3556 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3557 computeDoubleNodesInfo();
3560 myButtons[0]->setEnabled( true );
3561 myButtons[1]->setEnabled( true );
3562 myButtons[2]->setEnabled( true );
3566 for( int i=2; i<=11; i++)
3567 myMainLayout->itemAt(i)->widget()->setVisible( false );
3571 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3573 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3574 computeDoubleEdgesInfo();
3576 myButtons[3]->setEnabled( true );
3579 for( int i=11; i<=14; i++)
3580 myMainLayout->itemAt(i)->widget()->setVisible( false );
3584 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3585 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3587 computeDoubleFacesInfo();
3588 // over constrained faces
3589 computeOverConstrainedFacesInfo();
3590 // aspect Ratio histogram
3591 computeAspectRatio();
3594 myButtons[4]->setEnabled( true );
3595 myButtons[5]->setEnabled( true );
3596 myButtons[6]->setEnabled( true );
3598 #ifdef DISABLE_PLOT2DVIEWER
3599 myMainLayout->setRowStretch(12,0);
3600 for( int i=25; i<=27; i++)
3601 myMainLayout->itemAt(i)->widget()->setVisible( false );
3605 myMainLayout->setRowStretch(12,0);
3606 for( int i=18; i<=27; i++)
3607 myMainLayout->itemAt(i)->widget()->setVisible( false );
3611 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3612 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3614 computeDoubleVolumesInfo();
3615 // over constrained volumes
3616 computeOverConstrainedVolumesInfo();
3617 // aspect Ratio 3D histogram
3618 computeAspectRatio3D();
3621 myButtons[7]->setEnabled( true );
3622 myButtons[8]->setEnabled( true );
3623 myButtons[9]->setEnabled( true );
3625 #ifdef DISABLE_PLOT2DVIEWER
3626 myMainLayout->setRowStretch(17,0);
3627 for( int i=35; i<=37; i++)
3628 myMainLayout->itemAt(i)->widget()->setVisible( false );
3632 myMainLayout->setRowStretch(17,0);
3633 for( int i=28; i<=37; i++)
3634 myMainLayout->itemAt(i)->widget()->setVisible( false );
3638 //================================================================================
3640 * \brief Computes and shows nb of elements satisfying a given predicate
3641 * \param [in] ft - a predicate type (SMESH::FunctorType)
3642 * \param [in] iBut - index of one of myButtons to disable
3643 * \param [in] iWdg - index of one of myWidgets to show the computed number
3645 //================================================================================
3647 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3649 myButtons[ iBut ]->setEnabled( false );
3650 myWidgets[ iWdg ]->setText( "" );
3651 if ( myObject->_is_nil() ) return;
3653 SUIT_OverrideCursor wc;
3655 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3656 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3659 this->showInfo( myObject ); // try to show all values
3660 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3661 return; // <ft> predicate already computed
3663 // look for a predicate of type <ft>
3664 for ( int i = 0; i < myPredicates.count(); ++i )
3665 if ( myPredicates[i]->GetFunctorType() == ft )
3667 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3668 myWidgets[ iWdg ]->setText( QString::number( nb ));
3672 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3674 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3677 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3679 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3682 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3684 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3687 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3689 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3692 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3694 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3697 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3699 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3702 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3704 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3707 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3709 myButtons[ 1 ]->setEnabled( false );
3710 myWidgets[ 2 ]->setText( "" );
3711 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3712 if ( mesh->_is_nil() ) return;
3713 if ( !mesh->IsLoaded() )
3716 this->showInfo( myObject ); // try to show all values
3717 if ( !myWidgets[ 2 ]->text().isEmpty() )
3718 return; // already computed
3720 myNodeConnFunctor->SetMesh( mesh );
3721 SMESH::Histogram_var histogram =
3722 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3724 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3727 void SMESHGUI_CtrlInfo::computeAspectRatio()
3729 #ifndef DISABLE_PLOT2DVIEWER
3730 myButtons[6]->setEnabled( false );
3732 if ( myObject->_is_nil() ) return;
3734 SUIT_OverrideCursor wc;
3736 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3737 if ( aHistogram && !aHistogram->isEmpty() ) {
3738 QwtPlotItem* anItem = aHistogram->createPlotItem();
3739 anItem->attach( myPlot );
3746 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3748 #ifndef DISABLE_PLOT2DVIEWER
3749 myButtons[9]->setEnabled( false );
3751 if ( myObject->_is_nil() ) return;
3753 SUIT_OverrideCursor wc;
3755 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3756 if ( aHistogram && !aHistogram->isEmpty() ) {
3757 QwtPlotItem* anItem = aHistogram->createPlotItem();
3758 anItem->attach( myPlot3D );
3766 \brief Internal clean-up (reset widget)
3768 void SMESHGUI_CtrlInfo::clearInternal()
3770 for( int i=0; i<=35; i++)
3771 myMainLayout->itemAt(i)->widget()->setVisible( true );
3772 for( int i=0; i<=9; i++)
3773 myButtons[i]->setEnabled( false );
3774 myPlot->detachItems();
3775 myPlot3D->detachItems();
3778 myWidgets[0]->setText( QString() );
3779 for ( int i = 1; i < myWidgets.count(); i++ )
3780 myWidgets[i]->setText( "" );
3781 myMainLayout->setRowStretch(11,5);
3782 myMainLayout->setRowStretch(16,5);
3785 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3787 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3788 myButtons[1]->setEnabled( true );
3789 myWidgets[2]->setText("");
3792 #ifndef DISABLE_PLOT2DVIEWER
3793 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3795 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3796 if ( mesh->_is_nil() ) return 0;
3797 if ( !mesh->IsLoaded() )
3799 aNumFun->SetMesh( mesh );
3801 CORBA::Long cprecision = 6;
3802 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ))
3803 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3804 aNumFun->SetPrecision( cprecision );
3806 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3808 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3809 /*isLogarithmic=*/false,
3811 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3812 aHistogram->setColor( palette().color( QPalette::Highlight ));
3813 if ( &histogramVar.in() )
3815 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3816 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3817 if ( histogramVar->length() >= 2 )
3818 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3824 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3825 out << QString( 20, '-' ) << "\n";
3826 out << tr( "CTRL_INFO" ) << "\n";
3827 out << QString( 20, '-' ) << "\n";
3828 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3829 out << tr( "NODES_INFO" ) << "\n";
3830 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3831 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3832 out << tr( "EDGES_INFO" ) << "\n";
3833 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3834 out << tr( "FACES_INFO" ) << "\n";
3835 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3836 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3837 out << tr( "VOLUMES_INFO" ) << "\n";
3838 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3839 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3843 \class SMESHGUI_CtrlInfoDlg
3844 \brief Controls information dialog box
3849 \param parent parent widget
3851 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3854 setAttribute( Qt::WA_DeleteOnClose, true );
3855 setWindowTitle( tr( "CTRL_INFO" ));
3856 setMinimumSize( 400, 600 );
3858 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3861 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3862 okBtn->setAutoDefault( true );
3863 okBtn->setDefault( true );
3865 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3866 dumpBtn->setAutoDefault( true );
3867 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3868 helpBtn->setAutoDefault( true );
3870 QHBoxLayout* btnLayout = new QHBoxLayout;
3871 btnLayout->setSpacing( SPACING );
3872 btnLayout->setMargin( 0 );
3874 btnLayout->addWidget( okBtn );
3875 btnLayout->addWidget( dumpBtn );
3876 btnLayout->addStretch( 10 );
3877 btnLayout->addWidget( helpBtn );
3879 QVBoxLayout* l = new QVBoxLayout ( this );
3880 l->setMargin( MARGIN );
3881 l->setSpacing( SPACING );
3882 l->addWidget( myCtrlInfo );
3883 l->addLayout( btnLayout );
3885 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
3886 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
3887 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
3888 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
3889 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
3897 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3902 \brief Show controls information
3903 \param IO interactive object
3905 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3907 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ))
3908 myCtrlInfo->showInfo( obj );
3912 \brief Perform clean-up actions on the dialog box closing.
3914 void SMESHGUI_CtrlInfoDlg::reject()
3916 SMESH::SetPointRepresentation( false );
3921 \brief Setup selection mode depending on the current dialog box state.
3923 void SMESHGUI_CtrlInfoDlg::updateSelection()
3925 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3926 disconnect( selMgr, 0, this, 0 );
3927 SMESH::SetPointRepresentation( false );
3928 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3933 \brief Show mesh information
3935 void SMESHGUI_CtrlInfoDlg::updateInfo()
3937 SUIT_OverrideCursor wc;
3939 SALOME_ListIO selected;
3940 SMESHGUI::selectionMgr()->selectedObjects( selected );
3942 if ( selected.Extent() == 1 ) {
3943 Handle(SALOME_InteractiveObject) IO = selected.First();
3949 \brief Activate dialog box
3951 void SMESHGUI_CtrlInfoDlg::activate()
3953 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3954 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3959 \brief Deactivate dialog box
3961 void SMESHGUI_CtrlInfoDlg::deactivate()
3963 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ));
3967 * \brief Dump contents into a file
3969 void SMESHGUI_CtrlInfoDlg::dump()
3971 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3973 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3974 if ( !appStudy ) return;
3975 _PTR( Study ) aStudy = appStudy->studyDS();
3977 QStringList aFilters;
3978 aFilters.append( tr( "TEXT_FILES" ));
3980 DumpFileDlg fd( this );
3981 fd.setWindowTitle( tr( "SAVE_INFO" ));
3982 fd.setNameFilters( aFilters );
3983 fd.myBaseChk->hide();
3984 fd.myElemChk->hide();
3985 fd.myAddChk ->hide();
3986 fd.myCtrlChk->hide();
3987 if ( fd.exec() == QDialog::Accepted )
3989 QString aFileName = fd.selectedFile();
3990 if ( !aFileName.isEmpty() ) {
3991 QFileInfo aFileInfo( aFileName );
3992 if ( aFileInfo.isDir() )
3995 QFile aFile( aFileName );
3996 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ))
3999 QTextStream out( &aFile );
4000 myCtrlInfo->saveInfo( out );
4008 void SMESHGUI_CtrlInfoDlg::help()
4010 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");