1 // Copyright (C) 2007-2015 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_IdValidator.h"
37 #include "SMESHGUI_SpinBox.h"
38 #include "SMESHGUI_Utils.h"
39 #include "SMESHGUI_VTKUtils.h"
40 #include "SMESH_Actor.h"
42 #include <LightApp_SelectionMgr.h>
43 #include <SUIT_FileDlg.h>
44 #include <SUIT_OverrideCursor.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SVTK_ViewWindow.h>
49 #include <SALOMEDSClient_Study.hxx>
50 #include <SalomeApp_Study.h>
52 #include <QApplication>
53 #include <QButtonGroup>
55 #include <QContextMenuEvent>
56 #include <QGridLayout>
57 #include <QHBoxLayout>
58 #include <QHeaderView>
59 #include <QItemDelegate>
64 #include <QPushButton>
65 #include <QToolButton>
66 #include <QRadioButton>
67 #include <QTextStream>
69 #include <QTextBrowser>
70 #include <QVBoxLayout>
72 #include "utilities.h"
74 #include <SALOMEconfig.h>
75 #include CORBA_SERVER_HEADER(GEOM_Gen)
79 const int SPACING = 6;
81 const int MAXITEMS = 10;
82 const int GROUPS_ID = 100;
83 const int SUBMESHES_ID = 200;
84 const int SPACING_INFO = 2;
87 TypeRole = Qt::UserRole + 10,
92 NodeConnectivity = 100,
101 class ExtraWidget : public QWidget
104 ExtraWidget( QWidget*, bool = false );
107 void updateControls( int, int, int = MAXITEMS );
116 ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
118 current = new QLabel( this );
119 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
120 prev = new QPushButton( tr( "<<" ), this );
121 next = new QPushButton( tr( ">>" ), this );
122 QHBoxLayout* hbl = new QHBoxLayout( this );
123 hbl->setContentsMargins( 0, SPACING, 0, 0 );
124 hbl->setSpacing( SPACING );
126 hbl->addWidget( current );
127 hbl->addWidget( prev );
128 hbl->addWidget( next );
131 ExtraWidget::~ExtraWidget()
135 void ExtraWidget::updateControls( int total, int index, int blockSize )
137 setVisible( total > blockSize );
138 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
139 current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) );
140 prev->setEnabled( index > 0 );
141 next->setEnabled( (index+1)*blockSize < total );
146 \brief Customization of standard "Save file" dialog box for dump info operation
150 class DumpFileDlg : public SUIT_FileDlg
153 DumpFileDlg( QWidget* parent );
155 QCheckBox* myBaseChk;
156 QCheckBox* myElemChk;
158 QCheckBox* myCtrlChk;
165 DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true )
167 QGridLayout* grid = ::qobject_cast<QGridLayout *>( layout() );
169 QWidget* hB = new QWidget( this );
170 myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
171 myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
172 myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
173 myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
175 QGridLayout* layout = new QGridLayout( hB );
176 layout->addWidget( myBaseChk, 0, 0 );
177 layout->addWidget( myElemChk, 0, 1 );
178 layout->addWidget( myAddChk, 1, 0 );
179 layout->addWidget( myCtrlChk, 1, 1 );
181 QPushButton* pb = new QPushButton( this );
183 int row = grid->rowCount();
184 grid->addWidget( new QLabel( "", this ), row, 0 );
185 grid->addWidget( hB, row, 1, 1, 3 );
186 grid->addWidget( pb, row, 5 );
193 \brief Get depth of the tree item
195 \param theItem tree widget item
196 \return item's depth in tree widget (where top-level items have zero depth)
198 static int itemDepth( QTreeWidgetItem* item )
201 QTreeWidgetItem* p = item->parent();
210 \class SMESHGUI_MeshInfo
211 \brief Base mesh information widget
213 Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
218 \param parent parent widget
220 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
221 : QFrame( parent ), myWidgets( iElementsEnd )
223 setFrameStyle( StyledPanel | Sunken );
225 QGridLayout* l = new QGridLayout( this );
226 l->setMargin( MARGIN );
227 l->setSpacing( SPACING );
232 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
233 QLabel* aName = createField();
234 aName->setObjectName("meshName");
235 aName->setMinimumWidth( 150 );
236 QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this );
237 QLabel* aObj = createField();
238 aObj->setObjectName("meshType");
239 aObj->setMinimumWidth( 150 );
240 myWidgets[ index++ ] << aNameLab << aName;
241 myWidgets[ index++ ] << aObjLab << aObj;
244 QWidget* aNodesLine = createLine();
245 QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this );
246 QLabel* aNodes = createField();
247 aNodes->setObjectName("nbNodes");
248 myWidgets[ index++ ] << aNodesLine;
249 myWidgets[ index++ ] << aNodesLab << aNodes;
252 QWidget* aElemLine = createLine();
253 QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this );
254 QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this );
255 QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this );
256 QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this );
257 QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this );
258 myWidgets[ index++ ] << aElemLine;
259 myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad;
261 // ... Number elements
262 QWidget* aNbLine = createLine();
263 QLabel* aNbTotal = createField();
264 aNbTotal->setObjectName("totalNbElems");
265 QLabel* aNbLin = createField();
266 aNbLin->setObjectName("totalNbLinearElems");
267 QLabel* aNbQuad = createField();
268 aNbQuad->setObjectName("totalNbQuadraticElems");
269 QLabel* aNbBiQuad = createField();
270 aNbQuad->setObjectName("totalNbBiQuadraticElems");
271 myWidgets[ index++ ] << aNbLine;
272 myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
275 QWidget* a0DLine = createLine();
276 QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this );
277 QLabel* a0DTotal = createField();
278 a0DTotal->setObjectName("nb0D");
280 myWidgets[ index++ ] << a0DLine;
281 myWidgets[ index++ ] << a0DLab << a0DTotal;
284 QWidget* aBallLine = createLine();
285 QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this );
286 QLabel* aBallTotal = createField();
287 aBallTotal->setObjectName("nbBall");
288 myWidgets[ index++ ] << aBallLine;
289 myWidgets[ index++ ] << aBallLab << aBallTotal;
292 QWidget* a1DLine = createLine();
293 QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this );
294 QLabel* a1DTotal = createField();
295 a1DTotal->setObjectName("nb1D");
296 QLabel* a1DLin = createField();
297 a1DLin->setObjectName("nbLinear1D");
298 QLabel* a1DQuad = createField();
299 a1DQuad->setObjectName("nbQuadratic1D");
300 myWidgets[ index++ ] << a1DLine;
301 myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
304 QWidget* a2DLine = createLine();
305 QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this );
306 QLabel* a2DTotal = createField();
307 a2DTotal->setObjectName("nb2D");
308 QLabel* a2DLin = createField();
309 a2DLin->setObjectName("nbLinear2D");
310 QLabel* a2DQuad = createField();
311 a2DQuad->setObjectName("nbQuadratic2D");
312 QLabel* a2DBiQuad = createField();
313 a2DBiQuad->setObjectName("nbBiQuadratic2D");
314 QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this );
315 QLabel* a2DTriTotal = createField();
316 a2DTriTotal->setObjectName("nbTriangle");
317 QLabel* a2DTriLin = createField();
318 a2DTriLin->setObjectName("nbLinearTriangle");
319 QLabel* a2DTriQuad = createField();
320 a2DTriQuad->setObjectName("nbQuadraticTriangle");
321 QLabel* a2DTriBiQuad = createField();
322 a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
323 QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this );
324 QLabel* a2DQuaTotal = createField();
325 a2DQuaTotal->setObjectName("nbQuadrangle");
326 QLabel* a2DQuaLin = createField();
327 a2DQuaLin->setObjectName("nbLinearQuadrangle");
328 QLabel* a2DQuaQuad = createField();
329 a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
330 QLabel* a2DQuaBiQuad = createField();
331 a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
332 QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
333 QLabel* a2DPolTotal = createField();
334 a2DPolTotal->setObjectName("nbPolygon");
335 myWidgets[ index++ ] << a2DLine;
336 myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
337 myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
338 myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
339 myWidgets[ index++ ] << a2DPolLab << a2DPolTotal;
342 QWidget* a3DLine = createLine();
343 QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this );
344 QLabel* a3DTotal = createField();
345 a3DTotal->setObjectName("nb3D");
346 QLabel* a3DLin = createField();
347 a3DLin->setObjectName("nbLinear3D");
348 QLabel* a3DQuad = createField();
349 a3DQuad->setObjectName("nbQuadratic3D");
350 QLabel* a3DBiQuad = createField();
351 a3DBiQuad->setObjectName("nbBiQuadratic3D");
352 QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
353 QLabel* a3DTetTotal = createField();
354 a3DTetTotal->setObjectName("nbTetrahedron");
355 QLabel* a3DTetLin = createField();
356 a3DTetLin->setObjectName("nbLinearTetrahedron");
357 QLabel* a3DTetQuad = createField();
358 a3DTetQuad->setObjectName("nbQudraticTetrahedron");
359 QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
360 QLabel* a3DHexTotal = createField();
361 a3DHexTotal->setObjectName("nbHexahedron");
362 QLabel* a3DHexLin = createField();
363 a3DHexLin->setObjectName("nbLinearHexahedron");
364 QLabel* a3DHexQuad = createField();
365 a3DHexQuad->setObjectName("nbQuadraticHexahedron");
366 QLabel* a3DHexBiQuad = createField();
367 a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
368 QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this );
369 QLabel* a3DPyrTotal = createField();
370 a3DPyrTotal->setObjectName("nbPyramid");
371 QLabel* a3DPyrLin = createField();
372 a3DPyrLin->setObjectName("nbLinearPyramid");
373 QLabel* a3DPyrQuad = createField();
374 a3DPyrQuad->setObjectName("nbQuadraticPyramid");
375 QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this );
376 QLabel* a3DPriTotal = createField();
377 a3DPriTotal->setObjectName("nbPrism");
378 QLabel* a3DPriLin = createField();
379 a3DPriLin->setObjectName("nbLinearPrism");
380 QLabel* a3DPriQuad = createField();
381 a3DPriQuad->setObjectName("nbQuadraticPrism");
382 QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
383 QLabel* a3DHexPriTotal = createField();
384 a3DHexPriTotal->setObjectName("nbHexagonalPrism");
385 QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
386 QLabel* a3DPolTotal = createField();
387 a3DPolTotal->setObjectName("nbPolyhedron");
388 myWidgets[ index++ ] << a3DLine;
389 myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad;
390 myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
391 myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
392 myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
393 myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
394 myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
395 myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
397 myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
398 myLoadBtn->setAutoDefault( true );
399 connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
401 setFontAttributes( aNameLab, Bold );
402 setFontAttributes( aObjLab, Bold );
403 setFontAttributes( aNodesLab, Bold );
404 setFontAttributes( aElemLab, Bold );
405 setFontAttributes( aElemTotal, Italic );
406 setFontAttributes( aElemLin, Italic );
407 setFontAttributes( aElemQuad, Italic );
408 setFontAttributes( aElemBiQuad, Italic );
409 setFontAttributes( a0DLab, Bold );
410 setFontAttributes( aBallLab, Bold );
411 setFontAttributes( a1DLab, Bold );
412 setFontAttributes( a2DLab, Bold );
413 setFontAttributes( a3DLab, Bold );
415 l->addWidget( aNameLab, 0, 0 );
416 l->addWidget( aName, 0, 1, 1, 4 );
417 l->addWidget( aObjLab, 1, 0 );
418 l->addWidget( aObj, 1, 1, 1, 4 );
419 l->addWidget( aNodesLine, 2, 0, 1, 5 );
420 l->addWidget( aNodesLab, 3, 0 );
421 l->addWidget( aNodes, 3, 1 );
422 l->addWidget( aElemLine, 4, 0, 1, 5 );
423 l->addWidget( aElemLab, 5, 0 );
424 l->addWidget( aElemTotal, 5, 1 );
425 l->addWidget( aElemLin, 5, 2 );
426 l->addWidget( aElemQuad, 5, 3 );
427 l->addWidget( aElemBiQuad, 5, 4 );
428 l->addWidget( aNbLine, 6, 1, 1, 4 );
429 l->addWidget( aNbTotal, 7, 1 );
430 l->addWidget( aNbLin, 7, 2 );
431 l->addWidget( aNbQuad, 7, 3 );
432 l->addWidget( aNbBiQuad, 7, 4 );
433 l->addWidget( a0DLine, 8, 1, 1, 4 );
434 l->addWidget( a0DLab, 9, 0 );
435 l->addWidget( a0DTotal, 9, 1 );
436 l->addWidget( aBallLine, 10, 1, 1, 4 );
437 l->addWidget( aBallLab, 11, 0 );
438 l->addWidget( aBallTotal, 11, 1 );
439 l->addWidget( a1DLine, 12, 1, 1, 4 );
440 l->addWidget( a1DLab, 13, 0 );
441 l->addWidget( a1DTotal, 13, 1 );
442 l->addWidget( a1DLin, 13, 2 );
443 l->addWidget( a1DQuad, 13, 3 );
444 l->addWidget( a2DLine, 14, 1, 1, 4 );
445 l->addWidget( a2DLab, 15, 0 );
446 l->addWidget( a2DTotal, 15, 1 );
447 l->addWidget( a2DLin, 15, 2 );
448 l->addWidget( a2DQuad, 15, 3 );
449 l->addWidget( a2DBiQuad, 15, 4 );
450 l->addWidget( a2DTriLab, 16, 0 );
451 l->addWidget( a2DTriTotal, 16, 1 );
452 l->addWidget( a2DTriLin, 16, 2 );
453 l->addWidget( a2DTriQuad, 16, 3 );
454 l->addWidget( a2DTriBiQuad, 16, 4 );
455 l->addWidget( a2DQuaLab, 17, 0 );
456 l->addWidget( a2DQuaTotal, 17, 1 );
457 l->addWidget( a2DQuaLin, 17, 2 );
458 l->addWidget( a2DQuaQuad, 17, 3 );
459 l->addWidget( a2DQuaBiQuad, 17, 4 );
460 l->addWidget( a2DPolLab, 18, 0 );
461 l->addWidget( a2DPolTotal, 18, 1 );
462 l->addWidget( a3DLine, 19, 1, 1, 4 );
463 l->addWidget( a3DLab, 20, 0 );
464 l->addWidget( a3DTotal, 20, 1 );
465 l->addWidget( a3DLin, 20, 2 );
466 l->addWidget( a3DQuad, 20, 3 );
467 l->addWidget( a3DBiQuad, 20, 4 );
468 l->addWidget( a3DTetLab, 21, 0 );
469 l->addWidget( a3DTetTotal, 21, 1 );
470 l->addWidget( a3DTetLin, 21, 2 );
471 l->addWidget( a3DTetQuad, 21, 3 );
472 l->addWidget( a3DHexLab, 22, 0 );
473 l->addWidget( a3DHexTotal, 22, 1 );
474 l->addWidget( a3DHexLin, 22, 2 );
475 l->addWidget( a3DHexQuad, 22, 3 );
476 l->addWidget( a3DHexBiQuad, 22, 4 );
477 l->addWidget( a3DPyrLab, 23, 0 );
478 l->addWidget( a3DPyrTotal, 23, 1 );
479 l->addWidget( a3DPyrLin, 23, 2 );
480 l->addWidget( a3DPyrQuad, 23, 3 );
481 l->addWidget( a3DPriLab, 24, 0 );
482 l->addWidget( a3DPriTotal, 24, 1 );
483 l->addWidget( a3DPriLin, 24, 2 );
484 l->addWidget( a3DPriQuad, 24, 3 );
485 l->addWidget( a3DHexPriLab, 25, 0 );
486 l->addWidget( a3DHexPriTotal, 25, 1 );
487 l->addWidget( a3DPolLab, 26, 0 );
488 l->addWidget( a3DPolTotal, 26, 1 );
489 l->addWidget( myLoadBtn, 28, 1, 1, 4 );
491 l->setColumnStretch( 0, 0 );
492 l->setColumnStretch( 1, 5 );
493 l->setColumnStretch( 2, 5 );
494 l->setColumnStretch( 3, 5 );
495 l->setColumnStretch( 4, 5 );
496 l->setRowStretch( 27, 5 );
504 SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
509 \brief Show information on the mesh object.
510 \param obj object being processed (mesh, sub-mesh, group, ID source)
512 void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
515 if ( !CORBA::is_nil( obj ) ) {
516 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
518 myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
519 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
520 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
521 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
522 if ( !aMesh->_is_nil() ) {
523 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
525 else if ( !aSubMesh->_is_nil() ) {
526 myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
528 else if ( !aGroup->_is_nil() ) {
530 switch( aGroup->GetType() ) {
531 case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break;
532 case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break;
533 case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break;
534 case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break;
535 case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break;
536 case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break;
537 default: objType = tr( "OBJECT_GROUP" );break;
539 myWidgets[iObject][iSingle]->setProperty( "text", objType );
541 SMESH::long_array_var info = obj->GetMeshInfo();
542 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
543 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
544 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
545 long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
546 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) );
547 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
548 myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
549 long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
550 long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
551 long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
552 long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle];
553 long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
554 long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
556 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal ));
557 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) );
558 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) );
559 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
560 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) );
561 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
562 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
563 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] ) );
564 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) );
565 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
566 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
567 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
568 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
569 long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
570 long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
571 long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
572 long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
573 long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
574 long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
575 long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
576 long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
577 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ) );
578 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) );
579 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) );
580 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
581 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) );
582 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
583 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
584 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) );
585 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
586 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
587 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] ) );
588 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) );
589 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
590 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
591 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) );
592 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
593 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
594 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
595 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
596 long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
597 long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
598 long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
599 long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
600 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal ) );
601 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial ) );
602 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic ) );
603 myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic ) );
604 // before full loading from study file, type of elements in a sub-mesh can't be defined
606 bool infoOK = obj->IsMeshInfoCorrect();
607 myLoadBtn->setVisible( !infoOK );
611 // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
612 // 2. No info at all (for a group on geom or filter)
613 bool hasAnyInfo = false;
614 for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
615 hasAnyInfo = info[i];
616 if ( hasAnyInfo ) // believe it is a sub-mesh
618 if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 )
620 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
621 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
622 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
623 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
624 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
625 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
626 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
627 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
628 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
629 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
630 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
631 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
632 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
633 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
634 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
635 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
637 else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 )
639 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
640 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
641 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" );
642 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
643 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
644 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
645 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
646 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
647 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
648 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
649 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
650 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
651 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
652 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
653 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
654 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
655 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
656 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
657 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
658 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
659 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
660 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
665 myWidgets[iNodes][iTotal] ->setProperty( "text", "?" );
666 myWidgets[i0D][iTotal] ->setProperty( "text", "?" );
667 myWidgets[iBalls][iTotal] ->setProperty( "text", "?" );
668 myWidgets[i1D][iTotal] ->setProperty( "text", "?" );
669 myWidgets[i1D][iLinear] ->setProperty( "text", "?" );
670 myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" );
671 myWidgets[i2D][iTotal] ->setProperty( "text", "?" );
672 myWidgets[i2D][iLinear] ->setProperty( "text", "?" );
673 myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" );
674 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" );
675 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" );
676 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" );
677 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" );
678 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" );
679 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" );
680 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
681 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
682 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
683 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
684 myWidgets[i3D][iTotal] ->setProperty( "text", "?" );
685 myWidgets[i3D][iLinear] ->setProperty( "text", "?" );
686 myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" );
687 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" );
688 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" );
689 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" );
690 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" );
691 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" );
692 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
693 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" );
694 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" );
695 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" );
696 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" );
697 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" );
698 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" );
699 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" );
700 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" );
701 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" );
702 myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
703 myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
704 myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" );
705 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" );
712 \brief Load mesh from a study file
714 void SMESHGUI_MeshInfo::loadMesh()
716 SUIT_OverrideCursor wc;
718 SALOME_ListIO selected;
719 SMESHGUI::selectionMgr()->selectedObjects( selected );
721 if ( selected.Extent() == 1 ) {
722 Handle(SALOME_InteractiveObject) IO = selected.First();
723 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
724 if ( !CORBA::is_nil( obj ) ) {
725 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
726 if ( !mesh->_is_nil() )
736 \brief Reset the widget to the initial state (nullify all fields).
738 void SMESHGUI_MeshInfo::clear()
740 myWidgets[iName][iSingle] ->setProperty( "text", QString() );
741 myWidgets[iObject][iSingle] ->setProperty( "text", QString() );
742 myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) );
743 myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) );
744 myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) );
745 myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) );
746 myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) );
747 myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
748 myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) );
749 myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) );
750 myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
751 myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
752 myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
753 myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
754 myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
755 myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
756 myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) );
757 myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
758 myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
759 myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
760 myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
761 myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
762 myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
763 myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
764 myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
765 myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
766 myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
767 myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
768 myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
769 myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) );
770 myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
771 myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
772 myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) );
773 myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) );
774 myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
775 myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
776 myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) );
777 myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
778 myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) );
779 myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) );
780 myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 ) );
781 myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 ) );
782 myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
783 myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
787 \brief Create info field
788 \return new info field
790 QLabel* SMESHGUI_MeshInfo::createField()
792 QLabel* lab = new QLabel( this );
793 lab->setFrameStyle( StyledPanel | Sunken );
794 lab->setAlignment( Qt::AlignCenter );
795 lab->setAutoFillBackground( true );
796 QPalette pal = lab->palette();
797 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
798 lab->setPalette( pal );
799 lab->setMinimumWidth( 70 );
804 \brief Create horizontal rule.
805 \return new line object
807 QWidget* SMESHGUI_MeshInfo::createLine()
809 QFrame* line = new QFrame( this );
810 line->setFrameStyle( HLine | Sunken );
815 \brief Change widget font attributes (bold, italic, ...).
817 \param attr font attributes (XORed flags)
818 \param val value to be set to attributes
820 void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
824 if ( attr & Bold ) f.setBold( val );
825 if ( attr & Italic ) f.setItalic( val );
831 \brief Show/hide group(s) of fields.
832 \param start beginning of the block
833 \param end end of the block
834 \param on visibility flag
836 void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
838 start = qMax( 0, start );
839 end = qMin( end, (int)iElementsEnd );
840 for ( int i = start; i < end; i++ ) {
841 wlist wl = myWidgets[i];
842 foreach ( QWidget* w, wl ) w->setVisible( on );
846 void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
848 out << QString( 9, '-' ) << "\n";
849 out << tr( "BASE_INFO" ) << "\n";
850 out << QString( 9, '-' ) << "\n";
851 out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" ) ).toString() << "\n";
852 out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" ) ).toString() << "\n";
853 out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" ) ).toString() << "\n";
854 out << tr( "ELEMENTS_LAB" ) << "\n";
855 out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" ) ).toString() << "\n";
856 out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" ) ).toString() << "\n";
857 out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" ) ).toString() << "\n";
858 out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" ) ).toString() << "\n";
859 out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n";
860 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" ) ).toString() << "\n";
861 out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n";
862 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" ) ).toString() << "\n";
863 out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n";
864 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" ) ).toString() << "\n";
865 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" ) ).toString() << "\n";
866 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" ) ).toString() << "\n";
867 out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n";
868 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" ) ).toString() << "\n";
869 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" ) ).toString() << "\n";
870 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" ) ).toString() << "\n";
871 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
872 out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n";
873 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" ) ).toString() << "\n";
874 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" ) ).toString() << "\n";
875 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" ) ).toString() << "\n";
876 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
877 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n";
878 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" ) ).toString() << "\n";
879 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" ) ).toString() << "\n";
880 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" ) ).toString() << "\n";
881 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
882 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
883 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
884 out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
885 out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
886 out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
887 out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" ) ).toString() << "\n";
888 out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" ) ).toString() << "\n";
889 out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n";
890 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" ) ).toString() << "\n";
891 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" ) ).toString() << "\n";
892 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
893 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n";
894 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" ) ).toString() << "\n";
895 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" ) ).toString() << "\n";
896 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" ) ).toString() << "\n";
897 out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" ) ).toString() << "\n";
898 out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n";
899 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" ) ).toString() << "\n";
900 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" ) ).toString() << "\n";
901 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" ) ).toString() << "\n";
902 out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n";
903 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" ) ).toString() << "\n";
904 out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" ) ).toString() << "\n";
905 out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" ) ).toString() << "\n";
906 out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n";
907 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" ) ).toString() << "\n";
908 out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n";
909 out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" ) ).toString() << "\n" << "\n";
913 \class SMESHGUI_ElemInfo
914 \brief Base class for the mesh element information widget.
919 \param parent parent widget
921 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
922 : QWidget( parent ), myActor( 0 ), myIsElement( -1 )
924 myFrame = new QWidget( this );
925 myExtra = new ExtraWidget( this );
926 QVBoxLayout* vbl = new QVBoxLayout( this );
928 vbl->setSpacing( 0 );
929 vbl->addWidget( myFrame );
930 vbl->addWidget( myExtra );
931 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
932 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
939 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
944 \brief Set mesh data source (actor)
945 \param actor mesh object actor
947 void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
949 if ( myActor != actor ) {
957 \brief Show mesh element information
958 \param id mesh node / element ID
959 \param isElem show mesh element information if \c true or mesh node information if \c false
961 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
965 showInfo( ids, isElem );
969 \brief Show mesh element information
970 \param ids mesh nodes / elements identifiers
971 \param isElem show mesh element information if \c true or mesh node information if \c false
973 void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
975 QList<long> newIds = ids.toList();
977 if ( myIDs == newIds && myIsElement == isElem ) return;
980 myIsElement = isElem;
983 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
987 \brief Clear mesh element information widget
989 void SMESHGUI_ElemInfo::clear()
998 \brief Get central area widget
999 \return central widget
1001 QWidget* SMESHGUI_ElemInfo::frame() const
1008 \return actor being used
1010 SMESH_Actor* SMESHGUI_ElemInfo::actor() const
1016 \brief Get current info mode.
1017 \return \c true if mesh element information is shown or \c false if node information is shown
1019 bool SMESHGUI_ElemInfo::isElements() const
1025 \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
1026 \brief Show information on the specified nodes / elements
1028 This function is to be redefined in sub-classes.
1030 \param ids nodes / elements identifiers information is to be shown on
1034 \brief Internal clean-up (reset widget)
1036 void SMESHGUI_ElemInfo::clearInternal()
1041 \brief Get node connectivity
1042 \param node mesh node
1043 \return node connectivity map
1045 SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
1049 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1050 while ( it && it->more() ) {
1051 const SMDS_MeshElement* ne = it->next();
1052 elmap[ ne->GetType() ] << ne->GetID();
1059 \brief Format connectivity data to string representation
1060 \param connectivity connetivity map
1061 \param type element type
1062 \return string representation of the connectivity
1064 QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
1067 if ( connectivity.contains( type ) ) {
1068 QList<int> elements = connectivity[ type ];
1070 foreach( int id, elements )
1071 str << QString::number( id );
1073 return str.join( " " );
1077 \brief Calculate gravity center of the mesh element
1078 \param element mesh element
1080 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
1084 SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
1085 while ( nodeIt->more() ) {
1086 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1087 xyz.add( node->X(), node->Y(), node->Z() );
1089 xyz.divide( element->NbNodes() );
1095 \brief Calculate normal vector to the mesh face
1096 \param element mesh face
1098 SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
1100 gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
1101 return XYZ(n.X(), n.Y(), n.Z());
1105 \brief This slot is called from "Show Previous" button click.
1106 Shows information on the previous group of the items.
1108 void SMESHGUI_ElemInfo::showPrevious()
1110 myIndex = qMax( 0, myIndex-1 );
1112 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1116 \brief This slot is called from "Show Next" button click.
1117 Shows information on the next group of the items.
1119 void SMESHGUI_ElemInfo::showNext()
1121 myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
1123 information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
1127 \brief Update widgets state
1129 void SMESHGUI_ElemInfo::updateControls()
1131 myExtra->updateControls( myIDs.count(), myIndex );
1135 \class SMESHGUI_SimpleElemInfo
1136 \brief Represents mesh element information in the simple text area.
1141 \param parent parent widget
1143 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
1144 : SMESHGUI_ElemInfo( parent )
1146 myInfo = new QTextBrowser( frame() );
1147 QVBoxLayout* l = new QVBoxLayout( frame() );
1149 l->addWidget( myInfo );
1153 \brief Show mesh element information
1154 \param ids mesh nodes / elements identifiers
1156 void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
1161 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1162 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1163 int cprecision = -1;
1164 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1165 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1166 foreach ( long id, ids ) {
1167 if ( !isElements() ) {
1171 const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
1172 if ( !node ) return;
1175 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( id ) );
1177 myInfo->append( "" );
1179 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1180 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1181 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1182 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1184 myInfo->append( "" );
1186 Connectivity connectivity = nodeConnectivity( node );
1187 if ( !connectivity.isEmpty() ) {
1188 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1189 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1190 if ( !con.isEmpty() )
1191 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1192 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1193 if ( !con.isEmpty() )
1194 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1195 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1196 if ( !con.isEmpty() )
1197 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) ).arg( con ) );
1198 con = formatConnectivity( connectivity, SMDSAbs_Face );
1199 if ( !con.isEmpty() )
1200 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1201 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1202 if ( !con.isEmpty() )
1203 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1206 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1209 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1210 if ( !CORBA::is_nil( aMeshPtr ) ) {
1211 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1212 int shapeID = pos->shapeID;
1213 if ( shapeID > 0 ) {
1216 switch ( pos->shapeType ) {
1218 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1219 if ( pos->params.length() == 1 )
1223 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1224 if ( pos->params.length() == 2 ) {
1230 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1233 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1237 myInfo->append( "" );
1238 myInfo->append( QString( "<b>%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ) );
1239 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( shapeType ).arg( shapeID ) );
1240 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1241 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" ) ).
1242 arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1243 if ( pos->shapeType == GEOM::FACE ) {
1244 myInfo->append( QString( "- <b>%1: #%2</b>" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" ) ).
1245 arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) ) );
1250 // groups node belongs to
1251 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1252 if ( !CORBA::is_nil( aMesh ) ) {
1253 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1254 myInfo->append( "" ); // separator
1255 bool top_created = false;
1256 for ( int i = 0; i < groups->length(); i++ ) {
1257 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1258 if ( CORBA::is_nil( aGrp ) ) continue;
1259 QString aName = aGrp->GetName();
1260 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1261 if ( !top_created ) {
1262 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1265 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1266 if ( grp_details ) {
1267 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1268 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1269 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1271 // type : group on geometry, standalone group, group on filter
1272 if ( !CORBA::is_nil( aStdGroup ) ) {
1273 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1274 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1276 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1277 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1278 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1279 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1280 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1282 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1283 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1286 else if ( !CORBA::is_nil( aFltGroup ) ) {
1287 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1288 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1292 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1293 arg( QString::number( aGrp->Size() ) ) );
1296 SALOMEDS::Color color = aGrp->GetColor();
1297 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1298 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1306 // show element info
1308 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1309 SMESH::Controls::NumericalFunctorPtr afunctor;
1312 // Element ID && Type
1314 switch( e->GetType() ) {
1315 case SMDSAbs_0DElement:
1316 stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1318 stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1320 stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1322 stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1323 case SMDSAbs_Volume:
1324 stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1328 if ( stype.isEmpty() ) return;
1329 myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
1331 myInfo->append( "" );
1335 switch( e->GetEntityType() ) {
1336 case SMDSEntity_Triangle:
1337 case SMDSEntity_Quad_Triangle:
1338 case SMDSEntity_BiQuad_Triangle:
1339 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1340 case SMDSEntity_Quadrangle:
1341 case SMDSEntity_Quad_Quadrangle:
1342 case SMDSEntity_BiQuad_Quadrangle:
1343 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1344 case SMDSEntity_Polygon:
1345 case SMDSEntity_Quad_Polygon:
1346 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1347 case SMDSEntity_Tetra:
1348 case SMDSEntity_Quad_Tetra:
1349 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1350 case SMDSEntity_Pyramid:
1351 case SMDSEntity_Quad_Pyramid:
1352 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1353 case SMDSEntity_Hexa:
1354 case SMDSEntity_Quad_Hexa:
1355 case SMDSEntity_TriQuad_Hexa:
1356 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1357 case SMDSEntity_Penta:
1358 case SMDSEntity_Quad_Penta:
1359 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1360 case SMDSEntity_Hexagonal_Prism:
1361 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1362 case SMDSEntity_Polyhedra:
1363 case SMDSEntity_Quad_Polyhedra:
1364 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1368 if ( !gtype.isEmpty() )
1369 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" ) ).arg( gtype ) );
1371 // Quadratic flag (any element except 0D)
1372 if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
1373 myInfo->append( QString( "<b>%1?</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) ) );
1375 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1377 myInfo->append( QString( "<b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
1380 myInfo->append( "" );
1383 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1384 for ( int idx = 1; nodeIt->more(); idx++ ) {
1385 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1386 // node number and ID
1387 myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
1389 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" ) ).
1390 arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1391 arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
1392 arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1393 // node connectivity
1394 Connectivity connectivity = nodeConnectivity( node );
1395 if ( !connectivity.isEmpty() ) {
1396 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) ) );
1397 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1398 if ( !con.isEmpty() )
1399 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) ).arg( con ) );
1400 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1401 if ( !con.isEmpty() )
1402 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" ) ).arg( con ) );
1403 con = formatConnectivity( connectivity, SMDSAbs_Face );
1404 if ( !con.isEmpty() )
1405 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" ) ).arg( con ) );
1406 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1407 if ( !con.isEmpty() )
1408 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" ) ).arg( con ) );
1411 myInfo->append( QString( "<b>%1</b>" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" ) ).arg( id ) );
1415 myInfo->append( "" );
1418 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" ) ) );
1420 if ( e->GetType() == SMDSAbs_Edge ) {
1421 afunctor.reset( new SMESH::Controls::Length() );
1422 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1423 afunctor->SetPrecision( cprecision );
1424 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "LENGTH_EDGES" ) ).arg( afunctor->GetValue( id ) ) );
1426 if( e->GetType() == SMDSAbs_Face ) {
1428 afunctor.reset( new SMESH::Controls::Area() );
1429 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1430 afunctor->SetPrecision( cprecision );
1431 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "AREA_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1433 afunctor.reset( new SMESH::Controls::Taper() );
1434 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1435 afunctor->SetPrecision( cprecision );
1436 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "TAPER_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1438 afunctor.reset( new SMESH::Controls::AspectRatio() );
1439 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1440 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1442 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1443 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1444 afunctor->SetPrecision( cprecision );
1445 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1447 afunctor.reset( new SMESH::Controls::Warping() );
1448 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1449 afunctor->SetPrecision( cprecision );
1450 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "WARP_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1452 afunctor.reset( new SMESH::Controls::Skew() );
1453 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1454 afunctor->SetPrecision( cprecision );
1455 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "SKEW_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1457 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1458 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1459 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" ) ).arg( afunctor->GetValue( id ) ) );
1461 if( e->GetType() == SMDSAbs_Volume ) {
1463 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
1464 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1465 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1467 afunctor.reset( new SMESH::Controls::Volume() );
1468 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1469 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUME_3D_ELEMENTS" ) ).arg( afunctor->GetValue( id ) ) );
1471 afunctor.reset( new SMESH::Controls::Volume() );
1472 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1473 myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" ) ).arg( afunctor->GetValue( id ) ) );
1476 myInfo->append( "" );
1479 XYZ gc = gravityCenter( e );
1480 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1483 if( e->GetType() == SMDSAbs_Face ) {
1484 XYZ gc = normal( e );
1485 myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
1489 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1490 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1491 if ( !CORBA::is_nil( aMesh ) ) {
1492 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
1493 int shapeID = pos.shapeID;
1494 if ( shapeID > 0 ) {
1495 myInfo->append( "" ); // separator
1497 switch ( pos.shapeType ) {
1498 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
1499 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
1500 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
1501 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
1502 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
1503 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
1505 myInfo->append( QString( "<b>%1:</b> %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" ) ).arg( shapeType ).arg( shapeID ) );
1510 // Groups the element belongs to
1511 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1512 if ( !CORBA::is_nil( aMesh ) ) {
1513 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1514 myInfo->append( "" ); // separator
1515 bool top_created = false;
1516 for ( int i = 0; i < groups->length(); i++ ) {
1517 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1518 if ( CORBA::is_nil( aGrp ) ) continue;
1519 QString aName = aGrp->GetName();
1520 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1521 if ( !top_created ) {
1522 myInfo->append( QString( "<b>%1:</b>" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" ) ) );
1525 myInfo->append( QString( "+ <b>%1:</b>" ).arg( aName.trimmed() ) );
1526 if ( grp_details ) {
1527 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1528 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1529 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1531 // type : group on geometry, standalone group, group on filter
1532 if ( !CORBA::is_nil( aStdGroup ) ) {
1533 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1534 arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ) );
1536 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1537 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1538 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ) );
1539 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1540 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1542 myInfo->append( QString( " - <b>%1:</b> %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1543 arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) ).arg( sobj->GetName().c_str() ) );
1546 else if ( !CORBA::is_nil( aFltGroup ) ) {
1547 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" ) ).
1548 arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ) );
1551 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" ) ).
1552 arg( QString::number( aGrp->Size() ) ) );
1555 SALOMEDS::Color color = aGrp->GetColor();
1556 myInfo->append( QString( " - <b>%1:</b> %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" ) ).
1557 arg( QColor( color.R*255., color.G*255., color.B*255. ).name() ) );
1564 if ( ids.count() > 1 ) {
1565 myInfo->append( "" );
1566 myInfo->append( "------" );
1567 myInfo->append( "" );
1574 \brief Internal clean-up (reset widget)
1576 void SMESHGUI_SimpleElemInfo::clearInternal()
1581 void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out )
1583 out << QString( 12, '-' ) << "\n";
1584 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
1585 out << QString( 12, '-' ) << "\n";
1586 out << myInfo->toPlainText();
1592 \class SMESHGUI_TreeElemInfo::ItemDelegate
1593 \brief Item delegate for tree mesh info widget
1596 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
1599 ItemDelegate( QObject* );
1600 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
1607 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
1612 \brief Create item editor widget
1615 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
1617 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
1618 if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly( true );
1623 \class SMESHGUI_TreeElemInfo
1624 \brief Represents mesh element information in the tree-like form.
1629 \param parent parent widget
1631 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
1632 : SMESHGUI_ElemInfo( parent )
1634 myInfo = new QTreeWidget( frame() );
1635 myInfo->setColumnCount( 2 );
1636 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
1637 myInfo->header()->setStretchLastSection( true );
1638 myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
1639 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
1640 QVBoxLayout* l = new QVBoxLayout( frame() );
1642 l->addWidget( myInfo );
1643 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
1647 \brief Show mesh element information
1648 \param ids mesh nodes / elements identifiers
1650 void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
1655 int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1656 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1657 int cprecision = -1;
1658 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
1659 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
1660 foreach ( long id, ids ) {
1661 if ( !isElements() ) {
1665 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
1667 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
1670 QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
1671 nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" ) );
1672 nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
1674 QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
1675 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
1676 QTreeWidgetItem* xItem = createItem( coordItem );
1677 xItem->setText( 0, "X" );
1678 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1679 QTreeWidgetItem* yItem = createItem( coordItem );
1680 yItem->setText( 0, "Y" );
1681 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1682 QTreeWidgetItem* zItem = createItem( coordItem );
1683 zItem->setText( 0, "Z" );
1684 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
1686 QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
1687 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1688 Connectivity connectivity = nodeConnectivity( node );
1689 if ( !connectivity.isEmpty() ) {
1690 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
1691 if ( !con.isEmpty() ) {
1692 QTreeWidgetItem* i = createItem( conItem );
1693 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
1694 i->setText( 1, con );
1696 con = formatConnectivity( connectivity, SMDSAbs_Ball );
1697 if ( !con.isEmpty() ) {
1698 QTreeWidgetItem* i = createItem( conItem );
1699 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
1700 i->setText( 1, con );
1701 i->setData( 1, TypeRole, NodeConnectivity );
1703 con = formatConnectivity( connectivity, SMDSAbs_Edge );
1704 if ( !con.isEmpty() ) {
1705 QTreeWidgetItem* i = createItem( conItem );
1706 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
1707 i->setText( 1, con );
1708 i->setData( 1, TypeRole, NodeConnectivity );
1710 con = formatConnectivity( connectivity, SMDSAbs_Face );
1711 if ( !con.isEmpty() ) {
1712 QTreeWidgetItem* i = createItem( conItem );
1713 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
1714 i->setText( 1, con );
1715 i->setData( 1, TypeRole, NodeConnectivity );
1717 con = formatConnectivity( connectivity, SMDSAbs_Volume );
1718 if ( !con.isEmpty() ) {
1719 QTreeWidgetItem* i = createItem( conItem );
1720 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
1721 i->setText( 1, con );
1722 i->setData( 1, TypeRole, NodeConnectivity );
1726 conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" ) );
1729 SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer();
1730 if ( !CORBA::is_nil( aMeshPtr ) ) {
1731 SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id );
1732 int shapeID = pos->shapeID;
1733 if ( shapeID > 0 ) {
1736 switch ( pos->shapeType ) {
1738 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" );
1739 if ( pos->params.length() == 1 )
1743 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" );
1744 if ( pos->params.length() == 2 ) {
1750 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" );
1753 shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" );
1756 QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
1757 posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") );
1758 posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
1759 if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) {
1760 QTreeWidgetItem* uItem = createItem( posItem );
1761 uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") );
1762 uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
1763 if ( pos->shapeType == GEOM::FACE ) {
1764 QTreeWidgetItem* vItem = createItem( posItem );
1765 vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") );
1766 vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
1771 // groups node belongs to
1772 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
1773 if ( !CORBA::is_nil( aMesh ) ) {
1774 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
1775 QTreeWidgetItem* groupsItem = 0;
1776 for ( int i = 0; i < groups->length(); i++ ) {
1777 SMESH::SMESH_GroupBase_var aGrp = groups[i];
1778 if ( CORBA::is_nil( aGrp ) ) continue;
1779 QString aName = aGrp->GetName();
1780 if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
1781 if ( !groupsItem ) {
1782 groupsItem = createItem( nodeItem, Bold );
1783 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
1785 QTreeWidgetItem* it = createItem( groupsItem, Bold );
1786 it->setText( 0, aName.trimmed() );
1787 if ( grp_details ) {
1788 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
1789 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
1790 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
1792 // type : group on geometry, standalone group, group on filter
1793 QTreeWidgetItem* typeItem = createItem( it );
1794 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
1795 if ( !CORBA::is_nil( aStdGroup ) ) {
1796 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1798 else if ( !CORBA::is_nil( aGeomGroup ) ) {
1799 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1800 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
1801 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
1803 QTreeWidgetItem* gobjItem = createItem( typeItem );
1804 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
1805 gobjItem->setText( 1, sobj->GetName().c_str() );
1808 else if ( !CORBA::is_nil( aFltGroup ) ) {
1809 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1813 QTreeWidgetItem* sizeItem = createItem( it );
1814 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
1815 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
1818 SALOMEDS::Color color = aGrp->GetColor();
1819 QTreeWidgetItem* colorItem = createItem( it );
1820 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
1821 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
1829 // show element info
1831 const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
1832 SMESH::Controls::NumericalFunctorPtr afunctor;
1835 // element ID && type
1837 switch( e->GetType() ) {
1838 case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break;
1839 case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break;
1840 case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break;
1841 case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break;
1842 case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break;
1845 if ( stype.isEmpty() ) return;
1846 QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
1847 elemItem->setText( 0, stype );
1848 elemItem->setText( 1, QString( "#%1" ).arg( id ) );
1851 switch( e->GetEntityType() ) {
1852 case SMDSEntity_Triangle:
1853 case SMDSEntity_Quad_Triangle:
1854 case SMDSEntity_BiQuad_Triangle:
1855 gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break;
1856 case SMDSEntity_Quadrangle:
1857 case SMDSEntity_Quad_Quadrangle:
1858 case SMDSEntity_BiQuad_Quadrangle:
1859 gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break;
1860 case SMDSEntity_Polygon:
1861 case SMDSEntity_Quad_Polygon:
1862 gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break;
1863 case SMDSEntity_Tetra:
1864 case SMDSEntity_Quad_Tetra:
1865 gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break;
1866 case SMDSEntity_Pyramid:
1867 case SMDSEntity_Quad_Pyramid:
1868 gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break;
1869 case SMDSEntity_Hexa:
1870 case SMDSEntity_Quad_Hexa:
1871 case SMDSEntity_TriQuad_Hexa:
1872 gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
1873 case SMDSEntity_Penta:
1874 case SMDSEntity_Quad_Penta:
1875 gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
1876 case SMDSEntity_Hexagonal_Prism:
1877 gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
1878 case SMDSEntity_Polyhedra:
1879 case SMDSEntity_Quad_Polyhedra:
1880 gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break;
1884 if ( !gtype.isEmpty() ) {
1885 QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
1886 typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" ) );
1887 typeItem->setText( 1, gtype );
1889 // quadratic flag (for edges, faces and volumes)
1890 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
1892 QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
1893 quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" ) );
1894 quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" ) );
1896 if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
1898 QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
1899 diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" ) );
1900 diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
1903 QTreeWidgetItem* conItem = createItem( elemItem, Bold );
1904 conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
1907 if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) {
1908 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
1909 for ( int idx = 1; nodeIt->more(); idx++ ) {
1910 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
1911 nodeInfo( node, idx, e->NbNodes(), conItem );
1915 const SMDS_VtkVolume* aVtkVolume = dynamic_cast<const SMDS_VtkVolume*>(e);
1916 SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator();
1917 QList<const SMDS_MeshElement*> uniqueNodes;
1918 while ( nodeIt->more() )
1919 uniqueNodes.append( nodeIt->next() );
1921 SMDS_VolumeTool vtool( e );
1922 const int nbFaces = vtool.NbFaces();
1923 for( int face_id = 0; face_id < nbFaces; face_id++ ) {
1924 QTreeWidgetItem* faceItem = createItem( conItem, Bold );
1925 faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" ) ).arg( face_id + 1 ).arg( nbFaces ) );
1926 faceItem->setExpanded( true );
1928 const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id );
1929 const int nbNodes = vtool.NbFaceNodes( face_id );
1930 for( int node_id = 0; node_id < nbNodes; node_id++ ) {
1931 const SMDS_MeshNode* node = aNodeIds[node_id];
1932 nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem );
1937 QTreeWidgetItem* cntrItem = createItem( elemItem, Bold );
1938 cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) );
1940 if( e->GetType()==SMDSAbs_Edge){
1941 afunctor.reset( new SMESH::Controls::Length() );
1942 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1943 afunctor->SetPrecision( cprecision );
1944 QTreeWidgetItem* lenItem = createItem( cntrItem, Bold );
1945 lenItem->setText( 0, tr( "LENGTH_EDGES" ) );
1946 lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1948 if( e->GetType() == SMDSAbs_Face ) {
1950 afunctor.reset( new SMESH::Controls::Area() );
1951 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1952 afunctor->SetPrecision( cprecision );
1953 QTreeWidgetItem* areaItem = createItem( cntrItem, Bold );
1954 areaItem->setText( 0, tr( "AREA_ELEMENTS" ) );
1955 areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) );
1957 afunctor.reset( new SMESH::Controls::Taper() );
1958 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1959 afunctor->SetPrecision( cprecision );
1960 QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold );
1961 taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) );
1962 taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1964 afunctor.reset( new SMESH::Controls::AspectRatio() );
1965 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1966 QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold );
1967 ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" ));
1968 ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1970 afunctor.reset( new SMESH::Controls::MinimumAngle() );
1971 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1972 afunctor->SetPrecision( cprecision );
1973 QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold );
1974 minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) );
1975 minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1977 afunctor.reset( new SMESH::Controls::Warping() );
1978 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1979 afunctor->SetPrecision( cprecision );
1980 QTreeWidgetItem* warpItem = createItem( cntrItem, Bold );
1981 warpItem->setText( 0, tr( "WARP_ELEMENTS" ));
1982 warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1984 afunctor.reset( new SMESH::Controls::Skew() );
1985 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1986 afunctor->SetPrecision( cprecision );
1987 QTreeWidgetItem* skewItem = createItem( cntrItem, Bold );
1988 skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) );
1989 skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1991 afunctor.reset( new SMESH::Controls::MaxElementLength2D() );
1992 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
1993 QTreeWidgetItem* diamItem = createItem( cntrItem, Bold );
1994 diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" ));
1995 diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
1997 if( e->GetType() == SMDSAbs_Volume ) {
1999 afunctor.reset( new SMESH::Controls::AspectRatio3D() );
2000 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2001 QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold );
2002 ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) );
2003 ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2005 afunctor.reset( new SMESH::Controls::Volume() );
2006 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2007 QTreeWidgetItem* volItem = createItem( cntrItem, Bold );
2008 volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" ) );
2009 volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2011 afunctor.reset( new SMESH::Controls::MaxElementLength3D() );
2012 afunctor->SetMesh( actor()->GetObject()->GetMesh() );
2013 QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold );
2014 diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) );
2015 diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) );
2019 XYZ gc = gravityCenter( e );
2020 QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
2021 gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) );
2022 QTreeWidgetItem* xItem = createItem( gcItem );
2023 xItem->setText( 0, "X" );
2024 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2025 QTreeWidgetItem* yItem = createItem( gcItem );
2026 yItem->setText( 0, "Y" );
2027 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2028 QTreeWidgetItem* zItem = createItem( gcItem );
2029 zItem->setText( 0, "Z" );
2030 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2033 if( e->GetType() == SMDSAbs_Face ) {
2034 XYZ gc = normal( e );
2035 QTreeWidgetItem* nItem = createItem( elemItem, Bold );
2036 nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
2037 QTreeWidgetItem* xItem = createItem( nItem );
2038 xItem->setText( 0, "X" );
2039 xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2040 QTreeWidgetItem* yItem = createItem( nItem );
2041 yItem->setText( 0, "Y" );
2042 yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2043 QTreeWidgetItem* zItem = createItem( nItem );
2044 zItem->setText( 0, "Z" );
2045 zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2049 SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
2050 if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
2051 if ( !CORBA::is_nil( aMesh ) ) {
2052 SMESH::ElementPosition pos = aMesh->GetElementPosition( id );
2053 int shapeID = pos.shapeID;
2054 if ( shapeID > 0 ) {
2055 QTreeWidgetItem* shItem = createItem( elemItem, Bold );
2057 switch ( pos.shapeType ) {
2058 case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break;
2059 case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break;
2060 case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break;
2061 case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break;
2062 case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break;
2063 default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break;
2065 shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" ) );
2066 shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID ) );
2070 // groups element belongs to
2071 if ( !CORBA::is_nil( aMesh ) ) {
2072 SMESH::ListOfGroups_var groups = aMesh->GetGroups();
2073 QTreeWidgetItem* groupsItem = 0;
2074 for ( int i = 0; i < groups->length(); i++ ) {
2075 SMESH::SMESH_GroupBase_var aGrp = groups[i];
2076 if ( CORBA::is_nil( aGrp ) ) continue;
2077 QString aName = aGrp->GetName();
2078 if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id ) ) {
2079 if ( !groupsItem ) {
2080 groupsItem = createItem( elemItem, Bold );
2081 groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" ) );
2083 QTreeWidgetItem* it = createItem( groupsItem, Bold );
2084 it->setText( 0, aName.trimmed() );
2085 if ( grp_details ) {
2086 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp );
2087 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp );
2088 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp );
2090 // type : group on geometry, standalone group, group on filter
2091 QTreeWidgetItem* typeItem = createItem( it );
2092 typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" ) );
2093 if ( !CORBA::is_nil( aStdGroup ) ) {
2094 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
2096 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2097 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
2098 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2099 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2101 QTreeWidgetItem* gobjItem = createItem( typeItem );
2102 gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ) );
2103 gobjItem->setText( 1, sobj->GetName().c_str() );
2106 else if ( !CORBA::is_nil( aFltGroup ) ) {
2107 typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
2111 QTreeWidgetItem* sizeItem = createItem( it );
2112 sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" ) );
2113 sizeItem->setText( 1, QString::number( aGrp->Size() ) );
2116 SALOMEDS::Color color = aGrp->GetColor();
2117 QTreeWidgetItem* colorItem = createItem( it );
2118 colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" ) );
2119 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2130 \brief Show node information
2131 \param node mesh node for showing
2132 \param index index of current node
2133 \param nbNodes number of unique nodes in element
2134 \param parentItem parent item of tree
2136 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index,
2137 int nbNodes, QTreeWidgetItem* parentItem )
2139 int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2140 // node number and ID
2141 QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2142 nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" ) ).arg( index ).arg( nbNodes ) );
2143 nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
2144 nodeItem->setData( 1, TypeRole, ElemConnectivity );
2145 nodeItem->setData( 1, IdRole, node->GetID() );
2146 nodeItem->setExpanded( false );
2148 QTreeWidgetItem* coordItem = createItem( nodeItem );
2149 coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ) );
2150 QTreeWidgetItem* xItem = createItem( coordItem );
2151 xItem->setText( 0, "X" );
2152 xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2153 QTreeWidgetItem* yItem = createItem( coordItem );
2154 yItem->setText( 0, "Y" );
2155 yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2156 QTreeWidgetItem* zItem = createItem( coordItem );
2157 zItem->setText( 0, "Z" );
2158 zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
2159 // node connectivity
2160 QTreeWidgetItem* nconItem = createItem( nodeItem );
2161 nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ) );
2162 Connectivity connectivity = nodeConnectivity( node );
2163 if ( !connectivity.isEmpty() ) {
2164 QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2165 if ( !con.isEmpty() ) {
2166 QTreeWidgetItem* i = createItem( nconItem );
2167 i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ) );
2168 i->setText( 1, con );
2170 con = formatConnectivity( connectivity, SMDSAbs_Edge );
2171 if ( !con.isEmpty() ) {
2172 QTreeWidgetItem* i = createItem( nconItem );
2173 i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ) );
2174 i->setText( 1, con );
2175 i->setData( 1, TypeRole, NodeConnectivity );
2177 con = formatConnectivity( connectivity, SMDSAbs_Ball );
2178 if ( !con.isEmpty() ) {
2179 QTreeWidgetItem* i = createItem( nconItem );
2180 i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ) );
2181 i->setText( 1, con );
2182 i->setData( 1, TypeRole, NodeConnectivity );
2184 con = formatConnectivity( connectivity, SMDSAbs_Face );
2185 if ( !con.isEmpty() ) {
2186 QTreeWidgetItem* i = createItem( nconItem );
2187 i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ) );
2188 i->setText( 1, con );
2189 i->setData( 1, TypeRole, NodeConnectivity );
2191 con = formatConnectivity( connectivity, SMDSAbs_Volume );
2192 if ( !con.isEmpty() ) {
2193 QTreeWidgetItem* i = createItem( nconItem );
2194 i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ) );
2195 i->setText( 1, con );
2196 i->setData( 1, TypeRole, NodeConnectivity );
2201 \brief Internal clean-up (reset widget)
2203 void SMESHGUI_TreeElemInfo::clearInternal()
2210 \brief Create new tree item.
2211 \param parent parent tree widget item
2212 \param flags item flag
2213 \return new tree widget item
2215 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
2217 QTreeWidgetItem* item;
2219 item = new QTreeWidgetItem( parent );
2221 item = new QTreeWidgetItem( myInfo );
2223 item->setFlags( item->flags() | Qt::ItemIsEditable );
2225 QFont f = item->font( 0 );
2227 for ( int i = 0; i < myInfo->columnCount(); i++ ) {
2228 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2229 item->setFont( i, f );
2232 item->setExpanded( true );
2236 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2238 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2239 if ( widgets.isEmpty() ) return;
2240 QTreeWidgetItem* aTreeItem = widgets.first();
2241 int type = aTreeItem->data( 1, TypeRole ).toInt();
2242 int id = aTreeItem->data( 1, IdRole ).toInt();
2244 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ) );
2245 if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a )
2246 emit( itemInfo( id ) );
2247 else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a )
2248 emit( itemInfo( aTreeItem->text( 1 ) ) );
2251 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn )
2254 int type = theItem->data( 1, TypeRole ).toInt();
2255 int id = theItem->data( 1, IdRole ).toInt();
2256 if ( type == ElemConnectivity && id > 0 )
2257 emit( itemInfo( id ) );
2258 else if ( type == NodeConnectivity )
2259 emit( itemInfo( theItem->text( 1 ) ) );
2263 void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
2265 out << QString( 12, '-' ) << "\n";
2266 out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n";
2267 out << QString( 12, '-' ) << "\n";
2269 QTreeWidgetItemIterator it( myInfo );
2271 if ( !( *it )->text(0).isEmpty() ) {
2272 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2273 if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1);
2283 \brief Mesh information computer
2286 The class is created for different computation operation. Currently it is used
2287 to compute number of underlying nodes for the groups.
2293 GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* item, QObject* parent )
2294 : QObject( parent ), myItem( item )
2296 myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
2300 \brief Compute function
2302 void GrpComputor::compute()
2304 if ( !CORBA::is_nil( myGroup ) && myItem ) {
2305 QTreeWidgetItem* item = myItem;
2307 int nbNodes = myGroup->GetNumberOfNodes();
2308 item->treeWidget()->removeItemWidget( item, 1 );
2309 item->setText( 1, QString::number( nbNodes ));
2314 \class SMESHGUI_AddInfo
2315 \brief The wigdet shows additional information on the mesh object.
2320 \param parent parent widget
2322 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
2323 : QTreeWidget( parent )
2325 setColumnCount( 2 );
2326 header()->setStretchLastSection( true );
2327 header()->setResizeMode( 0, QHeaderView::ResizeToContents );
2334 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2339 \brief Show additional information on the selected object
2340 \param obj object being processed (mesh, sub-mesh, group, ID source)
2342 void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
2344 setProperty( "group_index", 0 );
2345 setProperty( "submesh_index", 0 );
2346 myComputors.clear();
2349 if ( CORBA::is_nil( obj ) ) return;
2351 _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
2352 if ( !sobj ) return;
2355 QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
2356 nameItem->setText( 0, tr( "NAME" ) );
2357 nameItem->setText( 1, sobj->GetName().c_str() );
2359 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
2360 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
2361 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj );
2363 if ( !aMesh->_is_nil() )
2364 meshInfo( aMesh, nameItem );
2365 else if ( !aSubMesh->_is_nil() )
2366 subMeshInfo( aSubMesh, nameItem );
2367 else if ( !aGroup->_is_nil() )
2368 groupInfo( aGroup.in(), nameItem );
2372 \brief Create new tree item.
2373 \param parent parent tree widget item
2374 \param flags item flag
2375 \return new tree widget item
2377 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
2379 QTreeWidgetItem* item;
2382 item = new QTreeWidgetItem( parent );
2384 item = new QTreeWidgetItem( this );
2386 //item->setFlags( item->flags() | Qt::ItemIsEditable );
2388 QFont f = item->font( 0 );
2390 for ( int i = 0; i < columnCount(); i++ ) {
2391 if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
2392 item->setFont( i, f );
2395 item->setExpanded( true );
2400 \brief Show mesh info
2401 \param mesh mesh object
2402 \param parent parent tree item
2404 void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
2407 GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
2408 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
2409 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2410 typeItem->setText( 0, tr( "TYPE" ) );
2411 if ( !CORBA::is_nil( shape ) ) {
2412 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2413 _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
2415 QTreeWidgetItem* gobjItem = createItem( typeItem );
2416 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2417 gobjItem->setText( 1, sobj->GetName().c_str() );
2420 else if ( strlen( (char*)inf->fileName ) > 0 ) {
2421 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2422 QTreeWidgetItem* fileItem = createItem( typeItem );
2423 fileItem->setText( 0, tr( "FILE_NAME" ) );
2424 fileItem->setText( 1, (char*)inf->fileName );
2427 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2431 myGroups = mesh->GetGroups();
2435 mySubMeshes = mesh->GetSubMeshes();
2440 \brief Show sub-mesh info
2441 \param subMesh sub-mesh object
2442 \param parent parent tree item
2444 void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
2446 bool isShort = parent->parent() != 0;
2450 _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
2452 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2453 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2454 nameItem->setText( 1, sobj->GetName().c_str() );
2459 GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
2460 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2462 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2463 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2464 gobjItem->setText( 1, sobj->GetName().c_str() );
2469 \brief Show group info
2470 \param grp mesh group object
2471 \param parent parent tree item
2473 void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
2475 bool isShort = parent->parent() != 0;
2477 SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp );
2478 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
2479 SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp );
2483 _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
2485 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2486 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2487 nameItem->setText( 1, sobj->GetName().c_str() );
2491 // type : group on geometry, standalone group, group on filter
2492 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2493 typeItem->setText( 0, tr( "TYPE" ) );
2494 if ( !CORBA::is_nil( aStdGroup ) ) {
2495 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2497 else if ( !CORBA::is_nil( aGeomGroup ) ) {
2498 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2499 GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
2500 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
2502 QTreeWidgetItem* gobjItem = createItem( typeItem );
2503 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2504 gobjItem->setText( 1, sobj->GetName().c_str() );
2507 else if ( !CORBA::is_nil( aFltGroup ) ) {
2508 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2513 QString etype = tr( "UNKNOWN" );
2514 switch( grp->GetType() ) {
2516 etype = tr( "NODE" );
2519 etype = tr( "EDGE" );
2522 etype = tr( "FACE" );
2525 etype = tr( "VOLUME" );
2528 etype = tr( "0DELEM" );
2531 etype = tr( "BALL" );
2536 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2537 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2538 etypeItem->setText( 1, etype );
2542 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2543 sizeItem->setText( 0, tr( "SIZE" ) );
2544 sizeItem->setText( 1, QString::number( grp->Size() ) );
2547 SALOMEDS::Color color = grp->GetColor();
2548 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2549 colorItem->setText( 0, tr( "COLOR" ) );
2550 colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
2552 // nb of underlying nodes
2553 if ( grp->GetType() != SMESH::NODE) {
2554 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2555 nodesItem->setText( 0, tr( "NB_NODES" ) );
2556 int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
2557 SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
2558 bool meshLoaded = mesh->IsLoaded();
2559 bool toShowNodes = ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || grp->Size() <= nbNodesLimit );
2560 if ( toShowNodes && meshLoaded ) {
2561 // already calculated and up-to-date
2562 nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
2565 QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
2566 setItemWidget( nodesItem, 1, btn );
2567 GrpComputor* comp = new GrpComputor( grp, nodesItem, this );
2568 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2569 myComputors.append( comp );
2571 connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
2576 void SMESHGUI_AddInfo::showGroups()
2578 myComputors.clear();
2580 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2581 if ( !parent ) return;
2583 int idx = property( "group_index" ).toInt();
2585 QTreeWidgetItem* itemGroups = 0;
2586 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
2587 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
2588 itemGroups = parent->child( i );
2589 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
2591 extra->updateControls( myGroups->length(), idx );
2592 while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
2596 QMap<int, QTreeWidgetItem*> grpItems;
2597 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
2598 SMESH::SMESH_GroupBase_var grp = myGroups[i];
2599 if ( CORBA::is_nil( grp ) ) continue;
2600 _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
2601 if ( !grpSObj ) continue;
2603 int grpType = grp->GetType();
2605 if ( !itemGroups ) {
2606 // create top-level groups container item
2607 itemGroups = createItem( parent, Bold | All );
2608 itemGroups->setText( 0, tr( "GROUPS" ) );
2609 itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
2611 // total number of groups > 10, show extra widgets for info browsing
2612 if ( myGroups->length() > MAXITEMS ) {
2613 ExtraWidget* extra = new ExtraWidget( this, true );
2614 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2615 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2616 setItemWidget( itemGroups, 1, extra );
2617 extra->updateControls( myGroups->length(), idx );
2621 if ( grpItems.find( grpType ) == grpItems.end() ) {
2622 grpItems[ grpType ] = createItem( itemGroups, Bold | All );
2623 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2624 itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
2628 QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
2629 grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2632 groupInfo( grp.in(), grpNameItem );
2636 void SMESHGUI_AddInfo::showSubMeshes()
2638 QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
2639 if ( !parent ) return;
2641 int idx = property( "submesh_index" ).toInt();
2643 QTreeWidgetItem* itemSubMeshes = 0;
2644 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
2645 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
2646 itemSubMeshes = parent->child( i );
2647 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
2649 extra->updateControls( mySubMeshes->length(), idx );
2650 while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
2654 QMap<int, QTreeWidgetItem*> smItems;
2655 for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
2656 SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
2657 if ( CORBA::is_nil( sm ) ) continue;
2658 _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
2659 if ( !smSObj ) continue;
2661 GEOM::GEOM_Object_var gobj = sm->GetSubShape();
2662 if ( CORBA::is_nil(gobj ) ) continue;
2664 int smType = gobj->GetShapeType();
2665 if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
2667 if ( !itemSubMeshes ) {
2668 itemSubMeshes = createItem( parent, Bold | All );
2669 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2670 itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
2672 // total number of sub-meshes > 10, show extra widgets for info browsing
2673 if ( mySubMeshes->length() > MAXITEMS ) {
2674 ExtraWidget* extra = new ExtraWidget( this, true );
2675 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2676 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2677 setItemWidget( itemSubMeshes, 1, extra );
2678 extra->updateControls( mySubMeshes->length(), idx );
2682 if ( smItems.find( smType ) == smItems.end() ) {
2683 smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
2684 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2685 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2689 QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
2690 smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
2693 subMeshInfo( sm.in(), smNameItem );
2698 * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
2700 void SMESHGUI_AddInfo::changeLoadToCompute()
2702 for ( int i = 0; i < myComputors.count(); ++i )
2704 if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
2706 if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
2707 btn->setText( tr("COMPUTE") );
2712 void SMESHGUI_AddInfo::showPreviousGroups()
2714 int idx = property( "group_index" ).toInt();
2715 setProperty( "group_index", idx-1 );
2719 void SMESHGUI_AddInfo::showNextGroups()
2721 int idx = property( "group_index" ).toInt();
2722 setProperty( "group_index", idx+1 );
2726 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2728 int idx = property( "submesh_index" ).toInt();
2729 setProperty( "submesh_index", idx-1 );
2733 void SMESHGUI_AddInfo::showNextSubMeshes()
2735 int idx = property( "submesh_index" ).toInt();
2736 setProperty( "submesh_index", idx+1 );
2740 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2742 out << QString( 15, '-') << "\n";
2743 out << tr( "ADDITIONAL_INFO" ) << "\n";
2744 out << QString( 15, '-' ) << "\n";
2745 QTreeWidgetItemIterator it( this );
2747 if ( !( ( *it )->text(0) ).isEmpty() ) {
2748 out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0);
2749 if ( ( *it )->text(0) == tr( "COLOR" ) ) {
2750 out << ": " << ( ( ( *it )->background(1) ).color() ).name();
2752 else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1);
2761 \class SMESHGUI_MeshInfoDlg
2762 \brief Mesh information dialog box
2767 \param parent parent widget
2768 \param page specifies the dialog page to be shown at the start-up
2770 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
2771 : QDialog( parent ), myActor( 0 )
2774 setAttribute( Qt::WA_DeleteOnClose, true );
2775 setWindowTitle( tr( "MESH_INFO" ) );
2776 setSizeGripEnabled( true );
2778 myTabWidget = new QTabWidget( this );
2782 myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
2783 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
2787 QWidget* w = new QWidget( myTabWidget );
2789 myMode = new QButtonGroup( this );
2790 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
2791 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
2792 myMode->button( NodeMode )->setChecked( true );
2793 myID = new QLineEdit( w );
2794 myID->setValidator( new SMESHGUI_IdValidator( this ) );
2796 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
2797 mode = qMin( 1, qMax( 0, mode ) );
2800 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
2802 myElemInfo = new SMESHGUI_TreeElemInfo( w );
2804 QGridLayout* elemLayout = new QGridLayout( w );
2805 elemLayout->setMargin( MARGIN );
2806 elemLayout->setSpacing( SPACING );
2807 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
2808 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
2809 elemLayout->addWidget( myID, 0, 2 );
2810 elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
2812 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
2816 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
2817 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
2821 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
2822 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
2826 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
2827 okBtn->setAutoDefault( true );
2828 okBtn->setDefault( true );
2830 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
2831 dumpBtn->setAutoDefault( true );
2832 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
2833 helpBtn->setAutoDefault( true );
2835 QHBoxLayout* btnLayout = new QHBoxLayout;
2836 btnLayout->setSpacing( SPACING );
2837 btnLayout->setMargin( 0 );
2839 btnLayout->addWidget( okBtn );
2840 btnLayout->addWidget( dumpBtn );
2841 btnLayout->addStretch( 10 );
2842 btnLayout->addWidget( helpBtn );
2844 QVBoxLayout* l = new QVBoxLayout ( this );
2845 l->setMargin( MARGIN );
2846 l->setSpacing( SPACING );
2847 l->addWidget( myTabWidget );
2848 l->addLayout( btnLayout );
2850 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
2852 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
2853 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
2854 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
2855 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
2856 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
2857 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
2858 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
2859 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
2860 connect( myElemInfo, SIGNAL( itemInfo( int ) ), this, SLOT( showItemInfo( int ) ) );
2861 connect( myElemInfo, SIGNAL( itemInfo( QString ) ), this, SLOT( showItemInfo( QString ) ) );
2869 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
2874 \brief Show mesh information
2875 \param IO interactive object
2877 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
2879 SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
2880 if ( !CORBA::is_nil( obj ) ) {
2881 myBaseInfo->showInfo( obj );
2882 myAddInfo->showInfo( obj );
2883 myCtrlInfo->showInfo( obj );
2885 myActor = SMESH::FindActorByEntry( IO->getEntry() );
2886 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
2889 if ( myActor && selector ) {
2890 nb = myMode->checkedId() == NodeMode ?
2891 SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
2892 SMESH::GetNameOfSelectedNodes( selector, IO, ID );
2894 myElemInfo->setSource( myActor ) ;
2896 myID->setText( ID.trimmed() );
2898 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
2899 foreach ( ID, idTxt )
2900 ids << ID.trimmed().toLong();
2901 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
2905 myElemInfo->clear();
2911 \brief Perform clean-up actions on the dialog box closing.
2913 void SMESHGUI_MeshInfoDlg::reject()
2915 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2916 selMgr->clearFilters();
2917 SMESH::SetPointRepresentation( false );
2918 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2919 aViewWindow->SetSelectionMode( ActorSelection );
2924 \brief Process keyboard event
2925 \param e key press event
2927 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
2929 QDialog::keyPressEvent( e );
2930 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
2937 \brief Reactivate dialog box, when mouse pointer goes into it.
2939 void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
2945 \brief Setup selection mode depending on the current dialog box state.
2947 void SMESHGUI_MeshInfoDlg::updateSelection()
2949 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
2951 disconnect( selMgr, 0, this, 0 );
2952 selMgr->clearFilters();
2954 if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
2955 SMESH::SetPointRepresentation( false );
2956 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2957 aViewWindow->SetSelectionMode( ActorSelection );
2960 if ( myMode->checkedId() == NodeMode ) {
2961 SMESH::SetPointRepresentation( true );
2962 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2963 aViewWindow->SetSelectionMode( NodeSelection );
2966 SMESH::SetPointRepresentation( false );
2967 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
2968 aViewWindow->SetSelectionMode( CellSelection );
2972 QString oldID = myID->text().trimmed();
2973 SMESH_Actor* oldActor = myActor;
2976 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
2979 if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
2980 myID->setText( oldID );
2986 \brief Show help page
2988 void SMESHGUI_MeshInfoDlg::help()
2990 SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
2991 "mesh_infos_page.html#advanced_mesh_infos_anchor" :
2992 "mesh_infos_page.html#mesh_element_info_anchor" );
2996 \brief Show mesh information
2998 void SMESHGUI_MeshInfoDlg::updateInfo()
3000 SUIT_OverrideCursor wc;
3002 SALOME_ListIO selected;
3003 SMESHGUI::selectionMgr()->selectedObjects( selected );
3005 if ( selected.Extent() == 1 ) {
3006 Handle(SALOME_InteractiveObject) IO = selected.First();
3010 // myBaseInfo->clear();
3011 // myElemInfo->clear();
3012 // myAddInfo->clear();
3017 \brief Activate dialog box
3019 void SMESHGUI_MeshInfoDlg::activate()
3021 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3022 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3023 myTabWidget->setEnabled( true );
3028 \brief Deactivate dialog box
3030 void SMESHGUI_MeshInfoDlg::deactivate()
3032 myTabWidget->setEnabled( false );
3033 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3037 \brief Called when users switches between node / element modes.
3039 void SMESHGUI_MeshInfoDlg::modeChanged()
3046 \brief Caled when users prints mesh element ID in the corresponding field.
3048 void SMESHGUI_MeshInfoDlg::idChanged()
3050 SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
3051 if ( myActor && selector ) {
3052 Handle(SALOME_InteractiveObject) IO = myActor->getIO();
3053 TColStd_MapOfInteger ID;
3055 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3056 foreach ( QString tid, idTxt ) {
3057 long id = tid.trimmed().toLong();
3058 const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ?
3059 myActor->GetObject()->GetMesh()->FindElement( id ) :
3060 myActor->GetObject()->GetMesh()->FindNode( id );
3066 selector->AddOrRemoveIndex( IO, ID, false );
3067 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
3068 aViewWindow->highlight( IO, true, true );
3069 aViewWindow->Repaint();
3071 myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
3075 void SMESHGUI_MeshInfoDlg::showItemInfo( int id )
3077 if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id ) ) {
3078 myMode->button( NodeMode )->click();
3079 myID->setText( QString::number( id ) );
3083 void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr )
3085 if ( !theStr.isEmpty() ) {
3086 myMode->button( ElemMode )->click();
3087 myID->setText( theStr );
3091 void SMESHGUI_MeshInfoDlg::dump()
3093 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3095 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3096 if ( !appStudy ) return;
3097 _PTR( Study ) aStudy = appStudy->studyDS();
3099 QStringList aFilters;
3100 aFilters.append( tr( "TEXT_FILES" ) );
3102 bool anIsBase = true;
3103 bool anIsElem = true;
3104 bool anIsAdd = true;
3105 bool anIsCtrl = true;
3107 if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) {
3108 anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase );
3109 anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem );
3110 anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd );
3111 anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl );
3114 DumpFileDlg fd( this );
3115 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3116 fd.setFilters( aFilters );
3117 fd.myBaseChk->setChecked( anIsBase );
3118 fd.myElemChk->setChecked( anIsElem );
3119 fd.myAddChk ->setChecked( anIsAdd );
3120 fd.myCtrlChk->setChecked( anIsCtrl );
3121 if ( fd.exec() == QDialog::Accepted )
3123 QString aFileName = fd.selectedFile();
3125 bool toBase = fd.myBaseChk->isChecked();
3126 bool toElem = fd.myElemChk->isChecked();
3127 bool toAdd = fd.myAddChk->isChecked();
3128 bool toCtrl = fd.myCtrlChk->isChecked();
3130 if ( !aFileName.isEmpty() ) {
3131 QFileInfo aFileInfo( aFileName );
3132 if ( aFileInfo.isDir() )
3135 QFile aFile( aFileName );
3136 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3139 QTextStream out( &aFile );
3141 if ( toBase ) myBaseInfo->saveInfo( out );
3142 if ( toElem ) myElemInfo->saveInfo( out );
3143 if ( toAdd ) myAddInfo ->saveInfo( out );
3144 if ( toCtrl ) myCtrlInfo->saveInfo( out );
3150 \class SMESHGUI_CtrlInfo
3151 \brief Class for the mesh controls information widget.
3156 \param parent parent widget
3158 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
3159 : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
3161 setFrameStyle( StyledPanel | Sunken );
3163 myMainLayout = new QGridLayout( this );
3164 myMainLayout->setMargin( MARGIN );
3165 myMainLayout->setSpacing( SPACING );
3168 QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
3169 QLabel* aName = createField();
3170 aName->setMinimumWidth( 150 );
3173 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3174 QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3176 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3179 QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this );
3180 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3181 QLabel* aNodesFree = createField();
3182 myWidgets << aNodesFree;
3183 myPredicates << aFilterMgr->CreateFreeNodes();
3185 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3186 QLabel* aNodesDouble = createField();
3187 myWidgets << aNodesDouble;
3188 myPredicates << aFilterMgr->CreateEqualNodes();
3189 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3190 myToleranceWidget = new SMESHGUI_SpinBox( this );
3191 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3192 myToleranceWidget->setAcceptNames( false );
3193 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3196 QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this );
3197 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3198 QLabel* anEdgesDouble = createField();
3199 myWidgets << anEdgesDouble;
3200 myPredicates << aFilterMgr->CreateEqualEdges();
3203 QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this );
3204 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3205 QLabel* aFacesDouble = createField();
3206 myWidgets << aFacesDouble;
3207 myPredicates << aFilterMgr->CreateEqualFaces();
3208 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3209 QLabel* aFacesOver = createField();
3210 myWidgets << aFacesOver;
3211 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3212 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3213 myPlot = createPlot( this );
3214 myAspectRatio = aFilterMgr->CreateAspectRatio();
3217 QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this );
3218 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3219 QLabel* aVolumesDouble = createField();
3220 myWidgets << aVolumesDouble;
3221 myPredicates << aFilterMgr->CreateEqualVolumes();
3222 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3223 QLabel* aVolumesOver = createField();
3224 myWidgets << aVolumesOver;
3225 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3226 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3227 myPlot3D = createPlot( this );
3228 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3230 QToolButton* aFreeNodesBtn = new QToolButton( this );
3231 aFreeNodesBtn->setIcon(aComputeIcon);
3232 myButtons << aFreeNodesBtn; //0
3234 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3235 aDoubleNodesBtn->setIcon(aComputeIcon);
3236 myButtons << aDoubleNodesBtn; //1
3238 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3239 aDoubleEdgesBtn->setIcon(aComputeIcon);
3240 myButtons << aDoubleEdgesBtn; //2
3242 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3243 aDoubleFacesBtn->setIcon(aComputeIcon);
3244 myButtons << aDoubleFacesBtn; //3
3246 QToolButton* aOverContFacesBtn = new QToolButton( this );
3247 aOverContFacesBtn->setIcon(aComputeIcon);
3248 myButtons << aOverContFacesBtn; //4
3250 QToolButton* aComputeFaceBtn = new QToolButton( this );
3251 aComputeFaceBtn->setIcon(aComputeIcon);
3252 myButtons << aComputeFaceBtn; //5
3254 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3255 aDoubleVolumesBtn->setIcon(aComputeIcon);
3256 myButtons << aDoubleVolumesBtn; //6
3258 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3259 aOverContVolumesBtn->setIcon(aComputeIcon);
3260 myButtons << aOverContVolumesBtn; //7
3262 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3263 aComputeVolumeBtn->setIcon(aComputeIcon);
3264 myButtons << aComputeVolumeBtn; //8
3266 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3267 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3268 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3269 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3270 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3271 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3272 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3273 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3274 connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3275 connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double )));
3277 setFontAttributes( aNameLab );
3278 setFontAttributes( aNodesLab );
3279 setFontAttributes( anEdgesLab );
3280 setFontAttributes( aFacesLab );
3281 setFontAttributes( aVolumesLab );
3283 myMainLayout->addWidget( aNameLab, 0, 0 ); //0
3284 myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1
3285 myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2
3286 myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3
3287 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4
3288 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5
3289 myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6
3290 myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7
3291 myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8
3292 myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9
3293 myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10
3294 myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11
3295 myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12
3296 myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13
3297 myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14
3298 myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15
3299 myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16
3300 myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17
3301 myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18
3302 myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19
3303 myMainLayout->addWidget( aFacesOver, 9, 1 ); //20
3304 myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21
3305 myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22
3306 myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23
3307 myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24
3308 myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25
3309 myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26
3310 myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27
3311 myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28
3312 myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28
3313 myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30
3314 myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31
3315 myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32
3316 myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33
3317 myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34
3319 myMainLayout->setColumnStretch( 0, 0 );
3320 myMainLayout->setColumnStretch( 1, 5 );
3321 myMainLayout->setRowStretch ( 11, 5 );
3322 myMainLayout->setRowStretch ( 16, 5 );
3323 myMainLayout->setRowStretch ( 17, 1 );
3331 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3335 \brief Change widget font attributes (bold, ...).
3337 \param attr font attributes (XORed flags)
3339 void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w )
3342 QFont f = w->font();
3349 \brief Create info field
3350 \return new info field
3352 QLabel* SMESHGUI_CtrlInfo::createField()
3354 QLabel* lab = new QLabel( this );
3355 lab->setFrameStyle( StyledPanel | Sunken );
3356 lab->setAlignment( Qt::AlignCenter );
3357 lab->setAutoFillBackground( true );
3358 QPalette pal = lab->palette();
3359 pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
3360 lab->setPalette( pal );
3361 lab->setMinimumWidth( 60 );
3366 \brief Create QwtPlot
3369 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3371 QwtPlot* aPlot = new QwtPlot( parent );
3372 aPlot->setMinimumSize( 100, 100 );
3373 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3374 xFont.setPointSize( 5 );
3375 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3376 yFont.setPointSize( 5 );
3377 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3378 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3384 \brief Show controls information on the selected object
3386 void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
3390 myObject = SMESH::SMESH_IDSource::_duplicate( obj );
3391 if ( myObject->_is_nil() ) return;
3393 if ( _PTR(SObject) aSO = SMESH::FindSObject( obj ))
3394 myWidgets[0]->setText( aSO->GetName().c_str() );
3396 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3397 if ( mesh->_is_nil() ) return;
3399 const bool meshLoaded = mesh->IsLoaded();
3400 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3401 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3402 for ( int i = 0; i < myButtons.count(); ++i )
3403 myButtons[i]->setEnabled( true );
3405 SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType();
3406 if ( ! &nbElemsByType.in() ) return;
3408 const CORBA::Long ctrlLimit =
3409 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3412 const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ];
3413 const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3414 nbElemsByType[ SMESH::FACE ] +
3415 nbElemsByType[ SMESH::VOLUME ] );
3416 if ( nbNodes + nbElems > 0 ) {
3417 if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) {
3419 computeFreeNodesInfo();
3421 if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
3422 computeDoubleNodesInfo();
3425 myButtons[0]->setEnabled( true );
3426 myButtons[1]->setEnabled( true );
3430 for( int i=2; i<=10; i++)
3431 myMainLayout->itemAt(i)->widget()->setVisible( false );
3435 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3437 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3438 computeDoubleEdgesInfo();
3440 myButtons[2]->setEnabled( true );
3443 for( int i=11; i<=14; i++)
3444 myMainLayout->itemAt(i)->widget()->setVisible( false );
3448 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3449 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3451 computeDoubleFacesInfo();
3452 // over constrained faces
3453 computeOverConstrainedFacesInfo();
3454 // aspect Ratio histogram
3455 computeAspectRatio();
3458 myButtons[3]->setEnabled( true );
3459 myButtons[4]->setEnabled( true );
3460 myButtons[5]->setEnabled( true );
3464 myMainLayout->setRowStretch(11,0);
3465 for( int i=15; i<=24; i++)
3466 myMainLayout->itemAt(i)->widget()->setVisible( false );
3470 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3471 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3473 computeDoubleVolumesInfo();
3474 // over constrained volumes
3475 computeOverConstrainedVolumesInfo();
3476 // aspect Ratio 3D histogram
3477 computeAspectRatio3D();
3480 myButtons[6]->setEnabled( true );
3481 myButtons[7]->setEnabled( true );
3482 myButtons[8]->setEnabled( true );
3486 myMainLayout->setRowStretch(16,0);
3487 for( int i=25; i<=34; i++)
3488 myMainLayout->itemAt(i)->widget()->setVisible( false );
3492 //================================================================================
3494 * \brief Computes and shows nb of elements satisfying a given predicate
3495 * \param [in] ft - a predicate type (SMESH::FunctorType)
3496 * \param [in] iBut - index of one of myButtons to disable
3497 * \param [in] iWdg - index of one of myWidgets to show the computed number
3499 //================================================================================
3501 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3503 myButtons[ iBut ]->setEnabled( false );
3504 myWidgets[ iWdg ]->setText( "" );
3505 if ( myObject->_is_nil() ) return;
3507 SUIT_OverrideCursor wc;
3509 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3510 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3513 this->showInfo( myObject ); // try to show all values
3514 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3515 return; // <ft> predicate already computed
3517 // look for a predicate of type <ft>
3518 for ( int i = 0; i < myPredicates.count(); ++i )
3519 if ( myPredicates[i]->GetFunctorType() == ft )
3521 CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject );
3522 myWidgets[ iWdg ]->setText( QString::number( nb ));
3526 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3528 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3531 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3533 computeNb( SMESH::FT_EqualNodes, 1, 2 );
3536 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3538 computeNb( SMESH::FT_EqualEdges, 2, 3 );
3541 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3543 computeNb( SMESH::FT_EqualFaces, 3, 4 );
3546 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3548 computeNb( SMESH::FT_OverConstrainedFace, 4, 5 );
3551 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3553 computeNb( SMESH::FT_EqualVolumes, 6, 6 );
3556 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3558 computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 );
3561 void SMESHGUI_CtrlInfo::computeAspectRatio()
3563 myButtons[5]->setEnabled( false );
3565 if ( myObject->_is_nil() ) return;
3567 SUIT_OverrideCursor wc;
3569 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3570 if ( aHistogram && !aHistogram->isEmpty() ) {
3571 QwtPlotItem* anItem = aHistogram->createPlotItem();
3572 anItem->attach( myPlot );
3578 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3580 myButtons[8]->setEnabled( false );
3582 if ( myObject->_is_nil() ) return;
3584 SUIT_OverrideCursor wc;
3586 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3587 if ( aHistogram && !aHistogram->isEmpty() ) {
3588 QwtPlotItem* anItem = aHistogram->createPlotItem();
3589 anItem->attach( myPlot3D );
3596 \brief Internal clean-up (reset widget)
3598 void SMESHGUI_CtrlInfo::clearInternal()
3600 for( int i=0; i<=34; i++)
3601 myMainLayout->itemAt(i)->widget()->setVisible( true );
3602 for( int i=0; i<=8; i++)
3603 myButtons[i]->setEnabled( false );
3604 myPlot->detachItems();
3605 myPlot3D->detachItems();
3608 myWidgets[0]->setText( QString() );
3609 for ( int i = 1; i < myWidgets.count(); i++ )
3610 myWidgets[i]->setText( "" );
3611 myMainLayout->setRowStretch(11,5);
3612 myMainLayout->setRowStretch(16,5);
3615 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3617 //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE );
3618 myButtons[1]->setEnabled( true );
3619 myWidgets[2]->setText("");
3622 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3624 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
3625 if ( mesh->_is_nil() ) return 0;
3626 if ( !mesh->IsLoaded() )
3628 aNumFun->SetMesh( mesh );
3630 CORBA::Long cprecision = 6;
3631 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3632 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3633 aNumFun->SetPrecision( cprecision );
3635 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3637 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3638 /*isLogarithmic=*/false,
3640 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3641 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3642 if ( &histogramVar.in() )
3644 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3645 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3646 if ( histogramVar->length() >= 2 )
3647 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3652 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
3653 out << QString( 20, '-' ) << "\n";
3654 out << tr( "CTRL_INFO" ) << "\n";
3655 out << QString( 20, '-' ) << "\n";
3656 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n";
3657 out << tr( "NODES_INFO" ) << "\n";
3658 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n";
3659 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n";
3660 out << tr( "EDGES_INFO" ) << "\n";
3661 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n";
3662 out << tr( "FACES_INFO" ) << "\n";
3663 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n";
3664 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n";
3665 out << tr( "VOLUMES_INFO" ) << "\n";
3666 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n";
3667 out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n";
3671 \class SMESHGUI_CtrlInfoDlg
3672 \brief Controls information dialog box
3677 \param parent parent widget
3678 \param page specifies the dialog page to be shown at the start-up
3680 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
3683 setAttribute( Qt::WA_DeleteOnClose, true );
3684 setWindowTitle( tr( "CTRL_INFO" ) );
3685 setMinimumSize( 400, 600 );
3687 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
3690 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3691 okBtn->setAutoDefault( true );
3692 okBtn->setDefault( true );
3694 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3695 dumpBtn->setAutoDefault( true );
3696 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3697 helpBtn->setAutoDefault( true );
3699 QHBoxLayout* btnLayout = new QHBoxLayout;
3700 btnLayout->setSpacing( SPACING );
3701 btnLayout->setMargin( 0 );
3703 btnLayout->addWidget( okBtn );
3704 btnLayout->addWidget( dumpBtn );
3705 btnLayout->addStretch( 10 );
3706 btnLayout->addWidget( helpBtn );
3708 QVBoxLayout* l = new QVBoxLayout ( this );
3709 l->setMargin( MARGIN );
3710 l->setSpacing( SPACING );
3711 l->addWidget( myCtrlInfo );
3712 l->addLayout( btnLayout );
3714 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3715 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3716 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3717 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3718 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3726 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
3731 \brief Show controls information
3732 \param IO interactive object
3734 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
3736 if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
3737 myCtrlInfo->showInfo( obj );
3741 \brief Perform clean-up actions on the dialog box closing.
3743 void SMESHGUI_CtrlInfoDlg::reject()
3745 SMESH::SetPointRepresentation( false );
3750 \brief Setup selection mode depending on the current dialog box state.
3752 void SMESHGUI_CtrlInfoDlg::updateSelection()
3754 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3755 disconnect( selMgr, 0, this, 0 );
3756 SMESH::SetPointRepresentation( false );
3757 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3762 \brief Show mesh information
3764 void SMESHGUI_CtrlInfoDlg::updateInfo()
3766 SUIT_OverrideCursor wc;
3768 SALOME_ListIO selected;
3769 SMESHGUI::selectionMgr()->selectedObjects( selected );
3771 if ( selected.Extent() == 1 ) {
3772 Handle(SALOME_InteractiveObject) IO = selected.First();
3778 \brief Activate dialog box
3780 void SMESHGUI_CtrlInfoDlg::activate()
3782 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
3783 SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
3788 \brief Deactivate dialog box
3790 void SMESHGUI_CtrlInfoDlg::deactivate()
3792 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3796 * \brief Dump contents into a file
3798 void SMESHGUI_CtrlInfoDlg::dump()
3800 SUIT_Application* app = SUIT_Session::session()->activeApplication();
3802 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study *>( app->activeStudy() );
3803 if ( !appStudy ) return;
3804 _PTR( Study ) aStudy = appStudy->studyDS();
3806 QStringList aFilters;
3807 aFilters.append( tr( "TEXT_FILES" ) );
3809 DumpFileDlg fd( this );
3810 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3811 fd.setFilters( aFilters );
3812 fd.myBaseChk->hide();
3813 fd.myElemChk->hide();
3814 fd.myAddChk ->hide();
3815 fd.myCtrlChk->hide();
3816 if ( fd.exec() == QDialog::Accepted )
3818 QString aFileName = fd.selectedFile();
3819 if ( !aFileName.isEmpty() ) {
3820 QFileInfo aFileInfo( aFileName );
3821 if ( aFileInfo.isDir() )
3824 QFile aFile( aFileName );
3825 if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
3828 QTextStream out( &aFile );
3829 myCtrlInfo->saveInfo( out );
3837 void SMESHGUI_CtrlInfoDlg::help()
3839 SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor");