X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_MeshInfo.cxx;h=95e214d31b1bcc3253a9d84d8c6901e009e2c5ee;hp=255951008d61b34e164fef509623fdf3f1ce6537;hb=d4a710ce52f6e76786a7b3845e2f7975dc9a00b1;hpb=43a4d0b5c1ac4677ceb09f3059053e60c911bcf6 diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 255951008..95e214d31 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -1,23 +1,23 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : SMESHGUI_MeshInfo.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) @@ -52,16 +52,16 @@ #include #include #include -#include #include #include "utilities.h" #include -#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(GEOM_Gen) -const int SPACING = 6; -const int MARGIN = 9; +const int SPACING = 6; +const int MARGIN = 9; +const int MAXITEMS = 10; /*! \class SMESHGUI_MeshInfo @@ -169,6 +169,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) QLabel* a3DPriTotal = createField(); QLabel* a3DPriLin = createField(); QLabel* a3DPriQuad = createField(); + QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this ); + QLabel* a3DHexPriTotal = createField(); QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this ); QLabel* a3DPolTotal = createField(); myWidgets[15] << a3DLine; @@ -177,8 +179,13 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) myWidgets[18] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad; myWidgets[19] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad; myWidgets[20] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad; - myWidgets[21] << a3DPolLab << a3DPolTotal; + myWidgets[21] << a3DHexPriLab << a3DHexPriTotal; + myWidgets[22] << a3DPolLab << a3DPolTotal; + myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this ); + myLoadBtn->setAutoDefault( true ); + connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) ); + setFontAttributes( aNameLab, Bold ); setFontAttributes( aObjLab, Bold ); setFontAttributes( aNodesLab, Bold ); @@ -247,13 +254,16 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) l->addWidget( a3DPriTotal, 20, 1 ); l->addWidget( a3DPriLin, 20, 2 ); l->addWidget( a3DPriQuad, 20, 3 ); - l->addWidget( a3DPolLab, 21, 0 ); - l->addWidget( a3DPolTotal, 21, 1 ); + l->addWidget( a3DHexPriLab, 21, 0 ); + l->addWidget( a3DHexPriTotal, 21, 1 ); + l->addWidget( a3DPolLab, 22, 0 ); + l->addWidget( a3DPolTotal, 22, 1 ); + l->addWidget( myLoadBtn, 23, 1, 1, 3 ); l->setColumnStretch( 0, 0 ); l->setColumnStretch( 1, 5 ); l->setColumnStretch( 2, 5 ); l->setColumnStretch( 3, 5 ); - l->setRowStretch( 22, 5 ); + l->setRowStretch( 23, 5 ); clear(); } @@ -273,7 +283,7 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) { clear(); if ( !CORBA::is_nil( obj ) ) { - _PTR(SObject) sobj = ObjectToSObject( obj ); + _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); if ( sobj ) myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() ); SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); @@ -289,69 +299,177 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) QString objType; switch( aGroup->GetType() ) { case SMESH::NODE: - objType = tr( "OBJECT_GROUP_NODES" ); - break; + objType = tr( "OBJECT_GROUP_NODES" ); + break; case SMESH::EDGE: - objType = tr( "OBJECT_GROUP_EDGES" ); - break; + objType = tr( "OBJECT_GROUP_EDGES" ); + break; case SMESH::FACE: - objType = tr( "OBJECT_GROUP_FACES" ); - break; + objType = tr( "OBJECT_GROUP_FACES" ); + break; case SMESH::VOLUME: - objType = tr( "OBJECT_GROUP_VOLUMES" ); - break; + objType = tr( "OBJECT_GROUP_VOLUMES" ); + break; case SMESH::ELEM0D: - objType = tr( "OBJECT_GROUP_0DELEMS" ); - break; + objType = tr( "OBJECT_GROUP_0DELEMS" ); + break; default: - objType = tr( "OBJECT_GROUP" ); - break; + objType = tr( "OBJECT_GROUP" ); + break; } myWidgets[iObject][iSingle]->setProperty( "text", objType ); } SMESH::long_array_var info = obj->GetMeshInfo(); - myWidgets[iNodes][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Node] ) ); - myWidgets[i0D][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_0D] ) ); + myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) ); + myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) ); long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge]; - myWidgets[i1D][iTotal]->setProperty( "text", QString::number( nbEdges ) ); - myWidgets[i1D][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) ); + myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) ); + myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) ); myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) ); long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle]; - long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle]; + long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; - long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle]; - myWidgets[i2D][iTotal]->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) ); - myWidgets[i2D][iLinear]->setProperty( "text", QString::number( nb2DLinear ) ); - myWidgets[i2D][iQuadratic]->setProperty( "text", QString::number( nb2DQuadratic ) ); - myWidgets[i2DTriangles][iTotal]->setProperty( "text", QString::number( nbTriangles ) ); - myWidgets[i2DTriangles][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) ); - myWidgets[i2DTriangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) ); - myWidgets[i2DQuadrangles][iTotal]->setProperty( "text", QString::number( nbQuadrangles ) ); - myWidgets[i2DQuadrangles][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) ); - myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) ); - myWidgets[i2DPolygons][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) ); + long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; + myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) ); + myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) ); + myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] )); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) ); long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; - long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa]; + long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa]; long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid]; long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta]; - long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra]; - long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; - myWidgets[i3D][iTotal]->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) ); - myWidgets[i3D][iLinear]->setProperty( "text", QString::number( nb3DLinear ) ); - myWidgets[i3D][iQuadratic]->setProperty( "text", QString::number( nb3DQuadratic ) ); - myWidgets[i3DTetrahedrons][iTotal]->setProperty( "text", QString::number( nbTetrahedrons ) ); - myWidgets[i3DTetrahedrons][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) ); + long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism]; + long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; + myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) ); + myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) ); myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) ); - myWidgets[i3DHexahedrons][iTotal]->setProperty( "text", QString::number( nbHexahedrons ) ); - myWidgets[i3DHexahedrons][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) ); - myWidgets[i3DHexahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) ); - myWidgets[i3DPyramids][iTotal]->setProperty( "text", QString::number( nbPyramids ) ); - myWidgets[i3DPyramids][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) ); - myWidgets[i3DPyramids][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) ); - myWidgets[i3DPrisms][iTotal]->setProperty( "text", QString::number( nbPrisms ) ); - myWidgets[i3DPrisms][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) ); - myWidgets[i3DPrisms][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) ); - myWidgets[i3DPolyhedrons][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] ) ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) ); + + // before full loading from study file, type of elements in a sub-mesh can't be defined + // in some cases + bool infoOK = obj->IsMeshInfoCorrect(); + myLoadBtn->setVisible( !infoOK ); + if ( !infoOK ) + { + // two options: + // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh) + // 2. No info at all (for a group on geom or filter) + bool hasAnyInfo = false; + for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i ) + hasAnyInfo = info[i]; + if ( hasAnyInfo ) // believe it is a sub-mesh + { + if ( nb2DLinear + nb2DQuadratic > 0 ) + { + myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", "?" ); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); + } + else if ( nb3DLinear + nb3DQuadratic > 0 ) + { + myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" ); + } + } + else + { + myWidgets[iNodes][iTotal] ->setProperty( "text", "?" ); + myWidgets[i0D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i1D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i1D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" ); + } + } + } +} + +/*! + \brief Load mesh from a study file +*/ +void SMESHGUI_MeshInfo::loadMesh() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->_is_nil() ) + { + mesh->Load(); + showInfo( obj ); + } + } } } @@ -392,6 +510,7 @@ void SMESHGUI_MeshInfo::clear() myWidgets[i3DPrisms][iTotal]->setProperty( "text", QString::number( 0 ) ); myWidgets[i3DPrisms][iLinear]->setProperty( "text", QString::number( 0 ) ); myWidgets[i3DPrisms][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexaPrisms][iTotal]->setProperty( "text", QString::number( 0 ) ); myWidgets[i3DPolyhedrons][iTotal]->setProperty( "text", QString::number( 0 ) ); } @@ -465,8 +584,29 @@ void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on ) \param parent parent widget */ SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ) -: QWidget( parent ), myActor( 0 ), myID( 0 ), myIsElement( -1 ) +: QWidget( parent ), myActor( 0 ), myIsElement( -1 ) { + myFrame = new QWidget( this ); + myExtra = new QWidget( this ); + myCurrent = new QLabel( "10/43 items shown", myExtra ); + myCurrent->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); + myPrev = new QPushButton( tr( "<<" ), myExtra ); + myNext = new QPushButton( tr( ">>" ), myExtra ); + QHBoxLayout* hbl = new QHBoxLayout( myExtra ); + hbl->setContentsMargins( 0, SPACING, 0, 0 ); + hbl->setSpacing( SPACING ); + hbl->addStretch(); + hbl->addWidget( myCurrent ); + hbl->addWidget( myPrev ); + hbl->addWidget( myNext ); + QVBoxLayout* vbl = new QVBoxLayout( this ); + vbl->setMargin( 0 ); + vbl->setSpacing( 0 ); + vbl->addWidget( myFrame ); + vbl->addWidget( myExtra ); + connect( myPrev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) ); + connect( myNext, SIGNAL( clicked() ), this, SLOT( showNext() ) ); + clear(); } /*! @@ -484,7 +624,6 @@ void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor ) { if ( myActor != actor ) { myActor = actor; - myID = 0; myIsElement = -1; clear(); } @@ -492,19 +631,87 @@ void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor ) /*! \brief Show mesh element information - \param long id mesh node / element ID + \param id mesh node / element ID \param isElem show mesh element information if \c true or mesh node information if \c false */ void SMESHGUI_ElemInfo::showInfo( long id, bool isElem ) { - myID = id; + QSet ids; + ids << id; + showInfo( ids, isElem ); +} + +/*! + \brief Show mesh element information + \param ids mesh nodes / elements identifiers + \param isElem show mesh element information if \c true or mesh node information if \c false +*/ +void SMESHGUI_ElemInfo::showInfo( QSet ids, bool isElem ) +{ + QList newIds = ids.toList(); + qSort( newIds ); + if ( myIDs == newIds && myIsElement == isElem ) return; + + myIDs = newIds; myIsElement = isElem; + myIndex = 0; + updateControls(); + information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) ); } /*! - \fn void SMESHGUI_ElemInfo::clear() \brief Clear mesh element information widget */ +void SMESHGUI_ElemInfo::clear() +{ + myIDs.clear(); + myIndex = 0; + clearInternal(); + updateControls(); +} + +/*! + \brief Get central area widget + \return central widget +*/ +QWidget* SMESHGUI_ElemInfo::frame() const +{ + return myFrame; +} + +/*! + \brief Get actor + \return actor being used +*/ +SMESH_Actor* SMESHGUI_ElemInfo::actor() const +{ + return myActor; +} + +/*! + \brief Get current info mode. + \return \c true if mesh element information is shown or \c false if node information is shown +*/ +bool SMESHGUI_ElemInfo::isElements() const +{ + return myIsElement; +} + +/*! + \fn void SMESHGUI_ElemInfo::information( const QList& ids ) + \brief Show information on the specified nodes / elements + + This function is to be redefined in sub-classes. + + \param ids nodes / elements identifiers information is to be shown on +*/ + +/*! + \brief Internal clean-up (reset widget) +*/ +void SMESHGUI_ElemInfo::clearInternal() +{ +} /*! \brief Get node connectivity @@ -560,6 +767,39 @@ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* return xyz; } +/*! + \brief This slot is called from "Show Previous" button click. + Shows information on the previous group of the items. +*/ +void SMESHGUI_ElemInfo::showPrevious() +{ + myIndex = qMax( 0, myIndex-1 ); + updateControls(); + information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) ); +} + +/*! + \brief This slot is called from "Show Next" button click. + Shows information on the next group of the items. +*/ +void SMESHGUI_ElemInfo::showNext() +{ + myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS ); + updateControls(); + information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) ); +} + +/*! + \brief Update widgets state +*/ +void SMESHGUI_ElemInfo::updateControls() +{ + myExtra->setVisible( myIDs.count() > MAXITEMS ); + myCurrent->setText( tr( "X_FROM_Y_ITEMS_SHOWN" ).arg( myIndex*MAXITEMS+1 ).arg(qMin(myIndex*MAXITEMS+MAXITEMS, myIDs.count())).arg( myIDs.count() ) ); + myPrev->setEnabled( myIndex > 0 ); + myNext->setEnabled( (myIndex+1)*MAXITEMS < myIDs.count() ); +} + /*! \class SMESHGUI_SimpleElemInfo \brief Represents mesh element information in the simple text area. @@ -572,178 +812,183 @@ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) : SMESHGUI_ElemInfo( parent ) { - myInfo = new QTextBrowser( this ); - QVBoxLayout* l = new QVBoxLayout( this ); + myInfo = new QTextBrowser( frame() ); + QVBoxLayout* l = new QVBoxLayout( frame() ); l->setMargin( 0 ); l->addWidget( myInfo ); } /*! \brief Show mesh element information - \param long id mesh node / element ID - \param isElem show mesh element information if \c true or mesh node information if \c false + \param ids mesh nodes / elements identifiers */ -void SMESHGUI_SimpleElemInfo::showInfo( long id, bool isElem ) +void SMESHGUI_SimpleElemInfo::information( const QList& ids ) { - if ( myID == id && myIsElement == isElem ) return; - - SMESHGUI_ElemInfo::showInfo( id, isElem ); - - clear(); + clearInternal(); - if ( myActor ) { + if ( actor() ) { int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - if ( !isElem ) { - // - // show node info - // - const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindNode( id ); - if ( !e ) return; - const SMDS_MeshNode* node = static_cast( e ); - - // node ID - myInfo->append( QString( "%1 #%2" ).arg( tr( "NODE" ) ).arg( id ) ); - // separator - myInfo->append( "" ); - // coordinates - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ). - arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). - arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). - arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - // separator - myInfo->append( "" ); - // connectivity - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - myInfo->append( QString( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + foreach ( long id, ids ) { + if ( !isElements() ) { + // + // show node info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id ); + if ( !e ) return; + const SMDS_MeshNode* node = static_cast( e ); + + // node ID + myInfo->append( QString( "%1 #%2" ).arg( tr( "NODE" ) ).arg( id ) ); + // separator + myInfo->append( "" ); + // coordinates + myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ). + arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // separator + myInfo->append( "" ); + // connectivity + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + myInfo->append( QString( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + } + else { + myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); + } } else { - myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); - } - } - else { - // - // show element info - // - const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindElement( id ); - if ( !e ) return; - - // element ID && type - QString stype; - switch( e->GetType() ) { - case SMDSAbs_0DElement: - stype = tr( "0D ELEMENT" ); break; - case SMDSAbs_Edge: - stype = tr( "EDGE" ); break; - case SMDSAbs_Face: - stype = tr( "FACE" ); break; - case SMDSAbs_Volume: - stype = tr( "VOLUME" ); break; - default: - break; + // + // show element info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( !e ) return; + + // element ID && type + QString stype; + switch( e->GetType() ) { + case SMDSAbs_0DElement: + stype = tr( "0D ELEMENT" ); break; + case SMDSAbs_Edge: + stype = tr( "EDGE" ); break; + case SMDSAbs_Face: + stype = tr( "FACE" ); break; + case SMDSAbs_Volume: + stype = tr( "VOLUME" ); break; + default: + break; + } + if ( stype.isEmpty() ) return; + myInfo->append( QString( "%1 #%2" ).arg( stype ).arg( id ) ); + // separator + myInfo->append( "" ); + // geometry type + QString gtype; + switch( e->GetEntityType() ) { + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + gtype = tr( "TRIANGLE" ); break; + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + gtype = tr( "QUADRANGLE" ); break; + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: + gtype = tr( "POLYGON" ); break; + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + gtype = tr( "TETRAHEDRON" ); break; + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + gtype = tr( "PYRAMID" ); break; + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + gtype = tr( "HEXAHEDRON" ); break; + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + gtype = tr( "PRISM" ); break; + case SMDSEntity_Hexagonal_Prism: + gtype = tr( "HEX_PRISM" ); break; + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: + gtype = tr( "POLYHEDRON" ); break; + default: + break; + } + if ( !gtype.isEmpty() ) + myInfo->append( QString( "%1: %2" ).arg( tr( "TYPE" ) ).arg( gtype ) ); + // quadratic flag and gravity center (any element except 0D) + if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) { + // quadratic flag + myInfo->append( QString( "%1? %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) ); + // separator + myInfo->append( "" ); + // gravity center + XYZ gc = gravityCenter( e ); + myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) ); + } + // separator + myInfo->append( "" ); + // connectivity + SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); + for ( int idx = 1; nodeIt->more(); idx++ ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + // node number and ID + myInfo->append( QString( "%1 %2/%3 - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) ); + // node coordinates + myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ). + arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // node connectivity + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + myInfo->append( QString( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + } + else { + myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); + } + } } - if ( stype.isEmpty() ) return; - myInfo->append( QString( "%1 #%2" ).arg( stype ).arg( id ) ); // separator - myInfo->append( "" ); - // geometry type - QString gtype; - switch( e->GetEntityType() ) { - case SMDSEntity_Triangle: - case SMDSEntity_Quad_Triangle: - gtype = tr( "TRIANGLE" ); break; - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - gtype = tr( "QUADRANGLE" ); break; - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: - gtype = tr( "POLYGON" ); break; - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - gtype = tr( "TETRAHEDRON" ); break; - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - gtype = tr( "PYRAMID" ); break; - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - gtype = tr( "HEXAHEDRON" ); break; - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - gtype = tr( "PRISM" ); break; - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: - gtype = tr( "POLYHEDRON" ); break; - default: - break; - } - if ( !gtype.isEmpty() ) - myInfo->append( QString( "%1: %2" ).arg( tr( "TYPE" ) ).arg( gtype ) ); - // quadratic flag and gravity center (any element except 0D) - if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) { - // quadratic flag - myInfo->append( QString( "%1? %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) ); - // separator - myInfo->append( "" ); - // gravity center - XYZ gc = gravityCenter( e ); - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) ); - } - // separator - myInfo->append( "" ); - // connectivity - SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); - for ( int idx = 1; nodeIt->more(); idx++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - // node number and ID - myInfo->append( QString( "%1 %2/%3 - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) ); - // node coordinates - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ). - arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). - arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). - arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - // node connectivity - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - myInfo->append( QString( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); - } - else { - myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); - } - // separator - myInfo->append( "" ); + if ( ids.count() > 1 ) { + myInfo->append( "" ); + myInfo->append( "------" ); + myInfo->append( "" ); } } } } /*! - \brief Clear mesh element information widget + \brief Internal clean-up (reset widget) */ -void SMESHGUI_SimpleElemInfo::clear() +void SMESHGUI_SimpleElemInfo::clearInternal() { myInfo->clear(); } @@ -791,240 +1036,233 @@ QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, con SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent ) : SMESHGUI_ElemInfo( parent ) { - myInfo = new QTreeWidget( this ); + myInfo = new QTreeWidget( frame() ); myInfo->setColumnCount( 2 ); myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) ); myInfo->header()->setStretchLastSection( true ); myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); myInfo->setItemDelegate( new ItemDelegate( myInfo ) ); - QVBoxLayout* l = new QVBoxLayout( this ); + QVBoxLayout* l = new QVBoxLayout( frame() ); l->setMargin( 0 ); l->addWidget( myInfo ); } /*! \brief Show mesh element information - \param long id mesh node / element ID - \param isElem show mesh element information if \c true or mesh node information if \c false + \param ids mesh nodes / elements identifiers */ -void SMESHGUI_TreeElemInfo::showInfo( long id, bool isElem ) +void SMESHGUI_TreeElemInfo::information( const QList& ids ) { - if ( myID == id && myIsElement == isElem ) return; - - SMESHGUI_ElemInfo::showInfo( id, isElem ); + clearInternal(); - clear(); - - if ( myActor ) { + if ( actor() ) { int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - if ( !isElem ) { - // - // show node info - // - const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindNode( id ); - if ( !e ) return; - const SMDS_MeshNode* node = static_cast( e ); + foreach ( long id, ids ) { + if ( !isElements() ) { + // + // show node info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id ); + if ( !e ) return; + const SMDS_MeshNode* node = static_cast( e ); - // node ID - QTreeWidgetItem* nodeItem = createItem( 0, -1 ); - nodeItem->setText( 0, tr( "NODE" ) ); - nodeItem->setText( 1, QString( "#%1" ).arg( id ) ); - nodeItem->setExpanded( true ); - // coordinates - QTreeWidgetItem* coordItem = createItem( nodeItem, 0 ); - coordItem->setText( 0, tr( "COORDINATES" ) ); - coordItem->setExpanded( true ); - QTreeWidgetItem* xItem = createItem( coordItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - QTreeWidgetItem* yItem = createItem( coordItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - QTreeWidgetItem* zItem = createItem( coordItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - // connectivity - QTreeWidgetItem* conItem = createItem( nodeItem, 0 ); - conItem->setText( 0, tr( "CONNECTIVITY" ) ); - conItem->setExpanded( true ); - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, tr( "0D_ELEMENTS" ) ); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, tr( "EDGES" ) ); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, tr( "FACES" ) ); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, tr( "VOLUMES" ) ); - i->setText( 1, con ); - } + // node ID + QTreeWidgetItem* nodeItem = createItem( 0, Bold | All ); + nodeItem->setText( 0, tr( "NODE" ) ); + nodeItem->setText( 1, QString( "#%1" ).arg( id ) ); + // coordinates + QTreeWidgetItem* coordItem = createItem( nodeItem, Bold ); + coordItem->setText( 0, tr( "COORDINATES" ) ); + QTreeWidgetItem* xItem = createItem( coordItem ); + xItem->setText( 0, "X" ); + xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* yItem = createItem( coordItem ); + yItem->setText( 0, "Y" ); + yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* zItem = createItem( coordItem ); + zItem->setText( 0, "Z" ); + zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // connectivity + QTreeWidgetItem* conItem = createItem( nodeItem, Bold ); + conItem->setText( 0, tr( "CONNECTIVITY" ) ); + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "0D_ELEMENTS" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "EDGES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "FACES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "VOLUMES" ) ); + i->setText( 1, con ); + } + } + else { + conItem->setText( 1, tr( "FREE_NODE" ) ); + } } else { - conItem->setText( 1, tr( "FREE_NODE" ) ); - } - } - else { - // - // show element info - // - const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindElement( id ); - if ( !e ) return; - - // element ID && type - QString stype; - switch( e->GetType() ) { - case SMDSAbs_0DElement: - stype = tr( "0D ELEMENT" ); break; - case SMDSAbs_Edge: - stype = tr( "EDGE" ); break; - case SMDSAbs_Face: - stype = tr( "FACE" ); break; - case SMDSAbs_Volume: - stype = tr( "VOLUME" ); break; - default: - break; - } - if ( stype.isEmpty() ) return; - QTreeWidgetItem* elemItem = createItem( 0, -1 ); - elemItem->setText( 0, stype ); - elemItem->setText( 1, QString( "#%1" ).arg( id ) ); - elemItem->setExpanded( true ); - // geometry type - QString gtype; - switch( e->GetEntityType() ) { - case SMDSEntity_Triangle: - case SMDSEntity_Quad_Triangle: - gtype = tr( "TRIANGLE" ); break; - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - gtype = tr( "QUADRANGLE" ); break; - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: - gtype = tr( "POLYGON" ); break; - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - gtype = tr( "TETRAHEDRON" ); break; - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - gtype = tr( "PYRAMID" ); break; - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - gtype = tr( "HEXAHEDRON" ); break; - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - gtype = tr( "PRISM" ); break; - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: - gtype = tr( "POLYHEDRON" ); break; - default: - break; - } - if ( !gtype.isEmpty() ) { - QTreeWidgetItem* typeItem = createItem( elemItem, 0 ); - typeItem->setText( 0, tr( "TYPE" ) ); - typeItem->setText( 1, gtype ); - } - // quadratic flag and gravity center (any element except 0D) - if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) { - // quadratic flag - QTreeWidgetItem* quadItem = createItem( elemItem, 0 ); - quadItem->setText( 0, tr( "QUADRATIC" ) ); - quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ); - // gravity center - XYZ gc = gravityCenter( e ); - QTreeWidgetItem* gcItem = createItem( elemItem, 0 ); - gcItem->setText( 0, tr( "GRAVITY_CENTER" ) ); - gcItem->setExpanded( true ); - QTreeWidgetItem* xItem = createItem( gcItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - QTreeWidgetItem* yItem = createItem( gcItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - QTreeWidgetItem* zItem = createItem( gcItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - } - // connectivity - QTreeWidgetItem* conItem = createItem( elemItem, 0 ); - conItem->setText( 0, tr( "CONNECTIVITY" ) ); - conItem->setExpanded( true ); - SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); - for ( int idx = 1; nodeIt->more(); idx++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - // node number and ID - QTreeWidgetItem* nodeItem = createItem( conItem, 0 ); - nodeItem->setText( 0, QString( "%1 %2/%3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) ); - nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) ); - //nodeItem->setExpanded( true ); - // node coordinates - QTreeWidgetItem* coordItem = createItem( nodeItem ); - coordItem->setText( 0, tr( "COORDINATES" ) ); - coordItem->setExpanded( true ); - QTreeWidgetItem* xItem = createItem( coordItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - QTreeWidgetItem* yItem = createItem( coordItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - QTreeWidgetItem* zItem = createItem( coordItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); - // node connectivity - QTreeWidgetItem* nconItem = createItem( nodeItem ); - nconItem->setText( 0, tr( "CONNECTIVITY" ) ); - nconItem->setExpanded( true ); - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, tr( "0D_ELEMENTS" ) ); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, tr( "EDGES" ) ); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, tr( "FACES" ) ); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, tr( "VOLUMES" ) ); - i->setText( 1, con ); - } - } + // + // show element info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( !e ) return; + + // element ID && type + QString stype; + switch( e->GetType() ) { + case SMDSAbs_0DElement: + stype = tr( "0D ELEMENT" ); break; + case SMDSAbs_Edge: + stype = tr( "EDGE" ); break; + case SMDSAbs_Face: + stype = tr( "FACE" ); break; + case SMDSAbs_Volume: + stype = tr( "VOLUME" ); break; + default: + break; + } + if ( stype.isEmpty() ) return; + QTreeWidgetItem* elemItem = createItem( 0, Bold | All ); + elemItem->setText( 0, stype ); + elemItem->setText( 1, QString( "#%1" ).arg( id ) ); + // geometry type + QString gtype; + switch( e->GetEntityType() ) { + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + gtype = tr( "TRIANGLE" ); break; + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + gtype = tr( "QUADRANGLE" ); break; + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: + gtype = tr( "POLYGON" ); break; + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + gtype = tr( "TETRAHEDRON" ); break; + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + gtype = tr( "PYRAMID" ); break; + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + gtype = tr( "HEXAHEDRON" ); break; + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + gtype = tr( "PRISM" ); break; + case SMDSEntity_Hexagonal_Prism: + gtype = tr( "HEX_PRISM" ); break; + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: + gtype = tr( "POLYHEDRON" ); break; + default: + break; + } + if ( !gtype.isEmpty() ) { + QTreeWidgetItem* typeItem = createItem( elemItem, Bold ); + typeItem->setText( 0, tr( "TYPE" ) ); + typeItem->setText( 1, gtype ); + } + // quadratic flag and gravity center (any element except 0D) + if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) { + // quadratic flag + QTreeWidgetItem* quadItem = createItem( elemItem, Bold ); + quadItem->setText( 0, tr( "QUADRATIC" ) ); + quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ); + // gravity center + XYZ gc = gravityCenter( e ); + QTreeWidgetItem* gcItem = createItem( elemItem, Bold ); + gcItem->setText( 0, tr( "GRAVITY_CENTER" ) ); + QTreeWidgetItem* xItem = createItem( gcItem ); + xItem->setText( 0, "X" ); + xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* yItem = createItem( gcItem ); + yItem->setText( 0, "Y" ); + yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* zItem = createItem( gcItem ); + zItem->setText( 0, "Z" ); + zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + } + // connectivity + QTreeWidgetItem* conItem = createItem( elemItem, Bold ); + conItem->setText( 0, tr( "CONNECTIVITY" ) ); + SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); + for ( int idx = 1; nodeIt->more(); idx++ ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + // node number and ID + QTreeWidgetItem* nodeItem = createItem( conItem, Bold ); + nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) ); + nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) ); + nodeItem->setExpanded( false ); + // node coordinates + QTreeWidgetItem* coordItem = createItem( nodeItem ); + coordItem->setText( 0, tr( "COORDINATES" ) ); + QTreeWidgetItem* xItem = createItem( coordItem ); + xItem->setText( 0, "X" ); + xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* yItem = createItem( coordItem ); + yItem->setText( 0, "Y" ); + yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* zItem = createItem( coordItem ); + zItem->setText( 0, "Z" ); + zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // node connectivity + QTreeWidgetItem* nconItem = createItem( nodeItem ); + nconItem->setText( 0, tr( "CONNECTIVITY" ) ); + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "0D_ELEMENTS" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "EDGES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "FACES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "VOLUMES" ) ); + i->setText( 1, con ); + } + } + } } } } } /*! - \brief Clear mesh element information widget + \brief Internal clean-up (reset widget) */ -void SMESHGUI_TreeElemInfo::clear() +void SMESHGUI_TreeElemInfo::clearInternal() { myInfo->clear(); myInfo->repaint(); @@ -1032,11 +1270,11 @@ void SMESHGUI_TreeElemInfo::clear() /*! \brief Create new tree item. - \param parnt parent tree widget item - \param column item column to be set bold, if it is -1, bold font will be set for all columns + \param parent parent tree widget item + \param flags item flag \return new tree widget item */ -QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int column ) +QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags ) { QTreeWidgetItem* item; if ( parent ) @@ -1048,16 +1286,379 @@ QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int QFont f = item->font( 0 ); f.setBold( true ); - if ( column >= 0 && column < myInfo->columnCount() ) { - item->setFont( column, f ); + for ( int i = 0; i < myInfo->columnCount(); i++ ) { + if ( ( flags & Bold ) && ( i == 0 || flags & All ) ) + item->setFont( i, f ); + } + + item->setExpanded( true ); + return item; +} + +/*! + \class GrpComputor + \brief Mesh information computer + \internal + + The class is created for different computation operation. Currently it is used + to compute number of underlying nodes for the groups. +*/ + +/*! + \brief Contructor +*/ +GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* item, QObject* parent ) + : QObject( parent ), myItem( item ) +{ + myGroup = SMESH::SMESH_GroupBase::_narrow( grp ); +} + +/*! + \brief Compute function +*/ +void GrpComputor::compute() +{ + if ( !CORBA::is_nil( myGroup ) && myItem ) { + QTreeWidgetItem* item = myItem; + myItem = 0; + int nbNodes = myGroup->GetNumberOfNodes(); + item->treeWidget()->removeItemWidget( item, 1 ); + item->setText( 1, QString::number( nbNodes )); } - else if ( column == -1 ) { - for ( int i = 0; i < myInfo->columnCount(); i++ ) +} + +/*! + \class SMESHGUI_AddInfo + \brief The wigdet shows additional information on the mesh object. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ) +: QTreeWidget( parent ) +{ + setColumnCount( 2 ); + header()->setStretchLastSection( true ); + header()->setResizeMode( 0, QHeaderView::ResizeToContents ); + header()->hide(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_AddInfo::~SMESHGUI_AddInfo() +{ +} + +/*! + \brief Show additional information on the selected object + \param obj object being processed (mesh, sub-mesh, group, ID source) +*/ +void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +{ + myComputors.clear(); + + clear(); + + if ( CORBA::is_nil( obj ) ) return; + + _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); + if ( !sobj ) return; + + // name + QTreeWidgetItem* nameItem = createItem( 0, Bold | All ); + nameItem->setText( 0, tr( "NAME" ) ); + nameItem->setText( 1, sobj->GetName().c_str() ); + + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); + + if ( !aMesh->_is_nil() ) + meshInfo( aMesh, nameItem ); + else if ( !aSubMesh->_is_nil() ) + subMeshInfo( aSubMesh, nameItem ); + else if ( !aGroup->_is_nil() ) + groupInfo( aGroup.in(), nameItem ); +} + +/*! + \brief Create new tree item. + \param parent parent tree widget item + \param flags item flag + \return new tree widget item +*/ +QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags ) +{ + QTreeWidgetItem* item; + + if ( parent ) + item = new QTreeWidgetItem( parent ); + else + item = new QTreeWidgetItem( this ); + + //item->setFlags( item->flags() | Qt::ItemIsEditable ); + + QFont f = item->font( 0 ); + f.setBold( true ); + for ( int i = 0; i < columnCount(); i++ ) { + if ( ( flags & Bold ) && ( i == 0 || flags & All ) ) item->setFont( i, f ); } + + item->setExpanded( true ); return item; } +/*! + \brief Show mesh info + \param mesh mesh object + \param parent parent tree item +*/ +void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent ) +{ + // type + GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh(); + SALOME_MED::MedFileInfo* inf = mesh->GetMEDFileInfo(); + QTreeWidgetItem* typeItem = createItem( parent, Bold ); + typeItem->setText( 0, tr( "TYPE" ) ); + if ( !CORBA::is_nil( shape ) ) { + typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) ); + _PTR(SObject) sobj = SMESH::ObjectToSObject( shape ); + if ( sobj ) { + QTreeWidgetItem* gobjItem = createItem( typeItem ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, sobj->GetName().c_str() ); + } + } + else if ( strlen( (char*)inf->fileName ) > 0 ) { + typeItem->setText( 1, tr( "MESH_FROM_FILE" ) ); + QTreeWidgetItem* fileItem = createItem( typeItem ); + fileItem->setText( 0, tr( "FILE_NAME" ) ); + fileItem->setText( 1, (char*)inf->fileName ); + } + else { + typeItem->setText( 1, tr( "STANDALONE_MESH" ) ); + } + + // groups + SMESH::ListOfGroups_var groups = mesh->GetGroups(); + QTreeWidgetItem* itemGroups = 0; + QMap grpItems; + for ( int i = 0; i < groups->length(); i++ ) { + SMESH::SMESH_GroupBase_var grp = groups[i]; + if ( CORBA::is_nil( grp ) ) continue; + _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp ); + if ( !grpSObj ) continue; + + int grpType = grp->GetType(); + + if ( !itemGroups ) { + itemGroups = createItem( parent, Bold | All ); + itemGroups->setText( 0, tr( "GROUPS" ) ); + } + + if ( grpItems.find( grpType ) == grpItems.end() ) { + grpItems[ grpType ] = createItem( itemGroups, Bold | All ); + grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) ); + itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); + } + + // group name + QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] ); + grpNameItem->setText( 0, grpSObj->GetName().c_str() ); + + // group info + groupInfo( grp.in(), grpNameItem ); + } + + // sub-meshes + SMESH::submesh_array_var subMeshes = mesh->GetSubMeshes(); + QTreeWidgetItem* itemSubMeshes = 0; + QMap smItems; + for ( int i = 0; i < subMeshes->length(); i++ ) { + SMESH::SMESH_subMesh_var sm = subMeshes[i]; + if ( CORBA::is_nil( sm ) ) continue; + _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm ); + if ( !smSObj ) continue; + + GEOM::GEOM_Object_var gobj = sm->GetSubShape(); + if ( CORBA::is_nil(gobj ) ) continue; + + int smType = gobj->GetShapeType(); + if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND; + + if ( !itemSubMeshes ) { + itemSubMeshes = createItem( parent, Bold | All ); + itemSubMeshes->setText( 0, tr( "SUBMESHES" ) ); + } + + if ( smItems.find( smType ) == smItems.end() ) { + smItems[ smType ] = createItem( itemSubMeshes, Bold | All ); + smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) ); + itemSubMeshes->insertChild( smType, smItems[ smType ] ); + } + + // submesh name + QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] ); + smNameItem->setText( 0, smSObj->GetName().c_str() ); + + // submesh info + subMeshInfo( sm.in(), smNameItem ); + } +} + +/*! + \brief Show sub-mesh info + \param subMesh sub-mesh object + \param parent parent tree item +*/ +void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent ) +{ + bool isShort = parent->parent() != 0; + + if ( !isShort ) { + // parent mesh + _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() ); + if ( sobj ) { + QTreeWidgetItem* nameItem = createItem( parent, Bold ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, sobj->GetName().c_str() ); + } + } + + // shape + GEOM::GEOM_Object_var gobj = subMesh->GetSubShape(); + _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); + if ( sobj ) { + QTreeWidgetItem* gobjItem = createItem( parent, Bold ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, sobj->GetName().c_str() ); + } +} + +/*! + \brief Show group info + \param grp mesh group object + \param parent parent tree item +*/ +void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent ) +{ + bool isShort = parent->parent() != 0; + + SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp ); + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp ); + SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp ); + + if ( !isShort ) { + // parent mesh + _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() ); + if ( sobj ) { + QTreeWidgetItem* nameItem = createItem( parent, Bold ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, sobj->GetName().c_str() ); + } + } + + // type : group on geometry, standalone group, group on filter + QTreeWidgetItem* typeItem = createItem( parent, Bold ); + typeItem->setText( 0, tr( "TYPE" ) ); + if ( !CORBA::is_nil( aStdGroup ) ) { + typeItem->setText( 1, tr( "STANDALONE_GROUP" ) ); + } + else if ( !CORBA::is_nil( aGeomGroup ) ) { + typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) ); + GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); + _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); + if ( sobj ) { + QTreeWidgetItem* gobjItem = createItem( typeItem ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, sobj->GetName().c_str() ); + } + } + else if ( !CORBA::is_nil( aFltGroup ) ) { + typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) ); + } + + if ( !isShort ) { + // entity type + QString etype = tr( "UNKNOWN" ); + switch( grp->GetType() ) { + case SMESH::NODE: + etype = tr( "NODE" ); + break; + case SMESH::EDGE: + etype = tr( "EDGE" ); + break; + case SMESH::FACE: + etype = tr( "FACE" ); + break; + case SMESH::VOLUME: + etype = tr( "VOLUME" ); + break; + case SMESH::ELEM0D: + etype = tr( "0DELEM" ); + break; + default: + break; + } + QTreeWidgetItem* etypeItem = createItem( parent, Bold ); + etypeItem->setText( 0, tr( "ENTITY_TYPE" ) ); + etypeItem->setText( 1, etype ); + } + + // size + QTreeWidgetItem* sizeItem = createItem( parent, Bold ); + sizeItem->setText( 0, tr( "SIZE" ) ); + sizeItem->setText( 1, QString::number( grp->Size() ) ); + + // color + SALOMEDS::Color color = grp->GetColor(); + QTreeWidgetItem* colorItem = createItem( parent, Bold ); + colorItem->setText( 0, tr( "COLOR" ) ); + colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) ); + + // nb of underlying nodes + if ( grp->GetType() != SMESH::NODE) { + QTreeWidgetItem* nodesItem = createItem( parent, Bold ); + nodesItem->setText( 0, tr( "NB_NODES" ) ); + int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 ); + SMESH::SMESH_Mesh_var mesh = grp->GetMesh(); + bool meshLoaded = mesh->IsLoaded(); + bool toShowNodes = ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || grp->Size() <= nbNodesLimit ); + if ( toShowNodes && meshLoaded ) { + // already calculated and up-to-date + nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) ); + } + else { + QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this ); + setItemWidget( nodesItem, 1, btn ); + GrpComputor* comp = new GrpComputor( grp, nodesItem, this ); + connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) ); + myComputors.append( comp ); + if ( !meshLoaded ) + connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) ); + } + } +} + +/*! + * \brief Change button label of "nb underlying node" group from "Load" to "Compute" + */ +void SMESHGUI_AddInfo::changeLoadToCompute() +{ + for ( int i = 0; i < myComputors.count(); ++i ) + { + if ( QTreeWidgetItem* item = myComputors[i]->getItem() ) + { + if ( QPushButton* btn = qobject_cast( itemWidget ( item, 1 ))) + btn->setText( tr("COMPUTE")); + } + } +} + /*! \class SMESHGUI_MeshInfoDlg \brief Mesh information dialog box @@ -1092,7 +1693,7 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode ); myMode->button( NodeMode )->setChecked( true ); myID = new QLineEdit( w ); - myID->setValidator( new SMESHGUI_IdValidator( this, 1 ) ); + myID->setValidator( new SMESHGUI_IdValidator( this ) ); int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 ); mode = qMin( 1, qMax( 0, mode ) ); @@ -1112,6 +1713,13 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) myTabWidget->addTab( w, tr( "ELEM_INFO" ) ); + // additional info + + myAddInfo = new SMESHGUI_AddInfo( myTabWidget ); + myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) ); + + // buttons + QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); okBtn->setAutoDefault( true ); okBtn->setDefault( true ); @@ -1131,7 +1739,6 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) l->setMargin( MARGIN ); l->setSpacing( SPACING ); l->addWidget( myTabWidget ); - l->addStretch(); l->addLayout( btnLayout ); myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) ); @@ -1163,20 +1770,25 @@ void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); if ( !CORBA::is_nil( obj ) ) { myBaseInfo->showInfo( obj ); - + myAddInfo->showInfo( obj ); + myActor = SMESH::FindActorByEntry( IO->getEntry() ); SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); QString ID; int nb = 0; if ( myActor && selector ) { nb = myMode->checkedId() == NodeMode ? - SMESH::GetNameOfSelectedElements( selector, IO, ID ) : - SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); } - if ( nb == 1 ) { + myElemInfo->setSource( myActor ) ; + if ( nb > 0 ) { myID->setText( ID.trimmed() ); - myElemInfo->setSource( myActor ) ; - myElemInfo->showInfo( ID.toLong(), myMode->checkedId() == ElemMode ); + QSet ids; + QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); + foreach ( ID, idTxt ) + ids << ID.trimmed().toLong(); + myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); } else { myID->clear(); @@ -1229,7 +1841,7 @@ void SMESHGUI_MeshInfoDlg::updateSelection() disconnect( selMgr, 0, this, 0 ); selMgr->clearFilters(); - if ( myTabWidget->currentIndex() == BaseInfo ) { + if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) { SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( ActorSelection ); @@ -1238,24 +1850,24 @@ void SMESHGUI_MeshInfoDlg::updateSelection() if ( myMode->checkedId() == NodeMode ) { SMESH::SetPointRepresentation( true ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( NodeSelection ); + aViewWindow->SetSelectionMode( NodeSelection ); } else { SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( CellSelection ); + aViewWindow->SetSelectionMode( CellSelection ); } } - int oldID = myID->text().toLong(); + QString oldID = myID->text().trimmed(); SMESH_Actor* oldActor = myActor; myID->clear(); connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); updateInfo(); - if ( oldActor == myActor && myActor && oldID ) { - myID->setText( QString::number( oldID ) ); + if ( oldActor == myActor && myActor && !oldID.isEmpty() ) { + myID->setText( oldID ); idChanged(); } } @@ -1265,9 +1877,9 @@ void SMESHGUI_MeshInfoDlg::updateSelection() */ void SMESHGUI_MeshInfoDlg::help() { - SMESH::ShowHelpFile( myTabWidget->currentIndex() == BaseInfo ? - "mesh_infos_page.html#advanced_mesh_infos_anchor" : - "mesh_infos_page.html#mesh_element_info_anchor" ); + SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ? + "mesh_infos_page.html#advanced_mesh_infos_anchor" : + "mesh_infos_page.html#mesh_element_info_anchor" ); } /*! @@ -1287,6 +1899,7 @@ void SMESHGUI_MeshInfoDlg::updateInfo() // else { // myBaseInfo->clear(); // myElemInfo->clear(); +// myAddInfo->clear(); // } } @@ -1328,10 +1941,21 @@ void SMESHGUI_MeshInfoDlg::idChanged() if ( myActor && selector ) { Handle(SALOME_InteractiveObject) IO = myActor->getIO(); TColStd_MapOfInteger ID; - ID.Add( myID->text().toLong() ); + QSet ids; + QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts ); + foreach ( QString tid, idTxt ) { + long id = tid.trimmed().toLong(); + const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ? + myActor->GetObject()->GetMesh()->FindElement( id ) : + myActor->GetObject()->GetMesh()->FindNode( id ); + if ( e ) { + ID.Add( id ); + ids << id; + } + } selector->AddOrRemoveIndex( IO, ID, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->highlight( IO, true, true ); - myElemInfo->showInfo( myID->text().toLong(), myMode->checkedId() == ElemMode ); + myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); } }