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 ) ) );
1667 \brief Show mesh element information
1668 \param ids mesh nodes / elements identifiers
1670 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1675 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1676 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1677 int cprecision = -1;
1678 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1679 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1680 foreach ( long id, ids ) {
1681 if ( !isElements() ) {
1685 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1687 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1690 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1691 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1692 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1694 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1695 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1696 QTreeWidgetItem* xItem = createItem( coordItem );
1697 xItem->setText( 0, "X" );
1698 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1699 QTreeWidgetItem* yItem = createItem( coordItem );
1700 yItem->setText( 0, "Y" );
1701 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1702 QTreeWidgetItem* zItem = createItem( coordItem );
1703 zItem->setText( 0, "Z" );
1704 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1706 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1707 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1708 Connectivity connectivity = nodeConnectivity( node );
1709 if ( !connectivity.isEmpty() ) {
1710 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1711 if ( !con.isEmpty() ) {
1712 QTreeWidgetItem* i = createItem( conItem );
1713 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1714 i->setText( 1, con );
1716 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1717 if ( !con.isEmpty() ) {
1718 QTreeWidgetItem* i = createItem( conItem );
1719 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1720 i->setText( 1, con );
1721 i->setData( 1, TypeRole, NodeConnectivity );
1723 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1724 if ( !con.isEmpty() ) {
1725 QTreeWidgetItem* i = createItem( conItem );
1726 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1727 i->setText( 1, con );
1728 i->setData( 1, TypeRole, NodeConnectivity );
1730 con = formatConnectivity( connectivity, SMDSAbs_Face );
1731 if ( !con.isEmpty() ) {
1732 QTreeWidgetItem* i = createItem( conItem );
1733 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1734 i->setText( 1, con );
1735 i->setData( 1, TypeRole, NodeConnectivity );
1737 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1738 if ( !con.isEmpty() ) {
1739 QTreeWidgetItem* i = createItem( conItem );
1740 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1741 i->setText( 1, con );
1742 i->setData( 1, TypeRole, NodeConnectivity );
1746 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1749 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1750 if ( !CORBA::is_nil( aMeshPtr ) ) {
1751 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1752 int shapeID = pos->shapeID;
1753 if ( shapeID > 0 ) {
1755 double u = 0, v = 0;
1756 switch ( pos->shapeType ) {
1758 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1759 if ( pos->params.length() == 1 )
1763 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1764 if ( pos->params.length() == 2 ) {
1770 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1773 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1776 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1777 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1778 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1779 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1780 QTreeWidgetItem* uItem = createItem( posItem );
1781 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1782 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1783 if ( pos->shapeType == GEOM::FACE ) {
1784 QTreeWidgetItem* vItem = createItem( posItem );
1785 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1786 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1791 // groups node belongs to
1792 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1793 if ( !CORBA::is_nil( aMesh ) ) {
1794 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1795 QTreeWidgetItem* groupsItem = 0;
1796 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
1797 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1798 if ( CORBA::is_nil( aGrp ) ) continue;
1799 QString aName = aGrp->GetName();
1800 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1801 if ( !groupsItem ) {
1802 groupsItem = createItem( nodeItem, Bold );
1803 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1805 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1806 it->setText( 0, aName.trimmed() );
1807 if ( grp_details ) {
1808 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1809 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1810 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1812 // type : group on geometry, standalone group, group on filter
1813 QTreeWidgetItem* typeItem = createItem( it );
1814 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1815 if ( !CORBA::is_nil( aStdGroup ) ) {
1816 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1818 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1819 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1820 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1821 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1823 QTreeWidgetItem* gobjItem = createItem( typeItem );
1824 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1825 gobjItem->setText( 1, sobj->GetName().c_str() );
1828 else if ( !CORBA::is_nil( aFltGroup ) ) {
1829 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1833 QTreeWidgetItem* sizeItem = createItem( it );
1834 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1835 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1838 SALOMEDS::Color color = aGrp->GetColor();
1839 QTreeWidgetItem* colorItem = createItem( it );
1840 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1841 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1849 // show element info
1851 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1852 SMESH::Controls::NumericalFunctorPtr afunctor;
1855 // element ID && type
1857 switch( e->GetType() ) {
1858 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1859 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1860 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1861 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1862 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1865 if ( stype.isEmpty() ) return;
1866 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1867 elemItem->setText( 0, stype );
1868 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1871 switch( e->GetEntityType() ) {
1872 case SMDSEntity_Triangle:
1873 case SMDSEntity_Quad_Triangle:
1874 case SMDSEntity_BiQuad_Triangle:
1875 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1876 case SMDSEntity_Quadrangle:
1877 case SMDSEntity_Quad_Quadrangle:
1878 case SMDSEntity_BiQuad_Quadrangle:
1879 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1880 case SMDSEntity_Polygon:
1881 case SMDSEntity_Quad_Polygon:
1882 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1883 case SMDSEntity_Tetra:
1884 case SMDSEntity_Quad_Tetra:
1885 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1886 case SMDSEntity_Pyramid:
1887 case SMDSEntity_Quad_Pyramid:
1888 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1889 case SMDSEntity_Hexa:
1890 case SMDSEntity_Quad_Hexa:
1891 case SMDSEntity_TriQuad_Hexa:
1892 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1893 case SMDSEntity_Penta:
1894 case SMDSEntity_Quad_Penta:
1895 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1896 case SMDSEntity_Hexagonal_Prism:
1897 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1898 case SMDSEntity_Polyhedra:
1899 case SMDSEntity_Quad_Polyhedra:
1900 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1904 if ( !gtype.isEmpty() ) {
1905 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1906 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1907 typeItem->setText( 1, gtype );
1909 // quadratic flag (for edges, faces and volumes)
1910 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1912 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1913 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1914 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1916 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1918 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1919 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1920 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1923 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1924 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1927 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1928 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1929 for ( int idx = 1; nodeIt->more(); idx++ ) {
1930 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1931 nodeInfo( node, idx, e->NbNodes(), conItem );
1935 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1936 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1937 QList<const SMDS_MeshElement*> uniqueNodes;
1938 while ( nodeIt->more() )
1939 uniqueNodes.append( nodeIt->next() );
1941 SMDS_VolumeTool vtool( e );
1942 const int nbFaces = vtool.NbFaces();
1943 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1944 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1945 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1946 faceItem->setExpanded( true );
1948 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1949 const int nbNodes = vtool.NbFaceNodes( face_id );
1950 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1951 const SMDS_MeshNode* node = aNodeIds[node_id];
1952 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1957 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1958 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1960 if( e->GetType()==SMDSAbs_Edge){
1961 afunctor.reset( new SMESH::Controls::Length() );
1962 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1963 afunctor->SetPrecision( cprecision );
1964 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1965 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1966 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1968 if( e->GetType() == SMDSAbs_Face ) {
1970 afunctor.reset( new SMESH::Controls::Area() );
1971 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1972 afunctor->SetPrecision( cprecision );
1973 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1974 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1975 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1977 if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx
1979 afunctor.reset( new SMESH::Controls::Taper() );
1980 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1981 afunctor->SetPrecision( cprecision );
1982 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1983 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1984 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1986 afunctor.reset( new SMESH::Controls::Warping() );
1987 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1988 afunctor->SetPrecision( cprecision );
1989 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1990 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1991 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1996 afunctor.reset( new SMESH::Controls::AspectRatio() );
1997 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1998 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1999 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
2000 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2003 afunctor.reset( new SMESH::Controls::MinimumAngle() );
2004 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2005 afunctor->SetPrecision( cprecision );
2006 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
2007 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
2008 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2010 if ( e->NbNodes() == 3 || e->NbNodes() == 4 )
2012 afunctor.reset( new SMESH::Controls::Skew() );
2013 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2014 afunctor->SetPrecision( cprecision );
2015 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
2016 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
2017 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2022 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
2023 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2024 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
2025 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
2026 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2029 if( e->GetType() == SMDSAbs_Volume ) {
2033 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2034 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2035 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2036 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
2037 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2040 afunctor.reset( new SMESH::Controls::Volume() );
2041 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2042 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2043 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
2044 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2046 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2047 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2048 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2049 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
2050 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2054 XYZ gc = gravityCenter( e );
2055 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2056 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
2057 QTreeWidgetItem* xItem = createItem( gcItem );
2058 xItem->setText( 0, "X" );
2059 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2060 QTreeWidgetItem* yItem = createItem( gcItem );
2061 yItem->setText( 0, "Y" );
2062 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2063 QTreeWidgetItem* zItem = createItem( gcItem );
2064 zItem->setText( 0, "Z" );
2065 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2068 if( e->GetType() == SMDSAbs_Face ) {
2069 XYZ gc = normal( e );
2070 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2071 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2072 QTreeWidgetItem* xItem = createItem( nItem );
2073 xItem->setText( 0, "X" );
2074 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2075 QTreeWidgetItem* yItem = createItem( nItem );
2076 yItem->setText( 0, "Y" );
2077 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2078 QTreeWidgetItem* zItem = createItem( nItem );
2079 zItem->setText( 0, "Z" );
2080 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2084 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2085 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2086 if ( !CORBA::is_nil( aMesh ) ) {
2087 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2088 int shapeID = pos.shapeID;
2089 if ( shapeID > 0 ) {
2090 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2092 switch ( pos.shapeType ) {
2093 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2094 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2095 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2096 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2097 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2098 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2100 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2101 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2105 // groups element belongs to
2106 if ( !CORBA::is_nil( aMesh ) ) {
2107 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2108 QTreeWidgetItem* groupsItem = 0;
2109 for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
2110 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2111 if ( CORBA::is_nil( aGrp ) ) continue;
2112 QString aName = aGrp->GetName();
2113 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2114 if ( !groupsItem ) {
2115 groupsItem = createItem( elemItem, Bold );
2116 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2118 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2119 it->setText( 0, aName.trimmed() );
2120 if ( grp_details ) {
2121 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2122 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2123 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2125 // type : group on geometry, standalone group, group on filter
2126 QTreeWidgetItem* typeItem = createItem( it );
2127 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2128 if ( !CORBA::is_nil( aStdGroup ) ) {
2129 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2131 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2132 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2133 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2134 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2136 QTreeWidgetItem* gobjItem = createItem( typeItem );
2137 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2138 gobjItem->setText( 1, sobj->GetName().c_str() );
2141 else if ( !CORBA::is_nil( aFltGroup ) ) {
2142 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2146 QTreeWidgetItem* sizeItem = createItem( it );
2147 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2148 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2151 SALOMEDS::Color color = aGrp->GetColor();
2152 QTreeWidgetItem* colorItem = createItem( it );
2153 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2154 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2165 \brief Show node information
2166 \param node mesh node for showing
2167 \param index index of current node
2168 \param nbNodes number of unique nodes in element
2169 \param parentItem parent item of tree
2171 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2172 int nbNodes, QTreeWidgetItem* parentItem )
2174 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2175 // node number and ID
2176 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2177 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2178 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2179 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2180 nodeItem->setData( 1, IdRole, node->GetID() );
2181 nodeItem->setExpanded( false );
2183 QTreeWidgetItem* coordItem = createItem( nodeItem );
2184 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2185 QTreeWidgetItem* xItem = createItem( coordItem );
2186 xItem->setText( 0, "X" );
2187 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2188 QTreeWidgetItem* yItem = createItem( coordItem );
2189 yItem->setText( 0, "Y" );
2190 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2191 QTreeWidgetItem* zItem = createItem( coordItem );
2192 zItem->setText( 0, "Z" );
2193 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2194 // node connectivity
2195 QTreeWidgetItem* nconItem = createItem( nodeItem );
2196 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2197 Connectivity connectivity = nodeConnectivity( node );
2198 if ( !connectivity.isEmpty() ) {
2199 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2200 if ( !con.isEmpty() ) {
2201 QTreeWidgetItem* i = createItem( nconItem );
2202 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2203 i->setText( 1, con );
2205 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2206 if ( !con.isEmpty() ) {
2207 QTreeWidgetItem* i = createItem( nconItem );
2208 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2209 i->setText( 1, con );
2210 i->setData( 1, TypeRole, NodeConnectivity );
2212 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2213 if ( !con.isEmpty() ) {
2214 QTreeWidgetItem* i = createItem( nconItem );
2215 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2216 i->setText( 1, con );
2217 i->setData( 1, TypeRole, NodeConnectivity );
2219 con = formatConnectivity( connectivity, SMDSAbs_Face );
2220 if ( !con.isEmpty() ) {
2221 QTreeWidgetItem* i = createItem( nconItem );
2222 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2223 i->setText( 1, con );
2224 i->setData( 1, TypeRole, NodeConnectivity );
2226 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2227 if ( !con.isEmpty() ) {
2228 QTreeWidgetItem* i = createItem( nconItem );
2229 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2230 i->setText( 1, con );
2231 i->setData( 1, TypeRole, NodeConnectivity );
2236 \brief Internal clean-up (reset widget)
2238 void SMESHGUI_TreeElemInfo::clearInternal()
2245 \brief Create new tree item.
2246 \param parent parent tree widget item
2247 \param flags item flag
2248 \return new tree widget item
2250 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2252 QTreeWidgetItem* item;
2254 item = new QTreeWidgetItem( parent );
2256 item = new QTreeWidgetItem( myInfo );
2258 item->setFlags( item->flags() | Qt::ItemIsEditable );
2260 QFont f = item->font( 0 );
2262 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2263 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2264 item->setFont( i, f );
2267 item->setExpanded( true );
2271 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2273 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2274 if ( widgets.isEmpty() ) return;
2275 QTreeWidgetItem* aTreeItem = widgets.first();
2276 int type = aTreeItem->data( 1, TypeRole ).toInt();
2277 int id = aTreeItem->data( 1, IdRole ).toInt();
2279 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2280 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2281 emit( itemInfo( id ) );
2282 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2283 emit( itemInfo( aTreeItem->text( 1 ) ) );
2286 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2289 int type = theItem->data( 1, TypeRole ).toInt();
2290 int id = theItem->data( 1, IdRole ).toInt();
2291 if ( type == ElemConnectivity && id > 0 )
2292 emit( itemInfo( id ) );
2293 else if ( type == NodeConnectivity )
2294 emit( itemInfo( theItem->text( 1 ) ) );
2298 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2300 out << QString( 12, '-' ) << "\n";
2301 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2302 out << QString( 12, '-' ) << "\n";
2304 QTreeWidgetItemIterator it( myInfo );
2306 if ( !( *it )->text(0).isEmpty() ) {
2307 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2308 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2318 \brief Mesh information computer
2321 The class is created for different computation operation. Currently it is used
2322 to compute number of underlying nodes for the groups.
2328 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
2329 QTreeWidgetItem* item,
2332 : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
2334 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2338 \brief Compute function
2340 void GrpComputor::compute()
2342 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2343 SUIT_OverrideCursor wc;
2344 QTreeWidgetItem* item = myItem;
2346 int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
2347 item->treeWidget()->removeItemWidget( item, 1 );
2348 item->setText( 1, QString::number( nb ));
2353 \class SMESHGUI_AddInfo
2354 \brief The wigdet shows additional information on the mesh object.
2359 \param parent parent widget
2361 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2362 : QTreeWidget( parent )
2364 setColumnCount( 2 );
2365 header()->setStretchLastSection( true );
2366 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2367 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2369 header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2377 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2382 \brief Show additional information on the selected object
2383 \param obj object being processed (mesh, sub-mesh, group, ID source)
2385 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2387 setProperty( "group_index", 0 );
2388 setProperty( "submesh_index", 0 );
2389 myComputors.clear();
2392 if ( CORBA::is_nil( obj ) ) return;
2394 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2395 if ( !sobj ) return;
2398 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2399 nameItem->setText( 0, tr( "NAME" ) );
2400 nameItem->setText( 1, sobj->GetName().c_str() );
2402 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2403 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2404 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2406 if ( !aMesh->_is_nil() )
2407 meshInfo( aMesh, nameItem );
2408 else if ( !aSubMesh->_is_nil() )
2409 subMeshInfo( aSubMesh, nameItem );
2410 else if ( !aGroup->_is_nil() )
2411 groupInfo( aGroup.in(), nameItem );
2415 \brief Create new tree item.
2416 \param parent parent tree widget item
2417 \param flags item flag
2418 \return new tree widget item
2420 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2422 QTreeWidgetItem* item;
2425 item = new QTreeWidgetItem( parent );
2427 item = new QTreeWidgetItem( this );
2429 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2431 QFont f = item->font( 0 );
2433 for ( int i = 0; i < columnCount(); i++ ) {
2434 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2435 item->setFont( i, f );
2438 item->setExpanded( true );
2443 \brief Show mesh info
2444 \param mesh mesh object
2445 \param parent parent tree item
2447 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2450 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2451 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2452 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2453 typeItem->setText( 0, tr( "TYPE" ) );
2454 if ( !CORBA::is_nil( shape ) ) {
2455 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2456 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2458 QTreeWidgetItem* gobjItem = createItem( typeItem );
2459 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2460 gobjItem->setText( 1, sobj->GetName().c_str() );
2463 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2464 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2465 QTreeWidgetItem* fileItem = createItem( typeItem );
2466 fileItem->setText( 0, tr( "FILE_NAME" ) );
2467 fileItem->setText( 1, (char*)inf->fileName );
2470 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2474 myGroups = mesh->GetGroups();
2478 mySubMeshes = mesh->GetSubMeshes();
2483 \brief Show sub-mesh info
2484 \param subMesh sub-mesh object
2485 \param parent parent tree item
2487 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2489 bool isShort = parent->parent() != 0;
2493 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2495 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2496 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2497 nameItem->setText( 1, sobj->GetName().c_str() );
2502 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2503 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2505 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2506 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2507 gobjItem->setText( 1, sobj->GetName().c_str() );
2512 \brief Show group info
2513 \param grp mesh group object
2514 \param parent parent tree item
2516 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2518 bool isShort = parent->parent() != 0;
2520 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2521 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2522 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2526 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2528 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2529 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2530 nameItem->setText( 1, sobj->GetName().c_str() );
2534 // type : group on geometry, standalone group, group on filter
2535 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2536 typeItem->setText( 0, tr( "TYPE" ) );
2537 if ( !CORBA::is_nil( aStdGroup ) ) {
2538 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2540 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2541 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2542 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2543 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2545 QTreeWidgetItem* gobjItem = createItem( typeItem );
2546 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2547 gobjItem->setText( 1, sobj->GetName().c_str() );
2550 else if ( !CORBA::is_nil( aFltGroup ) ) {
2551 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2556 QString etype = tr( "UNKNOWN" );
2557 switch( grp->GetType() ) {
2559 etype = tr( "NODE" );
2562 etype = tr( "EDGE" );
2565 etype = tr( "FACE" );
2568 etype = tr( "VOLUME" );
2571 etype = tr( "0DELEM" );
2574 etype = tr( "BALL" );
2579 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2580 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2581 etypeItem->setText( 1, etype );
2584 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2585 bool meshLoaded = mesh->IsLoaded();
2587 // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
2589 if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
2590 groupSize = grp->Size();
2592 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2593 sizeItem->setText( 0, tr( "SIZE" ) );
2594 if ( groupSize > -1 ) {
2595 sizeItem->setText( 1, QString::number( groupSize ) );
2598 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2599 setItemWidget( sizeItem, 1, btn );
2600 GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
2601 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2602 myComputors.append( comp );
2604 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2608 SALOMEDS::Color color = grp->GetColor();
2609 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2610 colorItem->setText( 0, tr( "COLOR" ) );
2611 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2613 // nb of underlying nodes
2614 if ( grp->GetType() != SMESH::NODE) {
2615 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2616 nodesItem->setText( 0, tr( "NB_NODES" ) );
2617 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2618 bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
2619 if ( toShowNodes && meshLoaded ) {
2620 // already calculated and up-to-date
2621 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2624 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2625 setItemWidget( nodesItem, 1, btn );
2626 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2627 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2628 myComputors.append( comp );
2630 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2635 void SMESHGUI_AddInfo::showGroups()
2637 myComputors.clear();
2639 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2640 if ( !parent ) return;
2642 int idx = property( "group_index" ).toInt();
2644 QTreeWidgetItem* itemGroups = 0;
2645 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2646 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2647 itemGroups = parent->child( i );
2648 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2650 extra->updateControls( myGroups->length(), idx );
2651 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2655 QMap<int, QTreeWidgetItem*> grpItems;
2656 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2657 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2658 if ( CORBA::is_nil( grp ) ) continue;
2659 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2660 if ( !grpSObj ) continue;
2662 int grpType = grp->GetType();
2664 if ( !itemGroups ) {
2665 // create top-level groups container item
2666 itemGroups = createItem( parent, Bold | All );
2667 itemGroups->setText( 0, tr( "GROUPS" ) );
2668 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2670 // total number of groups > 10, show extra widgets for info browsing
2671 if ((int) myGroups->length() > MAXITEMS ) {
2672 ExtraWidget* extra = new ExtraWidget( this, true );
2673 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2674 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2675 setItemWidget( itemGroups, 1, extra );
2676 extra->updateControls( myGroups->length(), idx );
2680 if ( grpItems.find( grpType ) == grpItems.end() ) {
2681 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2682 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2683 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2687 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2688 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2691 groupInfo( grp.in(), grpNameItem );
2695 void SMESHGUI_AddInfo::showSubMeshes()
2697 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2698 if ( !parent ) return;
2700 int idx = property( "submesh_index" ).toInt();
2702 QTreeWidgetItem* itemSubMeshes = 0;
2703 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2704 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2705 itemSubMeshes = parent->child( i );
2706 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2708 extra->updateControls( mySubMeshes->length(), idx );
2709 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2713 QMap<int, QTreeWidgetItem*> smItems;
2714 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2715 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2716 if ( CORBA::is_nil( sm ) ) continue;
2717 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2718 if ( !smSObj ) continue;
2720 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2721 if ( CORBA::is_nil(gobj ) ) continue;
2723 int smType = gobj->GetShapeType();
2724 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2726 if ( !itemSubMeshes ) {
2727 itemSubMeshes = createItem( parent, Bold | All );
2728 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2729 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2731 // total number of sub-meshes > 10, show extra widgets for info browsing
2732 if ((int) mySubMeshes->length() > MAXITEMS ) {
2733 ExtraWidget* extra = new ExtraWidget( this, true );
2734 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2735 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2736 setItemWidget( itemSubMeshes, 1, extra );
2737 extra->updateControls( mySubMeshes->length(), idx );
2741 if ( smItems.find( smType ) == smItems.end() ) {
2742 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2743 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2744 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2748 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2749 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2752 subMeshInfo( sm.in(), smNameItem );
2757 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2759 void SMESHGUI_AddInfo::changeLoadToCompute()
2761 for ( int i = 0; i < myComputors.count(); ++i )
2763 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2765 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2766 btn->setText( tr("COMPUTE") );
2771 void SMESHGUI_AddInfo::showPreviousGroups()
2773 int idx = property( "group_index" ).toInt();
2774 setProperty( "group_index", idx-1 );
2778 void SMESHGUI_AddInfo::showNextGroups()
2780 int idx = property( "group_index" ).toInt();
2781 setProperty( "group_index", idx+1 );
2785 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2787 int idx = property( "submesh_index" ).toInt();
2788 setProperty( "submesh_index", idx-1 );
2792 void SMESHGUI_AddInfo::showNextSubMeshes()
2794 int idx = property( "submesh_index" ).toInt();
2795 setProperty( "submesh_index", idx+1 );
2799 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2801 out << QString( 15, '-') << "\n";
2802 out << tr( "ADDITIONAL_INFO" ) << "\n";
2803 out << QString( 15, '-' ) << "\n";
2804 QTreeWidgetItemIterator it( this );
2806 if ( !( ( *it )->text(0) ).isEmpty() ) {
2807 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2808 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2809 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2811 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2820 \class SMESHGUI_MeshInfoDlg
2821 \brief Mesh information dialog box
2826 \param parent parent widget
2827 \param page specifies the dialog page to be shown at the start-up
2829 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2830 : QDialog( parent ), myActor( 0 )
2833 setAttribute( Qt::WA_DeleteOnClose, true );
2834 setWindowTitle( tr( "MESH_INFO" ) );
2835 setSizeGripEnabled( true );
2837 myTabWidget = new QTabWidget( this );
2841 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2842 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2846 QWidget* w = new QWidget( myTabWidget );
2848 myMode = new QButtonGroup( this );
2849 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2850 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2851 myMode->button( NodeMode )->setChecked( true );
2852 myID = new QLineEdit( w );
2853 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2854 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
2855 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
2857 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2858 mode = qMin( 1, qMax( 0, mode ) );
2861 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2863 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2865 QGridLayout* elemLayout = new QGridLayout( w );
2866 elemLayout->setMargin( MARGIN );
2867 elemLayout->setSpacing( SPACING );
2868 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2869 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2870 elemLayout->addWidget( myID, 0, 2 );
2871 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 );
2872 elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 );
2874 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2878 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2879 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2883 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2884 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2888 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2889 okBtn->setAutoDefault( true );
2890 okBtn->setDefault( true );
2892 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2893 dumpBtn->setAutoDefault( true );
2894 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2895 helpBtn->setAutoDefault( true );
2897 QHBoxLayout* btnLayout = new QHBoxLayout;
2898 btnLayout->setSpacing( SPACING );
2899 btnLayout->setMargin( 0 );
2901 btnLayout->addWidget( okBtn );
2902 btnLayout->addWidget( dumpBtn );
2903 btnLayout->addStretch( 10 );
2904 btnLayout->addWidget( helpBtn );
2906 QVBoxLayout* l = new QVBoxLayout ( this );
2907 l->setMargin( MARGIN );
2908 l->setSpacing( SPACING );
2909 l->addWidget( myTabWidget );
2910 l->addLayout( btnLayout );
2912 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page )));
2914 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ));
2915 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ));
2916 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ));
2917 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ));
2918 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ));
2919 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ));
2920 connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) ));
2921 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ));
2922 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ));
2923 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int )));
2924 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString )));
2932 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2938 \brief Show mesh information
2939 \param IO interactive object
2941 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2946 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2947 if ( !CORBA::is_nil( obj ) )
2949 myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo,
2950 myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
2951 if ( myTabWidget->currentIndex() == CtrlInfo )
2952 myCtrlInfo->showInfo( obj );
2955 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2956 SVTK_Selector* selector = SMESH::GetSelector();
2959 if ( myActor && selector ) {
2960 nb = myMode->checkedId() == NodeMode ?
2961 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2962 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2964 myElemInfo->setSource( myActor ) ;
2966 myID->setText( ID.trimmed() );
2968 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2969 foreach ( ID, idTxt )
2970 ids << ID.trimmed().toLong();
2971 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2975 myElemInfo->clear();
2982 \brief Perform clean-up actions on the dialog box closing.
2984 void SMESHGUI_MeshInfoDlg::reject()
2986 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2987 selMgr->clearFilters();
2988 SMESH::SetPointRepresentation( false );
2989 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2990 aViewWindow->SetSelectionMode( ActorSelection );
2992 myIDPreview->SetPointsLabeled(false);
2996 \brief Process keyboard event
2997 \param e key press event
2999 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3001 QDialog::keyPressEvent( e );
3002 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3009 \brief Reactivate dialog box, when mouse pointer goes into it.
3011 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
3017 \brief Setup selection mode depending on the current dialog box state.
3019 void SMESHGUI_MeshInfoDlg::updateSelection()
3021 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3023 disconnect( selMgr, 0, this, 0 );
3024 selMgr->clearFilters();
3026 if ( myTabWidget->currentIndex() == BaseInfo ||
3027 myTabWidget->currentIndex() == AddInfo ||
3028 myTabWidget->currentIndex() == CtrlInfo ) {
3029 SMESH::SetPointRepresentation( false );
3030 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3031 aViewWindow->SetSelectionMode( ActorSelection );
3034 if ( myMode->checkedId() == NodeMode ) {
3035 SMESH::SetPointRepresentation( true );
3036 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3037 aViewWindow->SetSelectionMode( NodeSelection );
3040 SMESH::SetPointRepresentation( false );
3041 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3042 aViewWindow->SetSelectionMode( CellSelection );
3046 QString oldID = myID->text().trimmed();
3047 SMESH_Actor* oldActor = myActor;
3050 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3053 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
3054 myID->setText( oldID );
3060 \brief Show help page
3062 void SMESHGUI_MeshInfoDlg::help()
3064 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
3065 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
3066 "mesh_infos_page.html#mesh_element_info_anchor" );
3070 \brief Show mesh information
3072 void SMESHGUI_MeshInfoDlg::updateInfo()
3074 SUIT_OverrideCursor wc;
3076 SALOME_ListIO selected;
3077 SMESHGUI::selectionMgr()->selectedObjects( selected );
3079 if ( selected.Extent() == 1 ) {
3080 Handle(SALOME_InteractiveObject) IO = selected.First();
3089 \brief Activate dialog box
3091 void SMESHGUI_MeshInfoDlg::activate()
3093 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3094 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3095 myTabWidget->setEnabled( true );
3100 \brief Deactivate dialog box
3102 void SMESHGUI_MeshInfoDlg::deactivate()
3104 myTabWidget->setEnabled( false );
3105 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3109 \brief Called when users switches between node / element modes.
3111 void SMESHGUI_MeshInfoDlg::modeChanged()
3118 \brief Called when users prints mesh element ID in the corresponding field.
3120 void SMESHGUI_MeshInfoDlg::idChanged()
3122 myIDPreview->SetPointsLabeled( false );
3124 SVTK_Selector* selector = SMESH::GetSelector();
3125 if ( myActor && selector ) {
3126 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3127 TColStd_MapOfInteger ID;
3129 std::vector<int> idVec;
3130 std::list< gp_XYZ > aGrCentersXYZ;
3131 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3132 foreach ( QString tid, idTxt ) {
3133 long id = tid.trimmed().toLong();
3134 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3135 myActor->GetObject()->GetMesh()->FindElement( id ) :
3136 myActor->GetObject()->GetMesh()->FindNode( id );
3140 if ( myMode->checkedId() == ElemMode )
3142 idVec.push_back( id );
3143 aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e ));
3147 selector->AddOrRemoveIndex( IO, ID, false );
3148 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3150 if ( myMode->checkedId() == NodeMode )
3151 myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID );
3153 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3155 bool showIDs = ( !ID.IsEmpty() &&
3156 myIDPreviewCheck->isChecked() &&
3157 myTabWidget->currentIndex() == ElemInfo );
3158 myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() );
3160 aViewWindow->highlight( IO, true, true );
3161 aViewWindow->Repaint();
3163 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3168 * \brief Show IDs clicked
3170 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3172 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3173 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3174 aViewWindow->Repaint();
3177 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3179 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3180 myMode->button( NodeMode )->click();
3181 myID->setText( QString::number( id ) );
3185 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3187 if ( !theStr.isEmpty() ) {
3188 myMode->button( ElemMode )->click();
3189 myID->setText( theStr );
3193 void SMESHGUI_MeshInfoDlg::dump()
3195 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3197 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3198 if ( !appStudy ) return;
3199 _PTR( Study ) aStudy = appStudy->studyDS();
3201 QStringList aFilters;
3202 aFilters.append( tr( "TEXT_FILES" ) );
3204 bool anIsBase = true;
3205 bool anIsElem = true;
3206 bool anIsAdd = true;
3207 bool anIsCtrl = true;
3209 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3210 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3211 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3212 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3213 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3216 DumpFileDlg fd( this );
3217 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3218 fd.setNameFilters( aFilters );
3219 fd.myBaseChk->setChecked( anIsBase );
3220 fd.myElemChk->setChecked( anIsElem );
3221 fd.myAddChk ->setChecked( anIsAdd );
3222 fd.myCtrlChk->setChecked( anIsCtrl );
3223 if ( fd.exec() == QDialog::Accepted )
3225 QString aFileName = fd.selectedFile();
3227 bool toBase = fd.myBaseChk->isChecked();
3228 bool toElem = fd.myElemChk->isChecked();
3229 bool toAdd = fd.myAddChk->isChecked();
3230 bool toCtrl = fd.myCtrlChk->isChecked();
3232 if ( !aFileName.isEmpty() ) {
3233 QFileInfo aFileInfo( aFileName );
3234 if ( aFileInfo.isDir() )
3237 QFile aFile( aFileName );
3238 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3241 QTextStream out( &aFile );
3243 if ( toBase ) myBaseInfo->saveInfo( out );
3244 if ( toElem ) myElemInfo->saveInfo( out );
3245 if ( toAdd ) myAddInfo ->saveInfo( out );
3246 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3252 \class SMESHGUI_CtrlInfo
3253 \brief Class for the mesh controls information widget.
3258 \param parent parent widget
3260 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3261 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3263 setFrameStyle( StyledPanel | Sunken );
3265 myMainLayout = new QGridLayout( this );
3266 myMainLayout->setMargin( MARGIN );
3267 myMainLayout->setSpacing( SPACING );
3270 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3271 QLabel* aName = createField();
3272 aName->setMinimumWidth( 150 );
3275 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3276 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3278 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3281 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3282 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3283 QLabel* aNodesFree = createField();
3284 myWidgets << aNodesFree;
3285 myPredicates << aFilterMgr->CreateFreeNodes();
3287 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3288 QLabel* aNodesNbConn = createField();
3289 myWidgets << aNodesNbConn;
3290 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3292 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3293 QLabel* aNodesDouble = createField();
3294 myWidgets << aNodesDouble;
3295 myPredicates << aFilterMgr->CreateEqualNodes();
3296 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3297 myToleranceWidget = new SMESHGUI_SpinBox( this );
3298 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3299 myToleranceWidget->setAcceptNames( false );
3300 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3303 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3304 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3305 QLabel* anEdgesDouble = createField();
3306 myWidgets << anEdgesDouble;
3307 myPredicates << aFilterMgr->CreateEqualEdges();
3310 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3311 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3312 QLabel* aFacesDouble = createField();
3313 myWidgets << aFacesDouble;
3314 myPredicates << aFilterMgr->CreateEqualFaces();
3315 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3316 QLabel* aFacesOver = createField();
3317 myWidgets << aFacesOver;
3318 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3319 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3320 myPlot = createPlot( this );
3321 myAspectRatio = aFilterMgr->CreateAspectRatio();
3324 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3325 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3326 QLabel* aVolumesDouble = createField();
3327 myWidgets << aVolumesDouble;
3328 myPredicates << aFilterMgr->CreateEqualVolumes();
3329 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3330 QLabel* aVolumesOver = createField();
3331 myWidgets << aVolumesOver;
3332 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3333 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3334 myPlot3D = createPlot( this );
3335 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3337 QToolButton* aFreeNodesBtn = new QToolButton( this );
3338 aFreeNodesBtn->setIcon(aComputeIcon);
3339 myButtons << aFreeNodesBtn; //0
3341 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3342 aNodesNbConnBtn->setIcon(aComputeIcon);
3343 myButtons << aNodesNbConnBtn; //1
3345 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3346 aDoubleNodesBtn->setIcon(aComputeIcon);
3347 myButtons << aDoubleNodesBtn; //2
3349 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3350 aDoubleEdgesBtn->setIcon(aComputeIcon);
3351 myButtons << aDoubleEdgesBtn; //3
3353 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3354 aDoubleFacesBtn->setIcon(aComputeIcon);
3355 myButtons << aDoubleFacesBtn; //4
3357 QToolButton* aOverContFacesBtn = new QToolButton( this );
3358 aOverContFacesBtn->setIcon(aComputeIcon);
3359 myButtons << aOverContFacesBtn; //5
3361 QToolButton* aComputeFaceBtn = new QToolButton( this );
3362 aComputeFaceBtn->setIcon(aComputeIcon);
3363 myButtons << aComputeFaceBtn; //6
3365 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3366 aDoubleVolumesBtn->setIcon(aComputeIcon);
3367 myButtons << aDoubleVolumesBtn; //7
3369 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3370 aOverContVolumesBtn->setIcon(aComputeIcon);
3371 myButtons << aOverContVolumesBtn; //8
3373 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3374 aComputeVolumeBtn->setIcon(aComputeIcon);
3375 myButtons << aComputeVolumeBtn; //9
3377 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3378 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3379 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3380 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3381 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3382 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3383 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3384 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3385 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3386 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3387 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3389 setFontAttributes( aNameLab );
3390 setFontAttributes( aNodesLab );
3391 setFontAttributes( anEdgesLab );
3392 setFontAttributes( aFacesLab );
3393 setFontAttributes( aVolumesLab );
3395 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3396 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3397 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3398 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3399 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3400 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3401 myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6
3402 myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7
3403 myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8
3404 myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9
3405 myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10
3406 myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11
3407 myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12
3408 myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13
3409 myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14
3410 myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15
3411 myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16
3412 myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17
3413 myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18
3414 myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19
3415 myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20
3416 myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21
3417 myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22
3418 myMainLayout->addWidget( aFacesOver, 10, 1 ); //23
3419 myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24
3420 myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25
3421 myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26
3422 myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27
3423 myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28
3424 myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29
3425 myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30
3426 myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31
3427 myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32
3428 myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33
3429 myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34
3430 myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35
3431 myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36
3432 myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37
3434 myMainLayout->setColumnStretch( 0, 0 );
3435 myMainLayout->setColumnStretch( 1, 5 );
3436 myMainLayout->setRowStretch ( 11, 5 );
3437 myMainLayout->setRowStretch ( 16, 5 );
3438 myMainLayout->setRowStretch ( 17, 1 );
3446 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3450 \brief Change widget font attributes (bold, ...).
3452 \param attr font attributes (XORed flags)
3454 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3457 QFont f = w->font();
3464 \brief Create info field
3465 \return new info field
3467 QLabel* SMESHGUI_CtrlInfo::createField()
3469 QLabel* lab = new QLabel( this );
3470 lab->setFrameStyle( StyledPanel | Sunken );
3471 lab->setAlignment( Qt::AlignCenter );
3472 lab->setAutoFillBackground( true );
3473 QPalette pal = lab->palette();
3474 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3475 lab->setPalette( pal );
3476 lab->setMinimumWidth( 60 );
3481 \brief Create QwtPlot
3484 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3486 QwtPlot* aPlot = new QwtPlot( parent );
3487 aPlot->setMinimumSize( 100, 100 );
3488 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3489 xFont.setPointSize( 5 );
3490 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3491 yFont.setPointSize( 5 );
3492 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3493 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3499 \brief Show controls information on the selected object
3501 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3505 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3506 if ( myObject->_is_nil() ) return;
3508 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3509 myWidgets[0]->setText( aSO->GetName().c_str() );
3511 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3512 if ( mesh->_is_nil() ) return;
3514 const bool meshLoaded = mesh->IsLoaded();
3515 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3516 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3517 for ( int i = 0; i < myButtons.count(); ++i )
3518 myButtons[i]->setEnabled( true );
3520 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3521 if ( ! &nbElemsByType.in() ) return;
3523 const CORBA::Long ctrlLimit =
3524 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3527 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3528 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3529 nbElemsByType[ SMESH::FACE ] +
3530 nbElemsByType[ SMESH::VOLUME ] );
3531 if ( nbNodes + nbElems > 0 ) {
3532 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3534 computeFreeNodesInfo();
3535 computeNodesNbConnInfo();
3537 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3538 computeDoubleNodesInfo();
3541 myButtons[0]->setEnabled( true );
3542 myButtons[1]->setEnabled( true );
3543 myButtons[2]->setEnabled( true );
3547 for( int i=2; i<=11; i++)
3548 myMainLayout->itemAt(i)->widget()->setVisible( false );
3552 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3554 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3555 computeDoubleEdgesInfo();
3557 myButtons[3]->setEnabled( true );
3560 for( int i=11; i<=14; i++)
3561 myMainLayout->itemAt(i)->widget()->setVisible( false );
3565 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3566 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3568 computeDoubleFacesInfo();
3569 // over constrained faces
3570 computeOverConstrainedFacesInfo();
3571 // aspect Ratio histogram
3572 computeAspectRatio();
3575 myButtons[4]->setEnabled( true );
3576 myButtons[5]->setEnabled( true );
3577 myButtons[6]->setEnabled( true );
3579 #ifdef DISABLE_PLOT2DVIEWER
3580 myMainLayout->setRowStretch(12,0);
3581 for( int i=25; i<=27; i++)
3582 myMainLayout->itemAt(i)->widget()->setVisible( false );
3586 myMainLayout->setRowStretch(12,0);
3587 for( int i=18; i<=27; i++)
3588 myMainLayout->itemAt(i)->widget()->setVisible( false );
3592 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3593 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3595 computeDoubleVolumesInfo();
3596 // over constrained volumes
3597 computeOverConstrainedVolumesInfo();
3598 // aspect Ratio 3D histogram
3599 computeAspectRatio3D();
3602 myButtons[7]->setEnabled( true );
3603 myButtons[8]->setEnabled( true );
3604 myButtons[9]->setEnabled( true );
3606 #ifdef DISABLE_PLOT2DVIEWER
3607 myMainLayout->setRowStretch(17,0);
3608 for( int i=35; i<=37; i++)
3609 myMainLayout->itemAt(i)->widget()->setVisible( false );
3613 myMainLayout->setRowStretch(17,0);
3614 for( int i=28; i<=37; i++)
3615 myMainLayout->itemAt(i)->widget()->setVisible( false );
3619 //================================================================================
3621 * \brief Computes and shows nb of elements satisfying a given predicate
3622 * \param [in] ft - a predicate type (SMESH::FunctorType)
3623 * \param [in] iBut - index of one of myButtons to disable
3624 * \param [in] iWdg - index of one of myWidgets to show the computed number
3626 //================================================================================
3628 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3630 myButtons[ iBut ]->setEnabled( false );
3631 myWidgets[ iWdg ]->setText( "" );
3632 if ( myObject->_is_nil() ) return;
3634 SUIT_OverrideCursor wc;
3636 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3637 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3640 this->showInfo( myObject ); // try to show all values
3641 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3642 return; // <ft> predicate already computed
3644 // look for a predicate of type <ft>
3645 for ( int i = 0; i < myPredicates.count(); ++i )
3646 if ( myPredicates[i]->GetFunctorType() == ft )
3648 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3649 myWidgets[ iWdg ]->setText( QString::number( nb ));
3653 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3655 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3658 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3660 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3663 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3665 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3668 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3670 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3673 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3675 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3678 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3680 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3683 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3685 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3688 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3690 myButtons[ 1 ]->setEnabled( false );
3691 myWidgets[ 2 ]->setText( "" );
3692 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3693 if ( mesh->_is_nil() ) return;
3694 if ( !mesh->IsLoaded() )
3697 this->showInfo( myObject ); // try to show all values
3698 if ( !myWidgets[ 2 ]->text().isEmpty() )
3699 return; // already computed
3701 myNodeConnFunctor->SetMesh( mesh );
3702 SMESH::Histogram_var histogram =
3703 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject );
3705 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ));
3708 void SMESHGUI_CtrlInfo::computeAspectRatio()
3710 #ifndef DISABLE_PLOT2DVIEWER
3711 myButtons[6]->setEnabled( false );
3713 if ( myObject->_is_nil() ) return;
3715 SUIT_OverrideCursor wc;
3717 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3718 if ( aHistogram && !aHistogram->isEmpty() ) {
3719 QwtPlotItem* anItem = aHistogram->createPlotItem();
3720 anItem->attach( myPlot );
3727 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3729 #ifndef DISABLE_PLOT2DVIEWER
3730 myButtons[9]->setEnabled( false );
3732 if ( myObject->_is_nil() ) return;
3734 SUIT_OverrideCursor wc;
3736 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3737 if ( aHistogram && !aHistogram->isEmpty() ) {
3738 QwtPlotItem* anItem = aHistogram->createPlotItem();
3739 anItem->attach( myPlot3D );
3747 \brief Internal clean-up (reset widget)
3749 void SMESHGUI_CtrlInfo::clearInternal()
3751 for( int i=0; i<=35; i++)
3752 myMainLayout->itemAt(i)->widget()->setVisible( true );
3753 for( int i=0; i<=9; i++)
3754 myButtons[i]->setEnabled( false );
3755 myPlot->detachItems();
3756 myPlot3D->detachItems();
3759 myWidgets[0]->setText( QString() );
3760 for ( int i = 1; i < myWidgets.count(); i++ )
3761 myWidgets[i]->setText( "" );
3762 myMainLayout->setRowStretch(11,5);
3763 myMainLayout->setRowStretch(16,5);
3766 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3768 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3769 myButtons[1]->setEnabled( true );
3770 myWidgets[2]->setText("");
3773 #ifndef DISABLE_PLOT2DVIEWER
3774 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3776 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3777 if ( mesh->_is_nil() ) return 0;
3778 if ( !mesh->IsLoaded() )
3780 aNumFun->SetMesh( mesh );
3782 CORBA::Long cprecision = 6;
3783 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3784 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3785 aNumFun->SetPrecision( cprecision );
3787 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3789 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3790 /*isLogarithmic=*/false,
3792 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3793 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3794 if ( &histogramVar.in() )
3796 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3797 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3798 if ( histogramVar->length() >= 2 )
3799 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3805 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3806 out << QString( 20, '-' ) << "\n";
3807 out << tr( "CTRL_INFO" ) << "\n";
3808 out << QString( 20, '-' ) << "\n";
3809 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3810 out << tr( "NODES_INFO" ) << "\n";
3811 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3812 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3813 out << tr( "EDGES_INFO" ) << "\n";
3814 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3815 out << tr( "FACES_INFO" ) << "\n";
3816 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3817 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3818 out << tr( "VOLUMES_INFO" ) << "\n";
3819 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3820 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3824 \class SMESHGUI_CtrlInfoDlg
3825 \brief Controls information dialog box
3830 \param parent parent widget
3832 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3835 setAttribute( Qt::WA_DeleteOnClose, true );
3836 setWindowTitle( tr( "CTRL_INFO" ) );
3837 setMinimumSize( 400, 600 );
3839 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3842 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3843 okBtn->setAutoDefault( true );
3844 okBtn->setDefault( true );
3846 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3847 dumpBtn->setAutoDefault( true );
3848 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3849 helpBtn->setAutoDefault( true );
3851 QHBoxLayout* btnLayout = new QHBoxLayout;
3852 btnLayout->setSpacing( SPACING );
3853 btnLayout->setMargin( 0 );
3855 btnLayout->addWidget( okBtn );
3856 btnLayout->addWidget( dumpBtn );
3857 btnLayout->addStretch( 10 );
3858 btnLayout->addWidget( helpBtn );
3860 QVBoxLayout* l = new QVBoxLayout ( this );
3861 l->setMargin( MARGIN );
3862 l->setSpacing( SPACING );
3863 l->addWidget( myCtrlInfo );
3864 l->addLayout( btnLayout );
3866 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3867 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3868 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3869 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3870 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3878 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3883 \brief Show controls information
3884 \param IO interactive object
3886 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3888 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3889 myCtrlInfo->showInfo( obj );
3893 \brief Perform clean-up actions on the dialog box closing.
3895 void SMESHGUI_CtrlInfoDlg::reject()
3897 SMESH::SetPointRepresentation( false );
3902 \brief Setup selection mode depending on the current dialog box state.
3904 void SMESHGUI_CtrlInfoDlg::updateSelection()
3906 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3907 disconnect( selMgr, 0, this, 0 );
3908 SMESH::SetPointRepresentation( false );
3909 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3914 \brief Show mesh information
3916 void SMESHGUI_CtrlInfoDlg::updateInfo()
3918 SUIT_OverrideCursor wc;
3920 SALOME_ListIO selected;
3921 SMESHGUI::selectionMgr()->selectedObjects( selected );
3923 if ( selected.Extent() == 1 ) {
3924 Handle(SALOME_InteractiveObject) IO = selected.First();
3930 \brief Activate dialog box
3932 void SMESHGUI_CtrlInfoDlg::activate()
3934 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3935 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3940 \brief Deactivate dialog box
3942 void SMESHGUI_CtrlInfoDlg::deactivate()
3944 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3948 * \brief Dump contents into a file
3950 void SMESHGUI_CtrlInfoDlg::dump()
3952 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3954 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3955 if ( !appStudy ) return;
3956 _PTR( Study ) aStudy = appStudy->studyDS();
3958 QStringList aFilters;
3959 aFilters.append( tr( "TEXT_FILES" ) );
3961 DumpFileDlg fd( this );
3962 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3963 fd.setNameFilters( aFilters );
3964 fd.myBaseChk->hide();
3965 fd.myElemChk->hide();
3966 fd.myAddChk ->hide();
3967 fd.myCtrlChk->hide();
3968 if ( fd.exec() == QDialog::Accepted )
3970 QString aFileName = fd.selectedFile();
3971 if ( !aFileName.isEmpty() ) {
3972 QFileInfo aFileInfo( aFileName );
3973 if ( aFileInfo.isDir() )
3976 QFile aFile( aFileName );
3977 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3980 QTextStream out( &aFile );
3981 myCtrlInfo->saveInfo( out );
3989 void SMESHGUI_CtrlInfoDlg::help()
3991 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");