diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl index 85ae6dc27..9d45d6e64 100644 --- a/idl/SMESH_Filter.idl +++ b/idl/SMESH_Filter.idl @@ -61,6 +61,7 @@ module SMESH FT_MultiConnection2D, FT_Length, FT_Length2D, + FT_Length3D, FT_Deflection2D, FT_NodeConnectivityNumber, FT_BelongToMeshGroup, @@ -118,7 +119,8 @@ module SMESH */ interface NumericalFunctor: Functor { - double GetValue( in long theElementId ); + double GetValue ( in long theElementId ); + boolean IsApplicable( in long theElementId ); Histogram GetHistogram ( in short nbIntervals, in boolean isLogarithmic ); Histogram GetLocalHistogram( in short nbIntervals, in boolean isLogarithmic, @@ -151,6 +153,7 @@ module SMESH typedef sequence Values; Values GetValues(); }; + interface Length3D : NumericalFunctor{}; interface Deflection2D : NumericalFunctor{}; interface MultiConnection : NumericalFunctor{}; interface MultiConnection2D : NumericalFunctor @@ -588,6 +591,7 @@ module SMESH MaxElementLength3D CreateMaxElementLength3D(); Length CreateLength(); Length2D CreateLength2D(); + Length3D CreateLength3D(); Deflection2D CreateDeflection2D(); MultiConnection CreateMultiConnection(); MultiConnection2D CreateMultiConnection2D(); diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 719cd6430..ae66e1442 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -233,7 +233,7 @@ bool NumericalFunctor::GetPoints(const int theId, return false; const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); - if ( !anElem || anElem->GetType() != this->GetType() ) + if ( !IsApplicable( anElem )) return false; return GetPoints( anElem, theRes ); @@ -292,6 +292,24 @@ double NumericalFunctor::Round( const double & aVal ) return ( myPrecision >= 0 ) ? floor( aVal * myPrecisionValue + 0.5 ) / myPrecisionValue : aVal; } +//================================================================================ +/*! + * \brief Return true if a value can be computed for a given element. + * Some NumericalFunctor's are meaningful for elements of a certain + * geometry only. + */ +//================================================================================ + +bool NumericalFunctor::IsApplicable( const SMDS_MeshElement* element ) const +{ + return element && element->GetType() == this->GetType(); +} + +bool NumericalFunctor::IsApplicable( long theElementId ) const +{ + return IsApplicable( myMesh->FindElement( theElementId )); +} + //================================================================================ /*! * \brief Return histogram of functor values @@ -901,6 +919,11 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) return 0; } +bool AspectRatio::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && !element->IsPoly() ); +} + double AspectRatio::GetBadRate( double Value, int /*nbNodes*/ ) const { // the aspect ratio is in the range [1.0,infinity] @@ -1007,6 +1030,11 @@ double AspectRatio3D::GetValue( long theId ) return aVal; } +bool AspectRatio3D::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && !element->IsPoly() ); +} + double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) { double aQuality = 0.0; @@ -1015,11 +1043,11 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) int nbNodes = P.size(); if( myCurrElement->IsQuadratic() ) { - if(nbNodes==10) nbNodes=4; // quadratic tetrahedron + if (nbNodes==10) nbNodes=4; // quadratic tetrahedron else if(nbNodes==13) nbNodes=5; // quadratic pyramid else if(nbNodes==15) nbNodes=6; // quadratic pentahedron else if(nbNodes==20) nbNodes=8; // quadratic hexahedron - else if(nbNodes==27) nbNodes=8; // quadratic hexahedron + else if(nbNodes==27) nbNodes=8; // tri-quadratic hexahedron else return aQuality; } @@ -1296,6 +1324,11 @@ SMDSAbs_ElementType AspectRatio3D::GetType() const */ //================================================================================ +bool Warping::IsApplicable( const SMDS_MeshElement* element ) const +{ + return NumericalFunctor::IsApplicable( element ) && element->NbNodes() == 4; +} + double Warping::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 4 ) @@ -1360,6 +1393,11 @@ SMDSAbs_ElementType Warping::GetType() const */ //================================================================================ +bool Taper::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && element->NbNodes() == 4 ); +} + double Taper::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 4 ) @@ -1418,6 +1456,11 @@ static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ return v1.Magnitude() < gp::Resolution() || v2.Magnitude() < gp::Resolution() ? 0. : v1.Angle( v2 ); } +bool Skew::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && element->NbNodes() <= 4 ); +} + double Skew::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 3 && P.size() != 4 ) @@ -1534,11 +1577,34 @@ SMDSAbs_ElementType Length::GetType() const //================================================================================ /* - Class : Length2D - Description : Functor for calculating minimal length of edge + Class : Length3D + Description : Functor for calculating minimal length of element edge */ //================================================================================ +Length3D::Length3D(): + Length2D ( SMDSAbs_Volume ) +{ +} + +//================================================================================ +/* + Class : Length2D + Description : Functor for calculating minimal length of element edge +*/ +//================================================================================ + +Length2D::Length2D( SMDSAbs_ElementType type ): + myType ( type ) +{ +} + +bool Length2D::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && + element->GetEntityType() != SMDSEntity_Polyhedra ); +} + double Length2D::GetValue( const TSequenceOfXYZ& P ) { double aVal = 0; @@ -1783,7 +1849,7 @@ double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const SMDSAbs_ElementType Length2D::GetType() const { - return SMDSAbs_Face; + return myType; } Length2D::Value::Value(double theLength,long thePntId1, long thePntId2): @@ -1805,84 +1871,90 @@ bool Length2D::Value::operator<(const Length2D::Value& x) const void Length2D::GetValues(TValues& theValues) { - TValues aValues; - for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) + if ( myType == SMDSAbs_Face ) { - const SMDS_MeshFace* anElem = anIter->next(); - if ( anElem->IsQuadratic() ) + for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) { - // use special nodes iterator - SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator(); - long aNodeId[4] = { 0,0,0,0 }; - gp_Pnt P[4]; + const SMDS_MeshFace* anElem = anIter->next(); + if ( anElem->IsQuadratic() ) + { + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator(); + long aNodeId[4] = { 0,0,0,0 }; + gp_Pnt P[4]; - double aLength = 0; - if ( anIter->more() ) - { - const SMDS_MeshNode* aNode = anIter->next(); - P[0] = P[1] = SMESH_NodeXYZ( aNode ); - aNodeId[0] = aNodeId[1] = aNode->GetID(); - aLength = 0; - } - for ( ; anIter->more(); ) - { - const SMDS_MeshNode* N1 = anIter->next(); - P[2] = SMESH_NodeXYZ( N1 ); - aNodeId[2] = N1->GetID(); - aLength = P[1].Distance(P[2]); - if(!anIter->more()) break; - const SMDS_MeshNode* N2 = anIter->next(); - P[3] = SMESH_NodeXYZ( N2 ); - aNodeId[3] = N2->GetID(); - aLength += P[2].Distance(P[3]); + double aLength = 0; + if ( anIter->more() ) + { + const SMDS_MeshNode* aNode = anIter->next(); + P[0] = P[1] = SMESH_NodeXYZ( aNode ); + aNodeId[0] = aNodeId[1] = aNode->GetID(); + aLength = 0; + } + for ( ; anIter->more(); ) + { + const SMDS_MeshNode* N1 = anIter->next(); + P[2] = SMESH_NodeXYZ( N1 ); + aNodeId[2] = N1->GetID(); + aLength = P[1].Distance(P[2]); + if(!anIter->more()) break; + const SMDS_MeshNode* N2 = anIter->next(); + P[3] = SMESH_NodeXYZ( N2 ); + aNodeId[3] = N2->GetID(); + aLength += P[2].Distance(P[3]); + Value aValue1(aLength,aNodeId[1],aNodeId[2]); + Value aValue2(aLength,aNodeId[2],aNodeId[3]); + P[1] = P[3]; + aNodeId[1] = aNodeId[3]; + theValues.insert(aValue1); + theValues.insert(aValue2); + } + aLength += P[2].Distance(P[0]); Value aValue1(aLength,aNodeId[1],aNodeId[2]); - Value aValue2(aLength,aNodeId[2],aNodeId[3]); - P[1] = P[3]; - aNodeId[1] = aNodeId[3]; + Value aValue2(aLength,aNodeId[2],aNodeId[0]); theValues.insert(aValue1); theValues.insert(aValue2); } - aLength += P[2].Distance(P[0]); - Value aValue1(aLength,aNodeId[1],aNodeId[2]); - Value aValue2(aLength,aNodeId[2],aNodeId[0]); - theValues.insert(aValue1); - theValues.insert(aValue2); - } - else { - SMDS_NodeIteratorPtr aNodesIter = anElem->nodeIterator(); - long aNodeId[2] = {0,0}; - gp_Pnt P[3]; + else { + SMDS_NodeIteratorPtr aNodesIter = anElem->nodeIterator(); + long aNodeId[2] = {0,0}; + gp_Pnt P[3]; - double aLength; - const SMDS_MeshElement* aNode; - if ( aNodesIter->more()) - { - aNode = aNodesIter->next(); - P[0] = P[1] = SMESH_NodeXYZ( aNode ); - aNodeId[0] = aNodeId[1] = aNode->GetID(); - aLength = 0; - } - for( ; aNodesIter->more(); ) - { - aNode = aNodesIter->next(); - long anId = aNode->GetID(); + double aLength; + const SMDS_MeshElement* aNode; + if ( aNodesIter->more()) + { + aNode = aNodesIter->next(); + P[0] = P[1] = SMESH_NodeXYZ( aNode ); + aNodeId[0] = aNodeId[1] = aNode->GetID(); + aLength = 0; + } + for( ; aNodesIter->more(); ) + { + aNode = aNodesIter->next(); + long anId = aNode->GetID(); - P[2] = SMESH_NodeXYZ( aNode ); + P[2] = SMESH_NodeXYZ( aNode ); - aLength = P[1].Distance(P[2]); + aLength = P[1].Distance(P[2]); - Value aValue(aLength,aNodeId[1],anId); - aNodeId[1] = anId; - P[1] = P[2]; + Value aValue(aLength,aNodeId[1],anId); + aNodeId[1] = anId; + P[1] = P[2]; + theValues.insert(aValue); + } + + aLength = P[0].Distance(P[1]); + + Value aValue(aLength,aNodeId[0],aNodeId[1]); theValues.insert(aValue); } - - aLength = P[0].Distance(P[1]); - - Value aValue(aLength,aNodeId[0],aNodeId[1]); - theValues.insert(aValue); } } + else + { + // not implemented + } } //================================================================================ diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 4f717d3aa..359ffe1f7 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -136,6 +136,8 @@ namespace SMESH{ const std::vector& elements, const double* minmax=0, const bool isLogarithmic = false); + bool IsApplicable( long theElementId ) const; + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; virtual SMDSAbs_ElementType GetType() const = 0; virtual double GetBadRate( double Value, int nbNodes ) const = 0; long GetPrecision() const; @@ -176,8 +178,8 @@ namespace SMESH{ virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; }; - - + + /* Class : MaxElementLength3D Description : Functor calculating maximum length of 3D element @@ -212,6 +214,7 @@ namespace SMESH{ virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; }; @@ -225,6 +228,7 @@ namespace SMESH{ virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; }; @@ -237,7 +241,8 @@ namespace SMESH{ virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; - + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; + private: double ComputeA( const gp_XYZ&, const gp_XYZ&, const gp_XYZ&, const gp_XYZ& ) const; }; @@ -252,6 +257,7 @@ namespace SMESH{ virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; }; /* @@ -263,6 +269,7 @@ namespace SMESH{ virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; }; @@ -291,10 +298,12 @@ namespace SMESH{ /* Class : Length2D - Description : Functor for calculating minimal length of edge + Description : Functor for calculating minimal length of edges of element */ class SMESHCONTROLS_EXPORT Length2D: public virtual NumericalFunctor{ public: + Length2D( SMDSAbs_ElementType type = SMDSAbs_Face ); + virtual bool IsApplicable( const SMDS_MeshElement* element ) const; virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; @@ -306,9 +315,22 @@ namespace SMESH{ }; typedef std::set TValues; void GetValues(TValues& theValues); + + private: + SMDSAbs_ElementType myType; }; typedef boost::shared_ptr Length2DPtr; + /* + Class : Length2D + Description : Functor for calculating minimal length of edges of 3D element + */ + class SMESHCONTROLS_EXPORT Length3D: public virtual Length2D { + public: + Length3D(); + }; + typedef boost::shared_ptr Length3DPtr; + /* Class : Deflection2D Description : Functor for calculating distance between a face and geometry diff --git a/src/SMESHGUI/CMakeLists.txt b/src/SMESHGUI/CMakeLists.txt index 497d41954..1b8268651 100644 --- a/src/SMESHGUI/CMakeLists.txt +++ b/src/SMESHGUI/CMakeLists.txt @@ -165,6 +165,7 @@ SET(_other_HEADERS SMESHGUI_MeshEditPreview.h SMESHGUI_IdValidator.h SMESHGUI_FileValidator.h + SMESHGUI_SelectionProxy.h SMESH_SMESHGUI.hxx ) @@ -189,6 +190,7 @@ SET(_other_SOURCES SMESHGUI_GroupDlg.cxx SMESHGUI_RemoveNodesDlg.cxx SMESHGUI_RemoveElementsDlg.cxx + SMESHGUI_SelectionProxy.cxx SMESHGUI_MeshInfo.cxx SMESHGUI_Measurements.cxx SMESHGUI_Preferences_ScalarBarDlg.cxx diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index c153396ac..29505d1af 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -1571,6 +1571,7 @@ void SMESHGUI_FilterTable::updateAdditionalWidget() aCriterion == SMESH::FT_MaxElementLength3D || aCriterion == SMESH::FT_Length || aCriterion == SMESH::FT_Length2D || + aCriterion == SMESH::FT_Length3D || aCriterion == SMESH::FT_Deflection2D || aCriterion == SMESH::FT_BallDiameter ); @@ -1618,6 +1619,7 @@ const char* SMESHGUI_FilterTable::getPrecision( const int aType ) retval = "len_tol_precision"; break; case SMESH::FT_Length: case SMESH::FT_Length2D: + case SMESH::FT_Length3D: case SMESH::FT_Deflection2D: case SMESH::FT_MaxElementLength2D: case SMESH::FT_MaxElementLength3D: @@ -1830,6 +1832,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con case SMESH::FT_Length: case SMESH::FT_Length2D: + case SMESH::FT_Length3D: case SMESH::FT_Deflection2D: anIsDoubleCriterion = true; break; case SMESH::FT_BelongToMeshGroup: break; @@ -2270,6 +2273,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME"); aCriteria[ SMESH::FT_BareBorderVolume ] = tr("BARE_BORDER_VOLUME"); aCriteria[ SMESH::FT_OverConstrainedVolume] = tr("OVER_CONSTRAINED_VOLUME"); + aCriteria[ SMESH::FT_Length3D ] = tr("LENGTH3D"); aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D"); aCriteria[ SMESH::FT_MaxElementLength3D ] = tr("MAX_ELEMENT_LENGTH_3D"); aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 9c1fb8810..bcbd1b868 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -19,18 +19,11 @@ // // 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) #include "SMESHGUI_MeshInfo.h" -#include "SMDSAbs_ElementType.hxx" -#include "SMDS_BallElement.hxx" -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" #include "SMDS_Mesh.hxx" -#include "SMDS_VolumeTool.hxx" -#include "SMESHDS_Mesh.hxx" +#include "SMESH_Actor.h" #include "SMESHGUI.h" #include "SMESHGUI_FilterUtils.h" #include "SMESHGUI_IdPreview.h" @@ -38,21 +31,20 @@ #include "SMESHGUI_SpinBox.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" -#include "SMESH_Actor.h" -#include #include #include #include #include #include +#include #include -#include #include #include #include +#include #include #include #include @@ -63,67 +55,406 @@ #include #include #include -#include #include -#include +#include +#include #include #include +#include +#include +#include #include -#include "utilities.h" +//////////////////////////////////////////////////////////////////////////////// +/// \class Field +/// \brief Field widget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// -#include -#include CORBA_SERVER_HEADER(GEOM_Gen) +class Field : public QLabel +{ +public: + Field( QWidget*, const QString& = QString() ); + bool event( QEvent* ); +}; -namespace { +/*! + \brief Constructor. + \param parent Parent widget. + \param name Field name. Defauls to null string. +*/ +Field::Field( QWidget* parent, const QString& name ): QLabel( parent ) +{ + setFrameStyle( QLabel::StyledPanel | QLabel::Sunken ); + setAlignment( Qt::AlignCenter ); + setAutoFillBackground( true ); + QPalette pal = palette(); + QColor base = QApplication::palette().color( QPalette::Active, QPalette::Base ); + pal.setColor( QPalette::Window, base ); + setPalette( pal ); + setMinimumWidth( 60 ); + if ( !name.isEmpty() ) + setObjectName( name ); +} - const int SPACING = 6; - const int MARGIN = 9; - const int MAXITEMS = 10; - const int GROUPS_ID = 100; - const int SUBMESHES_ID = 200; - const int SPACING_INFO = 2; +/*! + \brief Event handler. Redefined from QLabel. +*/ +bool Field::event( QEvent* e ) +{ + if ( e->type() == QEvent::DynamicPropertyChange ) + { + QDynamicPropertyChangeEvent* ce = (QDynamicPropertyChangeEvent*)e; + if ( ce->propertyName() == "value" && property( "value" ).isValid() ) + { + setText( QString::number( property( "value" ).toInt() ) ); + setProperty( "value", QVariant() ); + return true; + } + } + return QLabel::event( e ); +} - const char* id_preview_resource = "id_preview_resource"; +//////////////////////////////////////////////////////////////////////////////// +/// \class TreeItemCreator +/// \brief Generic tree item creator. +/// \internal +//////////////////////////////////////////////////////////////////////////////// - enum InfoRole { +class TreeItemCreator +{ +public: + TreeItemCreator() {} + virtual ~TreeItemCreator() {} + virtual QTreeWidgetItem* createItem( QTreeWidgetItem*, int ) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// +// General purpose services. +//////////////////////////////////////////////////////////////////////////////// + +namespace +{ + const int SPACING = 6; + const int MARGIN = 9; + + enum + { + Bold = 0x01, + Italic = 0x02, + AllColumns = 0x04, + Expanded = 0x08, + Editable = 0x10 + }; + + enum + { + GroupsId = 100, + SubMeshesId + }; + + enum + { TypeRole = Qt::UserRole + 10, IdRole, }; - enum InfoType { + enum + { NodeConnectivity = 100, ElemConnectivity, }; -} // namesapce + + /*! + \brief Get item's depth in the tree. + \param item Tree widget item. + \return Item's depth in the tree widget (top-level item has zero depth). + \internal + */ + int itemDepth( QTreeWidgetItem* item ) + { + QList parents; + parents << item; + while ( parents.last()->parent() ) + parents << parents.last()->parent(); + return parents.size()-1; + } + + /*! + \brief Get chunk size. + \return Chunk size. + \internal + */ + int blockSize() + { + return 10; + } + + /*! + \brief Get spacer. + \return Spacer string. + \internal + */ + QString spacing() + { + static int size = 1; + static QChar spacer = ' '; + return QString( size, spacer ); + } + + /*! + \brief Get indent. + \param length Indent size. Defaults to 1. + \return Indentation string. + \internal + */ + QString indent( int length = 1 ) + { + static int size = 4; + static QChar spacer = ' '; + return QString( size * length, spacer ); + } + + /*! + \brief Get indent. + \param spacer Spacer. + \param length Indent size. Defaults to 1. + \return Indentation string. + \internal + */ + QString indent( const QString& spacer, uint length = 1 ) + { + QString result; + while( length-- > 0 ) + result += spacer; + return result; + } + + /*! + \brief Get group separator. + \param length Length of ruler (number of symbols). Defaults to 80. + \return Ruler string. + \internal + */ + QString ruler( int length = 80 ) + { + static QChar ruler = '-'; + return QString( length, ruler ); + } + + /*! + \brief Get text value from label. + \param w Widget (QLabel). + \return Value string. + \internal + */ + QString widgetValue( QWidget* w ) + { + QString v; + if ( qobject_cast( w ) ) + v = qobject_cast( w )->text(); + return v; + } + + /*! + \brief Get font for given options. + \param font Initial font. + \param options Font attributes. + \return Font. + */ + QFont fontFromOptions( const QFont& font, int options ) + { + QFont f = font; + f.setBold( options & Bold ); + f.setItalic( options & Italic ); + return f; + } + + /*! + \brief Set font attributes to given widget. + \param w Widget. + \param options Font attributes. + */ + void setFontAttributes( QWidget* w, int options ) + { + if ( w ) + w->setFont( fontFromOptions( w->font(), options ) ); + } + + /*! + \brief Set attributes to given tree item. + \param item Tree widget item. + \param options Item attributes. + */ + void setTreeItemAttributes( QTreeWidgetItem* item, int options ) + { + if ( item && item->treeWidget() ) + { + for ( int i = 0; i < item->treeWidget()->columnCount(); i++ ) + { + if ( i == 0 || options & AllColumns ) + item->setFont( i, fontFromOptions( item->font( 0 ), options) ); + } + } + if ( options & Expanded ) + item->setExpanded( true ); + if ( options & Editable ) + item->setFlags( item->flags() | Qt::ItemIsEditable ); + } + + /*! + \brief Create label. + \param parent Parent widget. + \param options Label options. Defaults to 0 (none). + \return New label. + */ + QLabel* createLabel( QWidget* parent, int options = 0 ) + { + QLabel* lab = new QLabel( parent ); + setFontAttributes( lab, options ); + return lab; + } + + /*! + \brief Create label. + \param text Label text. + \param parent Parent widget. + \param options Label options. Defaults to 0 (none). + \return New label. + */ + QLabel* createLabel( const QString& text, QWidget* parent, int options = 0 ) + { + QLabel* lab = createLabel( parent, options ); + lab->setText( text ); + return lab; + } + + /*! + \brief Create information field. + \param parent Parent widget. + \param name Field's object. Default to null string. + \return New field. + */ + QLabel* createField( QWidget* parent, const QString& name = QString() ) + { + return new Field( parent, name ); + } + + /*! + \brief Create information field. + \param parent Parent widget. + \param options Label options. + \param name Field's object. Default to null string. + \return New field. + */ + QLabel* createField( QWidget* parent, int options, const QString& name = QString() ) + { + QLabel* field = createField( parent, name ); + setFontAttributes( field, options ); + return field; + } + + /*! + \brief Create ruler. + \param parent Parent widget. + \param orientation Ruler orientation. Defaults to horizontal. + \return New ruler. + */ + QWidget* createSeparator( QWidget* parent, Qt::Orientation orientation = Qt::Horizontal ) + { + QFrame* line = new QFrame( parent ); + line->setFrameShape( orientation == Qt::Horizontal ? QFrame::HLine : QFrame::HLine ); + line->setFrameShadow( QFrame::Sunken ); + return line; + } + + /*! + \brief Decorate text as bold. + \param text Initial text. + \return Decorated text. + */ + QString bold( const QString& text ) + { + return QString("%1").arg( text ); + } + + /*! + \brief Format connectivity data to string representation. + \param connectivity Connectivity map. + \param type Element type or face index if negative + \return Stringifed representation of the connectivity. + */ + QString formatConnectivity( SMESH::Connectivity connectivity, int type ) + { + QStringList str; + QString result; + bool isNodal = ( type == SMDSAbs_Node || type < 0 ); + type = qAbs( type ); + if ( connectivity.contains( type )) + { + QList elements = connectivity[ type ]; + if ( !isNodal ) // order of nodes is important + qSort( elements ); + foreach( int id, elements ) + str << QString::number( id ); + + // wrap IDs into an html link, to be treated by QTextBrowser used by SMESHGUI_SimpleElemInfo + QString s = str.join( " " ); + result = ( "" + // path + s + "" ); // anchor text + } + return result; + } +} // end of anonymous namespace + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_Info +/// \brief Base widget for all information panes. +//////////////////////////////////////////////////////////////////////////////// /*! - \class ExtraWidget - \internal + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ +SMESHGUI_Info::SMESHGUI_Info( QWidget* parent ): QWidget( parent ) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class ExtraWidget +/// \brief Auxiliary widget to browse between chunks of information. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + class ExtraWidget : public QWidget { public: ExtraWidget( QWidget*, bool = false ); - ~ExtraWidget(); - - void updateControls( int, int, int = MAXITEMS ); + void updateControls( int, int ); public: - QLabel* current; + QLabel* current; QPushButton* prev; QPushButton* next; - bool brief; + bool brief; }; -ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b ) +/* + \brief Constructor. + \param parent Parent widget. + \param briefSummary Show summary in brief format. Defaults to \c false. +*/ +ExtraWidget::ExtraWidget( QWidget* parent, bool briefSummary ): QWidget( parent ), brief( briefSummary ) { current = new QLabel( this ); current->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); - prev = new QPushButton( tr( "<<" ), this ); - next = new QPushButton( tr( ">>" ), this ); + prev = new QPushButton( "<<", this ); + next = new QPushButton( ">>", this ); QHBoxLayout* hbl = new QHBoxLayout( this ); - hbl->setContentsMargins( 0, SPACING, 0, 0 ); + hbl->setMargin( 0 ); hbl->setSpacing( SPACING ); hbl->addStretch(); hbl->addWidget( current ); @@ -131,884 +462,1047 @@ ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( hbl->addWidget( next ); } -ExtraWidget::~ExtraWidget() -{ -} - -void ExtraWidget::updateControls( int total, int index, int blockSize ) -{ - setVisible( total > blockSize ); - QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" ); - current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total )).arg( total )); - prev->setEnabled( index > 0 ); - next->setEnabled( (index+1)*blockSize < total ); -} - -/*! - \class DumpFileDlg - \brief Customization of standard "Save file" dialog box for dump info operation - \internal +/* + \brief Update controls. + \param total Total number of items. + \param index Current index. */ +void ExtraWidget::updateControls( int total, int index ) +{ + setVisible( total > blockSize() ); + QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" ); + current->setText( format.arg( index*blockSize()+1 ).arg( qMin( index*blockSize()+blockSize(), total ) ).arg( total ) ); + prev->setEnabled( index > 0 ); + next->setEnabled( (index+1)*blockSize() < total ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class DumpFileDlg +/// \brief Standard Save File dialog box, customized for dump info operation. +/// \internal +//////////////////////////////////////////////////////////////////////////////// class DumpFileDlg : public SUIT_FileDlg { + QMap myControls; public: - DumpFileDlg( QWidget* parent ); - - QCheckBox* myBaseChk; - QCheckBox* myElemChk; - QCheckBox* myAddChk; - QCheckBox* myCtrlChk; + DumpFileDlg( QWidget*, bool = true ); + bool isChecked( int ) const; + void setChecked( int, bool ); }; /*! - \brief Constructor + \brief Constructor. + \param parent Parent widget. + \param showControls Show additional controls. Defaults to \c true. \internal */ -DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true ) +DumpFileDlg::DumpFileDlg( QWidget* parent, bool showControls ): SUIT_FileDlg( parent, false, true, true ) { - QGridLayout* grid = ::qobject_cast( layout() ); - if ( grid ) { + if ( showControls ) + { QWidget* hB = new QWidget( this ); - myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB ); - myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB ); - myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB ); - myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::BaseInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::ElemInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::AddInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::CtrlInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB ); QGridLayout* layout = new QGridLayout( hB ); - layout->addWidget( myBaseChk, 0, 0 ); - layout->addWidget( myElemChk, 0, 1 ); - layout->addWidget( myAddChk, 1, 0 ); - layout->addWidget( myCtrlChk, 1, 1 ); + layout->setMargin( 0 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::BaseInfo], 0, 0 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::ElemInfo], 0, 1 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::AddInfo], 1, 0 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::CtrlInfo], 1, 1 ); - QPushButton* pb = new QPushButton( this ); - - int row = grid->rowCount(); - grid->addWidget( new QLabel( "", this ), row, 0 ); - grid->addWidget( hB, row, 1, 1, 3 ); - grid->addWidget( pb, row, 5 ); - - pb->hide(); + addWidgets( 0, hB, 0 ); } } /*! - \brief Get depth of the tree item + \brief Get control's value. + \param option Control identifier. + \return Control value. \internal - \param theItem tree widget item - \return item's depth in tree widget (where top-level items have zero depth) */ -static int itemDepth( QTreeWidgetItem* item ) +bool DumpFileDlg::isChecked( int option ) const { - int d = 0; - QTreeWidgetItem* p = item->parent(); - while ( p ) { - d++; - p = p->parent(); - } - return d; + return myControls.contains( option ) ? myControls[option]->isChecked() : false; } /*! - \class SMESHGUI_MeshInfo - \brief Base mesh information widget - - Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source. + \brief Set control's initial value. + \param option Control identifier. + \param value Control value. + \internal */ +void DumpFileDlg::setChecked( int option, bool value ) +{ + if ( myControls.contains( option ) ) + myControls[option]->setChecked( value ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_BaseInfo +/// \brief Show basic information on selected object. +/// +/// Displays the base information about selected object: mesh, sub-mesh, group +/// or arbitrary ID source. +/// \todo Hide unnecessary widgets (e.g. for mesh group). +//////////////////////////////////////////////////////////////////////////////// /*! \brief Constructor. - \param parent parent widget + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) - : QFrame( parent ), myWidgets( iElementsEnd ) +SMESHGUI_BaseInfo::SMESHGUI_BaseInfo( QWidget* parent ): SMESHGUI_Info( parent ) { - setFrameStyle( StyledPanel | Sunken ); - QGridLayout* l = new QGridLayout( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); - int index = 0; + // object info + // - name + addWidget( createLabel( tr( "NAME_LAB" ), this, Bold ), iName, iLabel ); + addWidget( createField( this, "meshName" ), iName, iSingle, 4 )->setMinimumWidth( 150 ); + // - type + addWidget( createLabel( tr( "OBJECT_LAB" ), this, Bold ), iObject, iLabel ); + addWidget( createField( this, "meshType" ), iObject, iSingle, 4 )->setMinimumWidth( 150 ); + // - --- (separator) + addWidget( createSeparator( this ), iObjectEnd, iLabel, 5 ); - // object - QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); - QLabel* aName = createField(); - aName->setObjectName("meshName"); - aName->setMinimumWidth( 150 ); - QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this ); - QLabel* aObj = createField(); - aObj->setObjectName("meshType"); - aObj->setMinimumWidth( 150 ); - myWidgets[ index++ ] << aNameLab << aName; - myWidgets[ index++ ] << aObjLab << aObj; + // node info + // - info + addWidget( createLabel( tr( "NODES_LAB" ), this, Bold ), iNodes, iLabel ); + addWidget( createField( this, "nbNodes" ), iNodes, iTotal ); + // - --- (separator) + addWidget( createSeparator( this ), iNodesEnd, iLabel, 5 ); - // nodes - QWidget* aNodesLine = createLine(); - QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this ); - QLabel* aNodes = createField(); - aNodes->setObjectName("nbNodes"); - myWidgets[ index++ ] << aNodesLine; - myWidgets[ index++ ] << aNodesLab << aNodes; + // element info + // - title + addWidget( createLabel( tr( "ELEMENTS_LAB" ), this, Bold ), iElementsTitle, iLabel ); + addWidget( createLabel( tr( "TOTAL_LAB" ), this, Italic ), iElementsTitle, iTotal ); + addWidget( createLabel( tr( "LINEAR_LAB" ), this, Italic ), iElementsTitle, iLinear ); + addWidget( createLabel( tr( "QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iQuadratic ); + addWidget( createLabel( tr( "BI_QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iBiQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), iElementsTitleEnd, iTotal, 4 ); + // - summary + addWidget( createField( this, "totalNbElems" ), iElementsTotal, iTotal ); + addWidget( createField( this, "totalNbLinearElems" ), iElementsTotal, iLinear ); + addWidget( createField( this, "totalNbQuadraticElems" ), iElementsTotal, iQuadratic ); + addWidget( createField( this, "totalNbBiQuadraticElems" ), iElementsTotal, iBiQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), iElementsTotalEnd, iTotal, 4 ); + // - 0D elements info + addWidget( createLabel( tr( "0D_LAB" ), this, Bold | Italic ), i0D, iLabel ); + addWidget( createField( this, "nb0D" ), i0D, iTotal ); + // - --- (separator) + addWidget( createSeparator( this ), i0DEnd, iTotal, 4 ); + // - balls info + addWidget( createLabel( tr( "BALL_LAB" ), this, Bold | Italic ), iBalls, iLabel ); + addWidget( createField( this, "nbBall" ), iBalls, iTotal ); + // - --- (separator) + addWidget( createSeparator( this ), iBallsEnd, iTotal, 4 ); + // - 1D elements info + addWidget( createLabel( tr( "1D_LAB" ), this, Bold | Italic ), i1D, iLabel ); + addWidget( createField( this, "nb1D" ), i1D, iTotal ); + addWidget( createField( this, "nbLinear1D" ), i1D, iLinear ); + addWidget( createField( this, "nbQuadratic1D" ), i1D, iQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), i1DEnd, iTotal, 4 ); + // - 2D elements info + // --+ summary + addWidget( createLabel( tr( "2D_LAB" ), this, Bold | Italic ), i2D, iLabel ); + addWidget( createField( this, "nb2D" ), i2D, iTotal ); + addWidget( createField( this, "nbLinear2D" ), i2D, iLinear ); + addWidget( createField( this, "nbQuadratic2D" ), i2D, iQuadratic ); + addWidget( createField( this, "nbBiQuadratic2D" ), i2D, iBiQuadratic ); + // --+ triangles + addWidget( createLabel( tr( "TRIANGLES_LAB" ), this, Italic ), i2DTriangles, iLabel ); + addWidget( createField( this, Italic, "nbTriangle" ), i2DTriangles, iTotal ); + addWidget( createField( this, Italic, "nbLinearTriangle" ), i2DTriangles, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticTriangle" ), i2DTriangles, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticTriangle" ), i2DTriangles, iBiQuadratic ); + // --+ quadrangles + addWidget( createLabel( tr( "QUADRANGLES_LAB" ), this, Italic ), i2DQuadrangles, iLabel ); + addWidget( createField( this, Italic, "nbQuadrangle" ), i2DQuadrangles, iTotal ); + addWidget( createField( this, Italic, "nbLinearQuadrangle" ), i2DQuadrangles, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticQuadrangle" ), i2DQuadrangles, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticQuadrangle" ), i2DQuadrangles, iBiQuadratic ); + // --+ polygons + addWidget( createLabel( tr( "POLYGONS_LAB" ), this, Italic ), i2DPolygons, iLabel ); + addWidget( createField( this, Italic, "nbPolygon" ), i2DPolygons, iTotal ); + addWidget( createField( this, Italic, "nbLinearPolygon" ), i2DPolygons, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticPolygon" ), i2DPolygons, iQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), i2DEnd, iTotal, 4 ); + // - 3D elements info + // --+ summary + addWidget( createLabel( tr( "3D_LAB" ), this, Bold | Italic ), i3D, iLabel ); + addWidget( createField( this, "nb3D" ), i3D, iTotal ); + addWidget( createField( this, "nbLinear3D" ), i3D, iLinear ); + addWidget( createField( this, "nbQuadratic3D" ), i3D, iQuadratic ); + addWidget( createField( this, "nbBiQuadratic3D" ), i3D, iBiQuadratic ); + // --+ tetras + addWidget( createLabel( tr( "TETRAHEDRONS_LAB" ), this, Italic ), i3DTetrahedrons, iLabel ); + addWidget( createField( this, Italic, "nbTetrahedron" ), i3DTetrahedrons, iTotal ); + addWidget( createField( this, Italic, "nbLinearTetrahedron" ), i3DTetrahedrons, iLinear ); + addWidget( createField( this, Italic, "nbQudraticTetrahedron" ), i3DTetrahedrons, iQuadratic ); + // --+ hexas + addWidget( createLabel( tr( "HEXAHEDONRS_LAB" ), this, Italic ), i3DHexahedrons, iLabel ); + addWidget( createField( this, Italic, "nbHexahedron" ), i3DHexahedrons, iTotal ); + addWidget( createField( this, Italic, "nbLinearHexahedron" ), i3DHexahedrons, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticHexahedron" ), i3DHexahedrons, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticHexahedron" ), i3DHexahedrons, iBiQuadratic ); + // --+ pyramids + addWidget( createLabel( tr( "PYRAMIDS_LAB" ), this, Italic ), i3DPyramids, iLabel ); + addWidget( createField( this, Italic, "nbPyramid" ), i3DPyramids, iTotal ); + addWidget( createField( this, Italic, "nbLinearPyramid" ), i3DPyramids, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticPyramid" ), i3DPyramids, iQuadratic ); + // --+ prisms + addWidget( createLabel( tr( "PRISMS_LAB" ), this, Italic ), i3DPrisms, iLabel ); + addWidget( createField( this, Italic, "nbPrism" ), i3DPrisms, iTotal ); + addWidget( createField( this, Italic, "nbLinearPrism" ), i3DPrisms, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticPrism" ), i3DPrisms, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticPrism" ), i3DPrisms, iBiQuadratic ); + // --+ hexagonal prisms + addWidget( createLabel( tr( "HEX_PRISMS_LAB" ), this, Italic ), i3DHexaPrisms, iLabel ); + addWidget( createField( this, Italic, "nbHexagonalPrism" ), i3DHexaPrisms, iTotal ); + // --+ polyhedrons + addWidget( createLabel( tr( "POLYHEDRONS_LAB" ), this, Italic ), i3DPolyhedrons, iLabel ); + addWidget( createField( this, Italic, "nbPolyhedron" ), i3DPolyhedrons, iTotal ); - // elements - QWidget* aElemLine = createLine(); - QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this ); - QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this ); - QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this ); - QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this ); - QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this ); - myWidgets[ index++ ] << aElemLine; - myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad; + // load button + QPushButton* loadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this ); + loadBtn->setAutoDefault( true ); + connect( loadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) ); + addWidget( loadBtn, iEnd, iSingle, 4 ); - // ... Number elements - QWidget* aNbLine = createLine(); - QLabel* aNbTotal = createField(); - aNbTotal->setObjectName("totalNbElems"); - QLabel* aNbLin = createField(); - aNbLin->setObjectName("totalNbLinearElems"); - QLabel* aNbQuad = createField(); - aNbQuad->setObjectName("totalNbQuadraticElems"); - QLabel* aNbBiQuad = createField(); - aNbBiQuad->setObjectName("totalNbBiQuadraticElems"); - myWidgets[ index++ ] << aNbLine; - myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad; - - // ... 0D elements - QWidget* a0DLine = createLine(); - QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this ); - QLabel* a0DTotal = createField(); - a0DTotal->setObjectName("nb0D"); - - myWidgets[ index++ ] << a0DLine; - myWidgets[ index++ ] << a0DLab << a0DTotal; - - // ... Ball elements - QWidget* aBallLine = createLine(); - QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this ); - QLabel* aBallTotal = createField(); - aBallTotal->setObjectName("nbBall"); - myWidgets[ index++ ] << aBallLine; - myWidgets[ index++ ] << aBallLab << aBallTotal; - - // ... 1D elements - QWidget* a1DLine = createLine(); - QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this ); - QLabel* a1DTotal = createField(); - a1DTotal->setObjectName("nb1D"); - QLabel* a1DLin = createField(); - a1DLin->setObjectName("nbLinear1D"); - QLabel* a1DQuad = createField(); - a1DQuad->setObjectName("nbQuadratic1D"); - myWidgets[ index++ ] << a1DLine; - myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad; - - // ... 2D elements - QWidget* a2DLine = createLine(); - QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this ); - QLabel* a2DTotal = createField(); - a2DTotal->setObjectName("nb2D"); - QLabel* a2DLin = createField(); - a2DLin->setObjectName("nbLinear2D"); - QLabel* a2DQuad = createField(); - a2DQuad->setObjectName("nbQuadratic2D"); - QLabel* a2DBiQuad = createField(); - a2DBiQuad->setObjectName("nbBiQuadratic2D"); - QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this ); - QLabel* a2DTriTotal = createField(); - a2DTriTotal->setObjectName("nbTriangle"); - QLabel* a2DTriLin = createField(); - a2DTriLin->setObjectName("nbLinearTriangle"); - QLabel* a2DTriQuad = createField(); - a2DTriQuad->setObjectName("nbQuadraticTriangle"); - QLabel* a2DTriBiQuad = createField(); - a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle"); - QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this ); - QLabel* a2DQuaTotal = createField(); - a2DQuaTotal->setObjectName("nbQuadrangle"); - QLabel* a2DQuaLin = createField(); - a2DQuaLin->setObjectName("nbLinearQuadrangle"); - QLabel* a2DQuaQuad = createField(); - a2DQuaQuad->setObjectName("nbQuadraticQuadrangle"); - QLabel* a2DQuaBiQuad = createField(); - a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle"); - QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this ); - QLabel* a2DPolTotal = createField(); - a2DPolTotal->setObjectName("nbPolygon"); - QLabel* a2DPolLin = createField(); - a2DPolLin->setObjectName("nbLinearPolygon"); - QLabel* a2DPolQuad = createField(); - a2DPolQuad->setObjectName("nbQuadraticPolygon"); - myWidgets[ index++ ] << a2DLine; - myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad; - myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad; - myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad; - myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad; - - // ... 3D elements - QWidget* a3DLine = createLine(); - QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this ); - QLabel* a3DTotal = createField(); - a3DTotal->setObjectName("nb3D"); - QLabel* a3DLin = createField(); - a3DLin->setObjectName("nbLinear3D"); - QLabel* a3DQuad = createField(); - a3DQuad->setObjectName("nbQuadratic3D"); - QLabel* a3DBiQuad = createField(); - a3DBiQuad->setObjectName("nbBiQuadratic3D"); - QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this ); - QLabel* a3DTetTotal = createField(); - a3DTetTotal->setObjectName("nbTetrahedron"); - QLabel* a3DTetLin = createField(); - a3DTetLin->setObjectName("nbLinearTetrahedron"); - QLabel* a3DTetQuad = createField(); - a3DTetQuad->setObjectName("nbQudraticTetrahedron"); - QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this ); - QLabel* a3DHexTotal = createField(); - a3DHexTotal->setObjectName("nbHexahedron"); - QLabel* a3DHexLin = createField(); - a3DHexLin->setObjectName("nbLinearHexahedron"); - QLabel* a3DHexQuad = createField(); - a3DHexQuad->setObjectName("nbQuadraticHexahedron"); - QLabel* a3DHexBiQuad = createField(); - a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron"); - QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this ); - QLabel* a3DPyrTotal = createField(); - a3DPyrTotal->setObjectName("nbPyramid"); - QLabel* a3DPyrLin = createField(); - a3DPyrLin->setObjectName("nbLinearPyramid"); - QLabel* a3DPyrQuad = createField(); - a3DPyrQuad->setObjectName("nbQuadraticPyramid"); - QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this ); - QLabel* a3DPriTotal = createField(); - a3DPriTotal->setObjectName("nbPrism"); - QLabel* a3DPriLin = createField(); - a3DPriLin->setObjectName("nbLinearPrism"); - QLabel* a3DPriQuad = createField(); - a3DPriQuad->setObjectName("nbQuadraticPrism"); - QLabel* a3DPriBiQuad = createField(); - a3DPriBiQuad->setObjectName("nbBiQuadraticPrism"); - QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this ); - QLabel* a3DHexPriTotal = createField(); - a3DHexPriTotal->setObjectName("nbHexagonalPrism"); - QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this ); - QLabel* a3DPolTotal = createField(); - a3DPolTotal->setObjectName("nbPolyhedron"); - myWidgets[ index++ ] << a3DLine; - myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad; - myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad; - myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad; - myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad; - myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad; - myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal; - myWidgets[ index++ ] << 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 ); - setFontAttributes( aElemLab, Bold ); - setFontAttributes( aElemTotal, Italic ); - setFontAttributes( aElemLin, Italic ); - setFontAttributes( aElemQuad, Italic ); - setFontAttributes( aElemBiQuad, Italic ); - setFontAttributes( a0DLab, Bold ); - setFontAttributes( aBallLab, Bold ); - setFontAttributes( a1DLab, Bold ); - setFontAttributes( a2DLab, Bold ); - setFontAttributes( a3DLab, Bold ); - - l->addWidget( aNameLab, 0, 0 ); - l->addWidget( aName, 0, 1, 1, 4 ); - l->addWidget( aObjLab, 1, 0 ); - l->addWidget( aObj, 1, 1, 1, 4 ); - l->addWidget( aNodesLine, 2, 0, 1, 5 ); - l->addWidget( aNodesLab, 3, 0 ); - l->addWidget( aNodes, 3, 1 ); - l->addWidget( aElemLine, 4, 0, 1, 5 ); - l->addWidget( aElemLab, 5, 0 ); - l->addWidget( aElemTotal, 5, 1 ); - l->addWidget( aElemLin, 5, 2 ); - l->addWidget( aElemQuad, 5, 3 ); - l->addWidget( aElemBiQuad, 5, 4 ); - l->addWidget( aNbLine, 6, 1, 1, 4 ); - l->addWidget( aNbTotal, 7, 1 ); - l->addWidget( aNbLin, 7, 2 ); - l->addWidget( aNbQuad, 7, 3 ); - l->addWidget( aNbBiQuad, 7, 4 ); - l->addWidget( a0DLine, 8, 1, 1, 4 ); - l->addWidget( a0DLab, 9, 0 ); - l->addWidget( a0DTotal, 9, 1 ); - l->addWidget( aBallLine, 10, 1, 1, 4 ); - l->addWidget( aBallLab, 11, 0 ); - l->addWidget( aBallTotal, 11, 1 ); - l->addWidget( a1DLine, 12, 1, 1, 4 ); - l->addWidget( a1DLab, 13, 0 ); - l->addWidget( a1DTotal, 13, 1 ); - l->addWidget( a1DLin, 13, 2 ); - l->addWidget( a1DQuad, 13, 3 ); - l->addWidget( a2DLine, 14, 1, 1, 4 ); - l->addWidget( a2DLab, 15, 0 ); - l->addWidget( a2DTotal, 15, 1 ); - l->addWidget( a2DLin, 15, 2 ); - l->addWidget( a2DQuad, 15, 3 ); - l->addWidget( a2DBiQuad, 15, 4 ); - l->addWidget( a2DTriLab, 16, 0 ); - l->addWidget( a2DTriTotal, 16, 1 ); - l->addWidget( a2DTriLin, 16, 2 ); - l->addWidget( a2DTriQuad, 16, 3 ); - l->addWidget( a2DTriBiQuad, 16, 4 ); - l->addWidget( a2DQuaLab, 17, 0 ); - l->addWidget( a2DQuaTotal, 17, 1 ); - l->addWidget( a2DQuaLin, 17, 2 ); - l->addWidget( a2DQuaQuad, 17, 3 ); - l->addWidget( a2DQuaBiQuad, 17, 4 ); - l->addWidget( a2DPolLab, 18, 0 ); - l->addWidget( a2DPolTotal, 18, 1 ); - l->addWidget( a2DPolLin, 18, 2 ); - l->addWidget( a2DPolQuad, 18, 3 ); - l->addWidget( a3DLine, 19, 1, 1, 4 ); - l->addWidget( a3DLab, 20, 0 ); - l->addWidget( a3DTotal, 20, 1 ); - l->addWidget( a3DLin, 20, 2 ); - l->addWidget( a3DQuad, 20, 3 ); - l->addWidget( a3DBiQuad, 20, 4 ); - l->addWidget( a3DTetLab, 21, 0 ); - l->addWidget( a3DTetTotal, 21, 1 ); - l->addWidget( a3DTetLin, 21, 2 ); - l->addWidget( a3DTetQuad, 21, 3 ); - l->addWidget( a3DHexLab, 22, 0 ); - l->addWidget( a3DHexTotal, 22, 1 ); - l->addWidget( a3DHexLin, 22, 2 ); - l->addWidget( a3DHexQuad, 22, 3 ); - l->addWidget( a3DHexBiQuad, 22, 4 ); - l->addWidget( a3DPyrLab, 23, 0 ); - l->addWidget( a3DPyrTotal, 23, 1 ); - l->addWidget( a3DPyrLin, 23, 2 ); - l->addWidget( a3DPyrQuad, 23, 3 ); - l->addWidget( a3DPriLab, 24, 0 ); - l->addWidget( a3DPriTotal, 24, 1 ); - l->addWidget( a3DPriLin, 24, 2 ); - l->addWidget( a3DPriQuad, 24, 3 ); - l->addWidget( a3DPriBiQuad, 24, 4 ); - l->addWidget( a3DHexPriLab, 25, 0 ); - l->addWidget( a3DHexPriTotal, 25, 1 ); - l->addWidget( a3DPolLab, 26, 0 ); - l->addWidget( a3DPolTotal, 26, 1 ); - l->addWidget( myLoadBtn, 28, 1, 1, 4 ); - - l->setColumnStretch( 0, 0 ); - l->setColumnStretch( 1, 5 ); - l->setColumnStretch( 2, 5 ); - l->setColumnStretch( 3, 5 ); - l->setColumnStretch( 4, 5 ); - l->setRowStretch( 27, 5 ); + // additional layout set-up + l->setColumnStretch( iLabel, 0 ); + l->setColumnStretch( iTotal, 5 ); + l->setColumnStretch( iLinear, 5 ); + l->setColumnStretch( iQuadratic, 5 ); + l->setColumnStretch( iBiQuadratic, 5 ); + l->setRowStretch( iElementsEnd, 5 ); + // set initial values clear(); } /*! - \brief Destructor + \brief Destructor. */ -SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo() +SMESHGUI_BaseInfo::~SMESHGUI_BaseInfo() { } /*! - \brief Show information on the mesh object. - \param obj object being processed (mesh, sub-mesh, group, ID source) + \brief Show information on given object. + \param proxy Object to show information on (mesh, sub-mesh, group, ID source). */ -void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +void SMESHGUI_BaseInfo::showInfo( const SMESH::SelectionProxy& proxy ) { + // reset panel clear(); - if ( !CORBA::is_nil( 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 ); - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); - if ( !aMesh->_is_nil() ) { - myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" )); - } - else if ( !aSubMesh->_is_nil() ) { - myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" )); - } - else if ( !aGroup->_is_nil() ) { - QString objType; - switch( aGroup->GetType() ) { - case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break; - case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break; - case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break; - case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break; - case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break; - case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break; - default: 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[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] )); - 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][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] )); - long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle]; - long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; - long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon]; - long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; - long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon]; - long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle]; - long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic; - myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal )); - myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear )); - myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic )); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic )); - 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[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_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[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] )); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons )); - myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] )); - myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] )); - long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; - 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] + info[SMDSEntity_BiQuad_Penta]; - 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_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; - long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta]; - long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic; - myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal )); - myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear )); - myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic )); - myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic )); - 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[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 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[i3DPrisms][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] )); - myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] )); - myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] )); - long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal; - long nbElemLinearial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear; - long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic; - long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic; - myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal )); - myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinearial )); - myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic )); - myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic )); - // 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 ) + // then fill panel with data if object is not null + if ( proxy ) + { + myProxy = proxy; + + SMESH::MeshInfo info = proxy.meshInfo(); + + // object info + // - name + widget( iName, iSingle )->setProperty( "text", proxy.name() ); + // - type + QString typeName; + SMESH::SelectionProxy::Type type = proxy.type(); + if ( type == SMESH::SelectionProxy::Mesh ) { - // 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 + typeName = tr( "OBJECT_MESH" ); + } + else if ( type == SMESH::SelectionProxy::Submesh ) + { + typeName = tr( "OBJECT_SUBMESH" ); + } + else if ( type >= SMESH::SelectionProxy::Group ) + { + switch( proxy.groupElementType() ) { - if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 ) + case SMESH::NODE: typeName = tr( "OBJECT_GROUP_NODES" ); break; + case SMESH::EDGE: typeName = tr( "OBJECT_GROUP_EDGES" ); break; + case SMESH::FACE: typeName = tr( "OBJECT_GROUP_FACES" ); break; + case SMESH::VOLUME: typeName = tr( "OBJECT_GROUP_VOLUMES" ); break; + case SMESH::ELEM0D: typeName = tr( "OBJECT_GROUP_0DELEMS" ); break; + case SMESH::BALL: typeName = tr( "OBJECT_GROUP_BALLS" ); break; + default: typeName = tr( "OBJECT_GROUP" ); break; + } + QString subType; + if ( type == SMESH::SelectionProxy::GroupStd ) + subType = tr( "OBJECT_GROUP_STANDALONE" ); + else if ( type == SMESH::SelectionProxy::GroupGeom ) + subType = tr( "OBJECT_GROUP_GEOM" ); + else if ( type == SMESH::SelectionProxy::GroupFilter ) + subType = tr( "OBJECT_GROUP_FILTER" ); + if ( !subType.isEmpty() ) + typeName = QString( "%1 %2" ).arg( typeName, subType ); + } + widget( iObject, iSingle )->setProperty( "text", typeName ); + + // node info + uint nbNodes = info[SMDSEntity_Node]; + widget( iNodes, iTotal )->setProperty( "value", nbNodes ); + + // element info + // - 0D elements info + uint nb0d = info[SMDSEntity_0D]; + widget( i0D, iTotal )->setProperty( "value", nb0d ); + // - balls info + uint nbBalls = info[SMDSEntity_Ball]; + widget( iBalls, iTotal )->setProperty( "value", nbBalls ); + // - 1D elements info + uint nb1dLin = info[SMDSEntity_Edge]; + uint nb1dQua = info[SMDSEntity_Quad_Edge]; + uint nb1d = nb1dLin + nb1dQua; + widget( i1D, iLinear )->setProperty( "value", nb1dLin ); + widget( i1D, iQuadratic )->setProperty( "value", nb1dQua ); + widget( i1D, iTotal )->setProperty( "value", nb1d ); + // - 2D elements info + // --+ triangles + uint nbTriLin = info[SMDSEntity_Triangle]; + uint nbTriQua = info[SMDSEntity_Quad_Triangle]; + uint nbTriBiq = info[SMDSEntity_BiQuad_Triangle]; + uint nbTri = nbTriLin + nbTriQua + nbTriBiq; + widget( i2DTriangles, iLinear )->setProperty( "value", nbTriLin ); + widget( i2DTriangles, iQuadratic )->setProperty( "value", nbTriQua ); + widget( i2DTriangles, iBiQuadratic )->setProperty( "value", nbTriBiq ); + widget( i2DTriangles, iTotal )->setProperty( "value", nbTri ); + // --+ quadrangles + uint nbQuadLin = info[SMDSEntity_Quadrangle]; + uint nbQuadQua = info[SMDSEntity_Quad_Quadrangle]; + uint nbQuadBiq = info[SMDSEntity_BiQuad_Quadrangle]; + uint nbQuad = nbQuadLin + nbQuadQua + nbQuadBiq; + widget( i2DQuadrangles, iLinear )->setProperty( "value", nbQuadLin ); + widget( i2DQuadrangles, iQuadratic )->setProperty( "value", nbQuadQua ); + widget( i2DQuadrangles, iBiQuadratic )->setProperty( "value", nbQuadBiq ); + widget( i2DQuadrangles, iTotal )->setProperty( "value", nbQuad ); + // --+ polygons + uint nbPolyLin = info[SMDSEntity_Polygon]; + uint nbPolyQua = info[SMDSEntity_Quad_Polygon]; + uint nbPoly = nbPolyLin + nbPolyQua; + widget( i2DPolygons, iLinear )->setProperty( "value", nbPolyLin ); + widget( i2DPolygons, iQuadratic )->setProperty( "value", nbPolyQua ); + widget( i2DPolygons, iTotal )->setProperty( "value", nbPoly ); + // --+ summary + uint nb2dLin = nbTriLin + nbQuadLin + nbPolyLin; + uint nb2dQua = nbTriQua + nbQuadQua + nbPolyQua; + uint nb2dBiq = nbTriBiq + nbQuadBiq; + uint nb2d = nb2dLin + nb2dQua + nb2dBiq; + widget( i2D, iLinear )->setProperty( "value", nb2dLin ); + widget( i2D, iQuadratic )->setProperty( "value", nb2dQua ); + widget( i2D, iBiQuadratic )->setProperty( "value", nb2dBiq ); + widget( i2D, iTotal )->setProperty( "value", nb2d ); + // - 3D elements info + // --+ tetras + uint nbTetraLin = info[SMDSEntity_Tetra]; + uint nbTetraQua = info[SMDSEntity_Quad_Tetra]; + uint nbTetra = nbTetraLin + nbTetraQua; + widget( i3DTetrahedrons, iLinear )->setProperty( "value", nbTetraLin ); + widget( i3DTetrahedrons, iQuadratic )->setProperty( "value", nbTetraQua ); + widget( i3DTetrahedrons, iTotal )->setProperty( "value", nbTetra ); + // --+ hexas + uint nbHexaLin = info[SMDSEntity_Hexa]; + uint nbHexaQua = info[SMDSEntity_Quad_Hexa]; + uint nbHexaBiq = info[SMDSEntity_TriQuad_Hexa]; + uint nbHexa = nbHexaLin + nbHexaQua + nbHexaBiq; + widget( i3DHexahedrons, iLinear )->setProperty( "value", nbHexaLin ); + widget( i3DHexahedrons, iQuadratic )->setProperty( "value", nbHexaQua ); + widget( i3DHexahedrons, iBiQuadratic )->setProperty( "value", nbHexaBiq ); + widget( i3DHexahedrons, iTotal )->setProperty( "value", nbHexa ); + // --+ pyramids + uint nbPyraLin = info[SMDSEntity_Pyramid]; + uint nbPyraQua = info[SMDSEntity_Quad_Pyramid]; + uint nbPyra = nbPyraLin + nbPyraQua; + widget( i3DPyramids, iLinear )->setProperty( "value", nbPyraLin ); + widget( i3DPyramids, iQuadratic )->setProperty( "value", nbPyraQua ); + widget( i3DPyramids, iTotal )->setProperty( "value", nbPyra ); + // --+ prisms + uint nbPentaLin = info[SMDSEntity_Penta]; + uint nbPentaQua = info[SMDSEntity_Quad_Penta]; + uint nbPentaBiq = info[SMDSEntity_BiQuad_Penta]; + uint nbPenta = nbPentaLin + nbPentaQua + nbPentaBiq; + widget( i3DPrisms, iLinear )->setProperty( "value", nbPentaLin ); + widget( i3DPrisms, iQuadratic )->setProperty( "value", nbPentaQua ); + widget( i3DPrisms, iBiQuadratic )->setProperty( "value", nbPentaBiq ); + widget( i3DPrisms, iTotal )->setProperty( "value", nbPenta ); + // --+ hexagonal prisms + uint nbHexaPri = info[SMDSEntity_Hexagonal_Prism]; + widget( i3DHexaPrisms, iTotal )->setProperty( "value", nbHexaPri ); + // --+ polyhedrons + uint nbPolyhedra = info[SMDSEntity_Polyhedra]; + widget( i3DPolyhedrons, iTotal )->setProperty( "value", nbPolyhedra ); + // --+ summary + uint nb3dLin = nbTetraLin + nbHexaLin + nbPyraLin + nbPentaLin + nbHexaPri + nbPolyhedra; + uint nb3dQua = nbTetraQua + nbHexaQua + nbPyraQua + nbPentaQua; + uint nb3dBiq = nbHexaBiq + nbPentaBiq; + uint nb3d = nb3dLin + nb3dQua + nb3dBiq; + widget( i3D, iLinear )->setProperty( "value", nb3dLin ); + widget( i3D, iQuadratic )->setProperty( "value", nb3dQua ); + widget( i3D, iBiQuadratic )->setProperty( "value", nb3dBiq ); + widget( i3D, iTotal )->setProperty( "value", nb3d ); + // - summary + uint nbElemLin = nb1dLin + nb2dLin + nb3dLin; + uint nbElemQua = nb1dQua + nb2dQua + nb3dQua; + uint nbElemBiq = nb2dBiq + nb3dBiq; + uint nbElem = nb0d + nbBalls + nb1d + nb2d + nb3d; + widget( iElementsTotal, iLinear )->setProperty( "value", nbElemLin ); + widget( iElementsTotal, iQuadratic )->setProperty( "value", nbElemQua ); + widget( iElementsTotal, iBiQuadratic )->setProperty( "value", nbElemBiq ); + widget( iElementsTotal, iTotal )->setProperty( "value", nbElem ); + + // show 'Load' button if data was not loaded yet + widget( iEnd, iSingle )->setVisible( !proxy.isValid() ); + + // until data is loaded from study file, type of elements in a sub-mesh or group + // can be undefined in some cases + if ( !proxy.isValid() ) + { + // two cases are possible: + // 1. type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh) + // 2. there is no info at all (for a group on geom or on filter) + if ( info.count( SMDSEntity_Node, SMDSEntity_Last ) > 0 ) // believe it is a sub-mesh + { + if ( nb2dLin + nb2dQua + nb2dBiq > 0 ) { - myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); - myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" ); + // we know nothing about triangles, quadranges and polygons + for ( int i = i2DTriangles; i < i2DEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "text", "?" ); + } + } + // we don't know if elements are linear, quadratic or bi-quadratic + for ( int j = iLinear; j < iNbColumns; j++ ) + { + if ( widget( i2D, j ) ) + widget( i2D, j )->setProperty( "text", "?" ); + if ( widget( iElementsTotal, j ) ) + widget( iElementsTotal, j )->setProperty( "text", "?" ); + } } - else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 ) + else if ( nb3dLin + nb3dQua + nb3dBiq > 0 ) { - myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3D][iBiQuadratic] ->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[i3DHexahedrons][iBiQuadratic] ->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", "?" ); - myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); - myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" ); + // we know nothing about tetras, hexas, etc. + for ( int i = i3DTetrahedrons; i < i3DEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "text", "?" ); + } + } + // we don't know if elements are linear, quadratic or bi-quadratic + for ( int j = iLinear; j < iNbColumns; j++ ) + { + if ( widget( i3D, j ) ) + widget( i3D, j )->setProperty( "text", "?" ); + if ( widget( iElementsTotal, j ) ) + widget( iElementsTotal, j )->setProperty( "text", "?" ); + } } } else { - myWidgets[iNodes][iTotal] ->setProperty( "text", "?" ); - myWidgets[i0D][iTotal] ->setProperty( "text", "?" ); - myWidgets[iBalls][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[i2D][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iBiQuadratic] ->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[i3DHexahedrons][iBiQuadratic] ->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", "?" ); - myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); - myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" ); + // we know nothing about nodes :( + widget( iNodes, iTotal )->setProperty( "text", "?" ); + // we know nothing about elements :( + for ( int i = iElementsTotal; i < iElementsEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "text", "?" ); + } + } } } } } /*! - \brief Load mesh from a study file + \brief Update information in panel. */ -void SMESHGUI_MeshInfo::loadMesh() +void SMESHGUI_BaseInfo::updateInfo() +{ + showInfo( myProxy ); +} + +/*! + \brief Load mesh from a study file. +*/ +void SMESHGUI_BaseInfo::loadMesh() { SUIT_OverrideCursor wc; + if ( myProxy ) + { + myProxy.load(); + updateInfo(); + } +} - 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 ); - } +/*! + \brief Reset panel (clear all data). +*/ +void SMESHGUI_BaseInfo::clear() +{ + // - name + widget( iName, iSingle )->setProperty( "text", QString() ); + // - type + widget( iObject, iSingle )->setProperty( "text", QString() ); + // - nodes + widget( iNodes, iTotal )->setProperty( "value", 0 ); + // - elements + for ( int i = iElementsTotal; i < iElementsEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "value", 0 ); } } } /*! - \brief Reset the widget to the initial state (nullify all fields). + \brief Register widget in a grid. + \param w Widget being added. + \param row Row index in a grid. + \param column Column index in a grid. + \param colspan Number of columns to span in a grid. Defaults to 1. + \return Just added widget. */ -void SMESHGUI_MeshInfo::clear() +QWidget* SMESHGUI_BaseInfo::addWidget( QWidget* w, int row, int column, int colspan ) { - myWidgets[iName][iSingle] ->setProperty( "text", QString() ); - myWidgets[iObject][iSingle] ->setProperty( "text", QString() ); - myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 )); - 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 )); - myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); + if ( !myWidgets.contains( row ) ) + myWidgets[row] = wlist(); + myWidgets[row][column] = w; + dynamic_cast( layout() )->addWidget( w, row, column, 1, colspan ); + return w; } /*! - \brief Create info field - \return new info field + \brief Get registered widget. + \param row Row index in a grid. + \param column Column index in a grid. + \return Widget stored in a given grid cell (0 if there's no widget). */ -QLabel* SMESHGUI_MeshInfo::createField() +QWidget* SMESHGUI_BaseInfo::widget( int row, int column ) const { - QLabel* lab = new QLabel( this ); - lab->setFrameStyle( StyledPanel | Sunken ); - lab->setAlignment( Qt::AlignCenter ); - lab->setAutoFillBackground( true ); - QPalette pal = lab->palette(); - pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base )); - lab->setPalette( pal ); - lab->setMinimumWidth( 70 ); - return lab; + return myWidgets.contains( row ) && myWidgets[row].contains( column ) ? myWidgets[row][column] : 0; } /*! - \brief Create horizontal rule. - \return new line object + \brief Get text value from registered widget. + \param row Row index in a grid. + \param column Column index in a grid. + \return Value string (empty string if no label in given cell). */ -QWidget* SMESHGUI_MeshInfo::createLine() +QString SMESHGUI_BaseInfo::value( int row, int column ) const { - QFrame* line = new QFrame( this ); - line->setFrameStyle( HLine | Sunken ); - return line; + return widgetValue( widget( row, column ) ); } /*! - \brief Change widget font attributes (bold, italic, ...). - \param w widget - \param attr font attributes (XORed flags) - \param val value to be set to attributes + \brief Show/hide group(s) of widgets. + \param startRow Starting grid row. + \param lastRow Last grid row. + \param on Visibility flag. */ -void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val ) +void SMESHGUI_BaseInfo::setFieldsVisible( int startRow, int lastRow, bool on ) { - if ( w && attr ) { - QFont f = w->font(); - if ( attr & Bold ) f.setBold( val ); - if ( attr & Italic ) f.setItalic( val ); - w->setFont( f ); + startRow = qMax( 0, startRow ); + lastRow = qMin( lastRow, (int)iEnd ); + for ( int i = startRow; i <= lastRow; i++ ) + { + wlist widgets = myWidgets[i]; + foreach ( QWidget* w, widgets ) + w->setVisible( on ); } } /*! - \brief Show/hide group(s) of fields. - \param start beginning of the block - \param end end of the block - \param on visibility flag + \brief Write information from panel to ouput stream. + \param out Text stream output. */ -void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on ) +void SMESHGUI_BaseInfo::saveInfo( QTextStream& out ) { - start = qMax( 0, start ); - end = qMin( end, (int)iElementsEnd ); - for ( int i = start; i < end; i++ ) { - wlist wl = myWidgets[i]; - foreach ( QWidget* w, wl ) w->setVisible( on ); + // title + QString title = tr( "BASE_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + out << endl; + + // object info + // - name + out << tr( "NAME_LAB" ) << spacing() << value( iName, iSingle ) << endl; + // - type + out << tr( "OBJECT_LAB" ) << spacing() << value( iObject, iSingle ) << endl; + // - --- (separator) + out << endl; + + // node info + out << tr( "NODES_LAB" ) << spacing() << value( iNodes, iTotal ) << endl; + // - --- (separator) + out << endl; + + // element info + QString lin = tr( "LINEAR_LAB" ) + ":" + spacing(); + QString qua = tr( "QUADRATIC_LAB" ) + ":" + spacing(); + QString biq = tr( "BI_QUADRATIC_LAB" ) + ":" + spacing(); + // - summary + out << tr( "ELEMENTS_LAB" ) << spacing() << value( iElementsTotal, iTotal ) << endl; + out << indent(1) << lin << value( iElementsTotal, iLinear ) << endl; + out << indent(1) << qua << value( iElementsTotal, iQuadratic ) << endl; + out << indent(1) << biq << value( iElementsTotal, iBiQuadratic ) << endl; + // - --- (separator) + out << endl; + // - 0D elements info + out << indent(1) << tr( "0D_LAB" ) << spacing() << value( i0D, iTotal ) << endl; + // - --- (separator) + out << endl; + // - balls info + out << indent(1) << tr( "BALL_LAB" ) << spacing() << value( iBalls, iTotal ) << endl; + // - --- (separator) + out << endl; + // - 1D elements info + out << indent(1) << tr( "1D_LAB" ) << spacing() << value( i1D, iTotal ) << endl; + out << indent(2) << lin << value( i1D, iLinear ) << endl; + out << indent(2) << qua << value( i1D, iQuadratic ) << endl; + // - --- (separator) + out << endl; + // - 2D elements info + // - summary + out << indent(1) << tr( "2D_LAB" ) << spacing() << value( i2D, iTotal ) << endl; + out << indent(2) << lin << value( i2D, iLinear ) << endl; + out << indent(2) << qua << value( i2D, iQuadratic ) << endl; + out << indent(2) << biq << value( i2D, iBiQuadratic ) << endl; + // - --- (separator) + out << endl; + // --+ triangles + out << indent(2) << tr( "TRIANGLES_LAB" ) << spacing() << value( i2DTriangles, iTotal ) << endl; + out << indent(3) << lin << value( i2DTriangles, iLinear ) << endl; + out << indent(3) << qua << value( i2DTriangles, iQuadratic ) << endl; + out << indent(3) << biq << value( i2DTriangles, iBiQuadratic ) << endl; + // --+ quadrangles + out << indent(2) << tr( "QUADRANGLES_LAB" ) << spacing() << value( i2DQuadrangles, iTotal ) << endl; + out << indent(3) << lin << value( i2DQuadrangles, iLinear ) << endl; + out << indent(3) << qua << value( i2DQuadrangles, iQuadratic ) << endl; + out << indent(3) << biq << value( i2DQuadrangles, iBiQuadratic ) << endl; + // --+ polygons + out << indent(2) << tr( "POLYGONS_LAB" ) << spacing() << value( i2DPolygons, iTotal ) << endl; + out << indent(3) << lin << value( i2DPolygons, iLinear ) << endl; + out << indent(3) << qua << value( i2DPolygons, iQuadratic ) << endl; + // - --- (separator) + out << endl; + // - 3D elements info + // --+ summary + out << indent(1) << tr( "3D_LAB" ) << spacing() << value( i3D, iTotal ) << endl; + out << indent(2) << lin << value( i3D, iLinear ) << endl; + out << indent(2) << qua << value( i3D, iQuadratic ) << endl; + out << indent(2) << biq << value( i3D, iBiQuadratic ) << endl; + // - --- (separator) + out << endl; + // --+ tetras + out << indent(2) << tr( "TETRAHEDRONS_LAB" ) << spacing() << value( i3DTetrahedrons, iTotal ) << endl; + out << indent(3) << lin << value( i3DTetrahedrons, iLinear ) << endl; + out << indent(3) << qua << value( i3DTetrahedrons, iQuadratic ) << endl; + // --+ hexas + out << indent(2) << tr( "HEXAHEDONRS_LAB" ) << spacing() << value( i3DHexahedrons, iTotal ) << endl; + out << indent(3) << lin << value( i3DHexahedrons, iLinear ) << endl; + out << indent(3) << qua << value( i3DHexahedrons, iQuadratic ) << endl; + out << indent(3) << biq << value( i3DHexahedrons, iBiQuadratic ) << endl; + // --+ pyramids + out << indent(2) << tr( "PYRAMIDS_LAB" ) << spacing() << value( i3DPyramids, iTotal ) << endl; + out << indent(3) << lin << value( i3DPyramids, iLinear ) << endl; + out << indent(3) << qua << value( i3DPyramids, iQuadratic ) << endl; + // --+ prisms + out << indent(2) << tr( "PRISMS_LAB" ) << spacing() << value( i3DPrisms, iTotal ) << endl; + out << indent(3) << lin << value( i3DPrisms, iLinear ) << endl; + out << indent(3) << qua << value( i3DPrisms, iQuadratic ) << endl; + out << indent(3) << biq << value( i3DPrisms, iBiQuadratic ) << endl; + // --+ hexagonal prisms + out << indent(2) << tr( "HEX_PRISMS_LAB" ) << spacing() << value( i3DHexaPrisms, iTotal ) << endl; + // --+ polyhedrons + out << indent(2) << tr( "POLYHEDRONS_LAB" ) << spacing() << value( i3DPolyhedrons, iTotal ) << endl; + // - --- (separator) + out << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class InfoWriter +/// \brief Base info writer class. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class InfoWriter +{ +protected: + int myPrecision; + bool myRecursive; +public: + InfoWriter( bool = false ); + void write( const QString&, bool = false ); + void write( const QString&, const QString&, bool = false ); + void write( const QString&, int, bool = false ); + void write( const QString&, double, bool = false ); + void write( const QString&, const SMESH::XYZ&, bool = false ); + virtual void indent() {} + virtual void unindent() {} + virtual void separator() {} +protected: + virtual void put( const QString&, const QString&, bool = false ) = 0; +}; + +InfoWriter::InfoWriter( bool r ): myRecursive(r) +{ + myPrecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); +} + +void InfoWriter::write( const QString& key, bool emphasize ) +{ + put( key, QString(), emphasize ); +} + +void InfoWriter::write( const QString& key, const QString& value, bool emphasize ) +{ + put( key, value, emphasize ); +} + +void InfoWriter::write( const QString& key, int value, bool emphasize ) +{ + put( key, QString::number( value ), emphasize ); +} + +void InfoWriter::write( const QString& key, double value, bool emphasize ) +{ + put( key, QString::number( value, myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ), emphasize ); +} + +void InfoWriter::write( const QString& key, const SMESH::XYZ& value, bool emphasize ) +{ + if ( myRecursive ) + { + write( key, emphasize ); + indent(); + write( "X", value.x() ); + write( "Y", value.y() ); + write( "Z", value.z() ); + unindent(); + } + else + { + QStringList vl; + vl << QString::number( value.x(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ); + vl << QString::number( value.y(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ); + vl << QString::number( value.z(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ); + put( key, vl.join( ", " ), emphasize ); } } -void SMESHGUI_MeshInfo::saveInfo( QTextStream &out ) +//////////////////////////////////////////////////////////////////////////////// +/// \class SimpleWriter +/// \brief Base text writer. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class SimpleWriter: public InfoWriter +{ +protected: + int myIndent; +public: + SimpleWriter(); + void indent(); + void unindent(); + void separator(); +protected: + void put( const QString&, const QString&, bool ); + virtual QString spacer() const; + virtual QString decorate( const QString& ) const; + virtual void dumpLine( const QString& ) = 0; +}; + +SimpleWriter::SimpleWriter(): InfoWriter(false), myIndent(0) { - out << QString( 9, '-' ) << "\n"; - out << tr( "BASE_INFO" ) << "\n"; - out << QString( 9, '-' ) << "\n"; - out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" )).toString() << "\n"; - out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" )).toString() << "\n"; - out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" )).toString() << "\n"; - out << tr( "ELEMENTS_LAB" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" )).toString() << "\n" << "\n"; } -/*! - \class SMESHGUI_ElemInfo - \brief Base class for the mesh element information widget. -*/ +void SimpleWriter::indent() +{ + myIndent += 1; +} + +void SimpleWriter::unindent() +{ + myIndent = qMax( myIndent-1, 0 ); +} + +void SimpleWriter::separator() +{ + write( "" ); +} + +QString SimpleWriter::spacer() const +{ + return " "; +} + +QString SimpleWriter::decorate( const QString& s ) const +{ + return s; +} + +void SimpleWriter::put( const QString& key, const QString& value, bool emphasize ) +{ + QString line; + line += ::indent( spacer(), myIndent*4 ); + line += decorate( key ); + if ( !value.isEmpty() ) + { + line += ":"; + line += emphasize ? decorate( value ) : value; + } + dumpLine( line ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class StreamWriter +/// \brief Writer for QTextStream. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class StreamWriter: public SimpleWriter +{ + QTextStream& myOut; +public: + StreamWriter( QTextStream& ); +protected: + void dumpLine( const QString& ); +}; + +StreamWriter::StreamWriter( QTextStream& out ): SimpleWriter(), myOut(out) +{ +} + +void StreamWriter::dumpLine( const QString& line ) +{ + myOut << line; + myOut << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class TextWriter +/// \brief Writer for QTextBrowser. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class TextWriter: public SimpleWriter +{ + QTextBrowser* myInfo; +public: + TextWriter( QTextBrowser* ); +protected: + QString spacer() const; + QString decorate( const QString& ) const; + void dumpLine( const QString& ); +}; + +TextWriter::TextWriter( QTextBrowser* w ): SimpleWriter(), myInfo(w) +{ +} + +QString TextWriter::spacer() const +{ + return " "; +} + +QString TextWriter::decorate( const QString& s ) const +{ + return bold( s ); +} + +void TextWriter::dumpLine( const QString& line ) +{ + myInfo->append( line ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class TreeWriter +/// \brief Writer for QTreeWidget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class TreeWriter: public InfoWriter +{ + QTreeWidget* myInfo; + QTreeWidgetItem* myCurrentItem; + TreeItemCreator* myCreator; +public: + TreeWriter( QTreeWidget*, TreeItemCreator* ); + ~TreeWriter(); + void indent(); + void unindent(); +protected: + void put( const QString&, const QString&, bool = false ); +}; + +TreeWriter::TreeWriter( QTreeWidget* w, TreeItemCreator* c ): + InfoWriter(true), myInfo(w), myCurrentItem(0), myCreator(c) +{ +} + +TreeWriter::~TreeWriter() +{ + delete myCreator; +} + +void TreeWriter::put( const QString& key, const QString& value, bool emphasize ) +{ + //std::string sss = myCurrentItem ? myCurrentItem->text(0).toStdString() : ""; + int options = Bold; + if ( emphasize ) options |= AllColumns; + QTreeWidgetItem* item = myCreator->createItem( myCurrentItem, options ); + item->setText( 0, key ); + if ( !value.isEmpty() ) + { + QString val = value; + if ( value.startsWith( "1 2 + { + int role = ( value[11] == 'n' ) ? NodeConnectivity : ElemConnectivity; + val = value.mid( value.lastIndexOf( '>', -5 ) + 1 ); // ==> 1 2 + val.chop( 4 ); + item->setData( 1, TypeRole, role ); + } + item->setText( 1, val ); + } +} + +void TreeWriter::indent() +{ + QTreeWidgetItem* item = myCurrentItem ? myCurrentItem : myInfo->invisibleRootItem(); + if ( item->childCount() > 0 ) + myCurrentItem = item->child( item->childCount()-1 ); +} + +void TreeWriter::unindent() +{ + if ( myCurrentItem ) + myCurrentItem = myCurrentItem->parent(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_ElemInfo +/// \brief Base class for the mesh element information widget. +/// +/// Displays the detail information about given mesh node(s) or element(s). +/// Default class does not provide working implementation but onle general +/// functionalities; main work is done in sub-classes. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ) - : QWidget( parent ), myActor( 0 ), myIsElement( -1 ) +SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ): SMESHGUI_Info( parent ), myWhat( ShowNone ) { myFrame = new QWidget( this ); myExtra = new ExtraWidget( this ); + QVBoxLayout* vbl = new QVBoxLayout( this ); vbl->setMargin( 0 ); - vbl->setSpacing( 0 ); + vbl->setSpacing( SPACING ); vbl->addWidget( myFrame ); vbl->addWidget( myExtra ); - connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() )); - connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() )); + + connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) ); + connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) ); + clear(); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo() { } /*! - \brief Set mesh data source (actor) - \param actor mesh object actor + \brief Show information on given node / element. + \param proxy Object to compute information on (mesh, sub-mesh, group, ID source). + \param id Mesh node / element ID. + \param isElement If \c true, show element info; otherwise show node info. */ -void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor, SMESH::SMESH_IDSource_var obj ) +void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy, uint id, bool isElement ) { - if ( myActor != actor ) { - myActor = actor; - myIsElement = -1; - SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); - myMeshHasShape = ( !mesh->_is_nil() && mesh->HasShapeToMesh() ); - clear(); - } -} - -/*! - \brief Show mesh element information - \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 ) -{ - QSet ids; + QSet ids; ids << id; - showInfo( ids, isElem ); + showInfo( proxy, ids, isElement ); } /*! - \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 + \brief Show information on given nodes / elements. + \param proxy Object to compute information on (mesh, sub-mesh, group, ID source). + \param ids Mesh nodes / elements IDs. + \param isElement If \c true, show element info; otherwise show node info. */ -void SMESHGUI_ElemInfo::showInfo( QSet ids, bool isElem ) +void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy, QSet ids, bool isElement ) { - QList newIds = ids.toList(); + if ( !proxy ) + { + clear(); + return; + } + + QList newIds = ids.toList(); qSort( newIds ); - if ( myIDs == newIds && myIsElement == isElem ) return; + int what = isElement ? ShowElements : ShowNodes; + + if ( myProxy == proxy && myIDs == newIds && myWhat == what ) + return; + + myProxy = proxy; + myProxy.refresh(); // try to re-initialize actor + + clear(); myIDs = newIds; - myIsElement = isElem; + myWhat = what; myIndex = 0; + updateControls(); - information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS )); + information( myIDs.mid( myIndex*blockSize(), blockSize() ) ); } /*! - \brief Clear mesh element information widget + \brief Show information on given group. + \param proxy Object to compute information on (group). +*/ +void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy ) +{ + if ( !proxy || proxy.groupElementType() == SMESH::ALL ) // null proxy or not a group + { + clear(); + return; + } + + showInfo( proxy, proxy.ids(), proxy.groupElementType() != SMESH::NODE ); +} + +/*! + \brief Reset panel (clear all data). */ void SMESHGUI_ElemInfo::clear() { @@ -1019,136 +1513,483 @@ void SMESHGUI_ElemInfo::clear() } /*! - \brief Get central area widget - \return central widget + \brief Get central area widget. + \return Central widget. */ -QWidget* SMESHGUI_ElemInfo::frame() const +QWidget* SMESHGUI_ElemInfo::centralWidget() const { return myFrame; } /*! - \brief Get actor - \return actor being used + \brief Get current mesh proxy object information is shown on. + \return Current proxy. */ -SMESH_Actor* SMESHGUI_ElemInfo::actor() const +SMESH::SelectionProxy SMESHGUI_ElemInfo::proxy() const { - return myActor; + return myProxy; } /*! \brief Get current info mode. - \return \c true if mesh element information is shown or \c false if node information is shown + \return Current panel mode. */ -bool SMESHGUI_ElemInfo::isElements() const +int SMESHGUI_ElemInfo::what() const { - return myIsElement; + return myWhat; } /*! - \fn void SMESHGUI_ElemInfo::information( const QList& ids ) - \brief Show information on the specified nodes / elements + \brief Get title for given element type. + \param type Mesh element type. + \param multiple Use plural form. Defaults to \c false. + \return Element type's title. +*/ +QString SMESHGUI_ElemInfo::type2str( int type, bool multiple ) +{ + QString title; + switch ( type ) + { + case SMDSAbs_Edge: + title = multiple ? tr( "EDGES" ) : tr( "EDGE" ) ; break; + case SMDSAbs_Face: + title = multiple ? tr( "FACES" ) : tr( "FACE" ); break; + case SMDSAbs_Volume: + title = multiple ? tr( "VOLUMES" ) : tr( "VOLUME" ); break; + case SMDSAbs_0DElement: + title = multiple ? tr( "0D_ELEMENTS" ) : tr( "0D_ELEMENT" ); break; + case SMDSAbs_Ball: + title = multiple ? tr( "BALL_ELEMENTS" ) : tr( "BALL" ); break; + default: + break; + } + return title; +} - This function is to be redefined in sub-classes. +/*! + \brief Get title for given shape type. + \param type Shape type. + \return Shape type's title. +*/ +QString SMESHGUI_ElemInfo::stype2str( int type ) +{ + QString title; + switch ( type ) + { + case GEOM::VERTEX: + title = tr( "GEOM_VERTEX" ); break; + case GEOM::EDGE: + title = tr( "GEOM_EDGE" ); break; + case GEOM::FACE: + title = tr( "GEOM_FACE" ); break; + case GEOM::SOLID: + default: + title = tr( "GEOM_SOLID" ); break; + break; + } + return title; +} - \param ids nodes / elements identifiers information is to be shown on +/*! + \brief Get title for given element type. + \param type Mesh element type. + \return Element type's title. +*/ +QString SMESHGUI_ElemInfo::etype2str( int type ) +{ + QString title; + switch ( type ) + { + case SMESH::Entity_0D: + title = tr( "SMESH_ELEM0D" ); break; + case SMESH::Entity_Edge: + title = tr( "SMESH_EDGE" ); break; + case SMESH::Entity_Quad_Edge: + title = tr( "SMESH_QUADRATIC_EDGE" ); break; + case SMESH::Entity_Triangle: + title = tr( "SMESH_TRIANGLE" ); break; + case SMESH::Entity_Quad_Triangle: + title = tr( "SMESH_QUADRATIC_TRIANGLE" ); break; + case SMESH::Entity_BiQuad_Triangle: + title = tr( "SMESH_BIQUADRATIC_TRIANGLE" ); break; + case SMESH::Entity_Quadrangle: + title = tr( "SMESH_QUADRANGLE" ); break; + case SMESH::Entity_Quad_Quadrangle: + title = tr( "SMESH_QUADRATIC_QUADRANGLE" ); break; + case SMESH::Entity_BiQuad_Quadrangle: + title = tr( "SMESH_BIQUADRATIC_QUADRANGLE" ); break; + case SMESH::Entity_Polygon: + title = tr( "SMESH_POLYGON" ); break; + case SMESH::Entity_Quad_Polygon: + title = tr( "SMESH_QUADRATIC_POLYGON" ); break; + case SMESH::Entity_Tetra: + title = tr( "SMESH_TETRAHEDRON" ); break; + case SMESH::Entity_Quad_Tetra: + title = tr( "SMESH_QUADRATIC_TETRAHEDRON" ); break; + case SMESH::Entity_Pyramid: + title = tr( "SMESH_PYRAMID" ); break; + case SMESH::Entity_Quad_Pyramid: + title = tr( "SMESH_QUADRATIC_PYRAMID" ); break; + case SMESH::Entity_Hexa: + title = tr( "SMESH_HEXAHEDRON" ); break; + case SMESH::Entity_Quad_Hexa: + title = tr( "SMESH_QUADRATIC_HEXAHEDRON" ); break; + case SMESH::Entity_TriQuad_Hexa: + title = tr( "SMESH_TRIQUADRATIC_HEXAHEDRON" ); break; + case SMESH::Entity_Penta: + title = tr( "SMESH_PENTA" ); break; + case SMESH::Entity_Quad_Penta: + title = tr( "SMESH_QUADRATIC_PENTAHEDRON" ); break; + case SMESH::Entity_BiQuad_Penta: + title = tr( "SMESH_BIQUADRATIC_PENTAHEDRON" ); break; + case SMESH::Entity_Hexagonal_Prism: + title = tr( "SMESH_HEX_PRISM" ); break; + case SMESH::Entity_Polyhedra: + title = tr( "SMESH_POLYEDRON" ); break; + case SMESH::Entity_Quad_Polyhedra: + title = tr( "SMESH_QUADRATIC_POLYEDRON" ); break; + case SMESH::Entity_Ball: + title = tr( "SMESH_BALL" ); break; + default: + break; + } + return title; +} + +/*! + \brief Get title for given quality control. + \param type Mesh control type. + \return Quality control's title. +*/ +QString SMESHGUI_ElemInfo::ctrl2str( int control ) +{ + QString title; + switch ( control ) + { + case SMESH::FT_AspectRatio: + title = tr( "ASPECTRATIO_ELEMENTS" ); break; + case SMESH::FT_AspectRatio3D: + title = tr( "ASPECTRATIO_3D_ELEMENTS" ); break; + case SMESH::FT_Warping: + title = tr( "WARP_ELEMENTS" ); break; + case SMESH::FT_MinimumAngle: + title = tr( "MINIMUMANGLE_ELEMENTS" ); break; + case SMESH::FT_Taper: + title = tr( "TAPER_ELEMENTS" ); break; + case SMESH::FT_Skew: + title = tr( "SKEW_ELEMENTS" ); break; + case SMESH::FT_Area: + title = tr( "AREA_ELEMENTS" ); break; + case SMESH::FT_Volume3D: + title = tr( "VOLUME_3D_ELEMENTS" ); break; + case SMESH::FT_MaxElementLength2D: + title = tr( "MAX_ELEMENT_LENGTH_2D" ); break; + case SMESH::FT_MaxElementLength3D: + title = tr( "MAX_ELEMENT_LENGTH_3D" ); break; + case SMESH::FT_Length: + title = tr( "LENGTH_EDGES" ); break; + case SMESH::FT_Length2D: + case SMESH::FT_Length3D: + title = tr( "MIN_ELEM_EDGE" ); break; + case SMESH::FT_BallDiameter: + title = tr( "BALL_DIAMETER" ); break; + default: + break; + } + return title; +} + +/*! + \brief Write information on given mesh nodes / elements. + \param writer Information writer. + \param ids Nodes / elements IDs. +*/ +void SMESHGUI_ElemInfo::writeInfo( InfoWriter* writer, const QList& ids ) +{ + if ( !proxy() ) + return; + + bool grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); + int cprecision = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ? + SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ) : -1; + + SMESH::XYZ xyz; + SMESH::Connectivity connectivity; + SMESH::Position position; + bool ok; + + foreach ( uint id, ids ) + { + writer->separator(); + + if ( what() == ShowNodes ) + { + // show node info + // - check that node exists + if ( !proxy().hasNode( id ) ) + continue; + // - id + writer->write( tr( "NODE" ), (int)id, true ); + writer->indent(); + // - coordinates + ok = proxy().nodeCoordinates( id, xyz ); + if ( ok ) + { + writer->write( tr( "COORDINATES" ), xyz ); + } + // - connectivity + ok = proxy().nodeConnectivity( id, connectivity ); + if ( ok ) + { + if ( !connectivity.isEmpty() ) + { + writer->write( tr( "CONNECTIVITY" ) ); + writer->indent(); + for ( int i = SMDSAbs_Edge; i <= SMDSAbs_Ball; i++ ) + { + QString formatted = formatConnectivity( connectivity, i ); + if ( !formatted.isEmpty() ) + writer->write( type2str( i, true ), formatted ); + } + writer->unindent(); + } + else + { + writer->write( tr( "CONNECTIVITY" ), tr( "FREE_NODE" ) ); + } + } + // - position + ok = proxy().nodePosition( id, position ); + if ( ok && position.isValid() ) + { + writer->write( tr( "POSITION" ), (stype2str( position.shapeType() ) + " #%1").arg( position.shapeId() ) ); + writer->indent(); + if ( position.hasU() ) + writer->write( tr("U_POSITION"), position.u() ); + if ( position.hasV() ) + writer->write( tr("V_POSITION"), position.v() ); + writer->unindent(); + } + // - groups node belongs to + QList groups = proxy().nodeGroups( id ); + bool topCreated = false; + foreach( SMESH::SelectionProxy group, groups ) + { + if ( group && !group.name().isEmpty() ) + { + if ( !topCreated ) + { + writer->write( SMESHGUI_AddInfo::tr( "GROUPS" ) ); + writer->indent(); + topCreated = true; + } + writer->write( group.name().trimmed() ); // trim name + if ( grp_details ) + { + writer->indent(); + int type = group.type(); + if ( type == SMESH::SelectionProxy::GroupStd ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ); + } + else if ( type == SMESH::SelectionProxy::GroupGeom ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ); + writer->write( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ), group.shapeName() ); + } + else if ( type == SMESH::SelectionProxy::GroupFilter ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ); + } + int size = group.size(); + if ( size != -1 ); + writer->write( SMESHGUI_AddInfo::tr( "SIZE" ), size ); + QColor color = group.color(); + if ( color.isValid() ) + writer->write( SMESHGUI_AddInfo::tr( "COLOR" ), color.name() ); + writer->unindent(); + } + } + } + if ( topCreated ) + writer->unindent(); + writer->unindent(); + } + else if ( what() == ShowElements ) + { + // show element info + // - check that element exists + if ( !proxy().hasElement( id ) ) + continue; + // - id & type + int type = proxy().elementType( id ); + if ( type == SMESH::ALL ) + continue; + writer->write( type2str( type ), (int)id, true ); + writer->indent(); + // - geometry type + type = proxy().elementEntityType( id ); + writer->write( tr( "TYPE" ), etype2str( type ) ); + // - connectivity + if ( type == SMESH::Entity_Polyhedra || + type == SMESH::Entity_Quad_Polyhedra ) + { + int nbNodes; + ok = proxy().perFaceConnectivity( id, connectivity, nbNodes ); + if ( ok && !connectivity.isEmpty() ) + { + writer->write( tr( "NB_NODES" ), nbNodes ); + writer->write( tr( "CONNECTIVITY" ) ); + writer->indent(); + int nbFaces = connectivity.size(); + for ( int iF = 1; iF <= nbFaces; ++iF ) + { + QString formatted = formatConnectivity( connectivity, -iF ); + writer->write(( type2str( SMDSAbs_Face, 0 ) + " %1 / %2" ).arg( iF ).arg( nbFaces ), + formatted ); + } + writer->unindent(); + } + } + else + { + ok = proxy().elementConnectivity( id, connectivity ); + if ( ok && !connectivity.isEmpty() ) + { + QString formatted = formatConnectivity( connectivity, SMDSAbs_Node ); + if ( !formatted.isEmpty() ) + { + writer->write( tr( "NB_NODES" ), connectivity[ SMDSAbs_Node ].size() ); + writer->write( tr( "CONNECTIVITY" ), formatted ); //todo: TypeRole: ElemConnectivity + } + } + } + // - position + ok = proxy().elementPosition( id, position ); + if ( ok && position.isValid() ) + { + writer->write( tr( "POSITION" ), (stype2str( position.shapeType() ) + " #%1").arg( position.shapeId() ) ); + } + // - gravity center + ok = proxy().elementGravityCenter( id, xyz ); + if ( ok ) + { + writer->write( tr( "GRAVITY_CENTER" ), xyz ); + } + // - normal vector + ok = proxy().elementNormal( id, xyz ); + if ( ok ) + { + writer->write( tr( "NORMAL_VECTOR" ), xyz ); + } + // - controls + bool topCreated = false; + for ( int i = SMESH::FT_AspectRatio; i < SMESH::FT_Undefined; i++ ) + { + QString ctrlTitle = ctrl2str( i ); + if ( ctrlTitle.isEmpty() ) + continue; + if ( !topCreated ) + { + writer->write( tr( "CONTROLS" ) ); + writer->indent(); + topCreated = true; + } + double value; + if ( proxy().elementControl( id, i, cprecision, value ) ) + writer->write( ctrlTitle, value ); + } + if ( topCreated ) + writer->unindent(); + // - groups element belongs to + QList groups = proxy().elementGroups( id ); + topCreated = false; + foreach( SMESH::SelectionProxy group, groups ) + { + if ( group && !group.name().isEmpty() ) + { + if ( !topCreated ) + { + writer->write( SMESHGUI_AddInfo::tr( "GROUPS" ) ); + writer->indent(); + topCreated = true; + } + writer->write( group.name().trimmed() ); // trim name + if ( grp_details ) + { + writer->indent(); + int type = group.type(); + if ( type == SMESH::SelectionProxy::GroupStd ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ); + } + else if ( type == SMESH::SelectionProxy::GroupGeom ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ); + writer->write( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ), group.shapeName() ); + } + else if ( type == SMESH::SelectionProxy::GroupFilter ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ); + } + int size = group.size(); + if ( size != -1 ); + writer->write( SMESHGUI_AddInfo::tr( "SIZE" ), size ); + QColor color = group.color(); + if ( color.isValid() ) + writer->write( SMESHGUI_AddInfo::tr( "COLOR" ), color.name() ); + writer->unindent(); + } + } + } + if ( topCreated ) + writer->unindent(); + writer->unindent(); + } + } +} + +/*! + \fn void SMESHGUI_ElemInfo::information( const QList& ids ) + \brief Show information on given mesh nodes / elements. + + This function has to be redefined in sub-classes. + + \param ids Nodes / elements IDs. */ /*! - \brief Internal clean-up (reset widget) + \brief Internal clean-up (reset panel). + + Default implementation does nothing; the method has to be redefined + in sub-classes to perform internal clean-up. */ void SMESHGUI_ElemInfo::clearInternal() { } /*! - \brief Get node connectivity - \param node mesh node - \return node connectivity map -*/ -SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node ) -{ - Connectivity elmap; - if ( node ) { - SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); - while ( it && it->more() ) { - const SMDS_MeshElement* ne = it->next(); - elmap[ ne->GetType() ] << ne->GetID(); - } - } - return elmap; -} - -/*! - \brief Format connectivity data to string representation - \param connectivity connetivity map - \param type element type - \return string representation of the connectivity -*/ -QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type ) -{ - QStringList str; - if ( connectivity.contains( type )) { - QList elements = connectivity[ type ]; - qSort( elements ); - foreach( int id, elements ) - str << QString::number( id ); - } - return str.join( " " ); -} - -/*! - \brief Calculate gravity center of the mesh element - \param element mesh element -*/ -SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element ) -{ - XYZ xyz; - if ( element ) { - SMDS_ElemIteratorPtr nodeIt = element->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - xyz.add( node->X(), node->Y(), node->Z() ); - } - xyz.divide( element->NbNodes() ); - } - return xyz; -} - -/*! - \brief Calculate normal vector to the mesh face - \param element mesh face -*/ -SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element ) -{ - gp_XYZ n = SMESH::getNormale( SMDS_Mesh::DownCast( element )); - return XYZ(n.X(), n.Y(), n.Z()); -} - -/*! - \brief This slot is called from "Show Previous" button click. - Shows information on the previous group of the items. + \brief Show previous chunk of information. */ void SMESHGUI_ElemInfo::showPrevious() { myIndex = qMax( 0, myIndex-1 ); updateControls(); - information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS )); + information( myIDs.mid( myIndex*blockSize(), blockSize() ) ); } /*! - \brief This slot is called from "Show Next" button click. - Shows information on the next group of the items. + \brief Show next chunk of information. */ void SMESHGUI_ElemInfo::showNext() { - myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS ); + myIndex = qMin( myIndex+1, myIDs.count() / blockSize() ); updateControls(); - information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS )); + information( myIDs.mid( myIndex*blockSize(), blockSize() ) ); } /*! - \brief Update widgets state + \brief Update control widget state. */ void SMESHGUI_ElemInfo::updateControls() { @@ -1156,448 +1997,53 @@ void SMESHGUI_ElemInfo::updateControls() } /*! - \class SMESHGUI_SimpleElemInfo - \brief Represents mesh element information in the simple text area. + \brief Write information from panel to ouput stream. + \param out Text stream output. */ +void SMESHGUI_ElemInfo::saveInfo( QTextStream &out ) +{ + // title + QString title = tr( "ELEM_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + // out << endl; + + // info + StreamWriter writer( out ); + writeInfo( &writer, myIDs ); + out << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_SimpleElemInfo +/// \brief Show mesh element information in the simple text area. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) : SMESHGUI_ElemInfo( parent ) { - myInfo = new QTextBrowser( frame() ); - QVBoxLayout* l = new QVBoxLayout( frame() ); + myInfo = new QTextBrowser( centralWidget() ); + QVBoxLayout* l = new QVBoxLayout( centralWidget() ); l->setMargin( 0 ); l->addWidget( myInfo ); + + connect( myInfo, SIGNAL( anchorClicked(QUrl)), this, SLOT( connectivityClicked( QUrl ))); } /*! - \brief Show mesh element information - \param ids mesh nodes / elements identifiers + \brief Show mesh element information. + \param ids Nodes / elements IDs. */ -void SMESHGUI_SimpleElemInfo::information( const QList& ids ) +void SMESHGUI_SimpleElemInfo::information( const QList& ids ) { clearInternal(); - - if ( actor() ) { - int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); - int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - int cprecision = -1; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) - cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); - foreach ( long id, ids ) { - if ( !isElements() ) { - // - // show node info - // - const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id ); - if ( !node ) return; - - // node ID - myInfo->append( QString( "%1 #%2" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id )); - // separator - myInfo->append( "" ); - // coordinates - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::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( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) ); - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Ball ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con )); - } - else { - myInfo->append( QString( "%1" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id )); - } - // node position - SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMeshPtr )) { - SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id ); - int shapeID = pos->shapeID; - if ( shapeID > 0 ) { - QString shapeType; - double u = 0, v = 0; - switch ( pos->shapeType ) { - case GEOM::EDGE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); - if ( pos->params.length() == 1 ) - u = pos->params[0]; - break; - case GEOM::FACE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); - if ( pos->params.length() == 2 ) { - u = pos->params[0]; - v = pos->params[1]; - } - break; - case GEOM::VERTEX: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); - break; - default: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); - break; - } - // separator - myInfo->append( "" ); - myInfo->append( QString( "%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) ); - myInfo->append( QString( "- %1: #%2" ).arg( shapeType ).arg( shapeID )); - if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) { - myInfo->append( QString( "- %1: #%2" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )). - arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) )); - if ( pos->shapeType == GEOM::FACE ) { - myInfo->append( QString( "- %1: #%2" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )). - arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) )); - } - } - } - } - // groups node belongs to - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - myInfo->append( "" ); // separator - bool top_created = false; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !top_created ) { - myInfo->append( QString( "%1:" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) ); - top_created = true; - } - myInfo->append( QString( "+ %1:" ).arg( aName.trimmed() )); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - if ( !CORBA::is_nil( aStdGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) ); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) ); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - myInfo->append( QString( " - %1: %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() )); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) ); - } - - // size - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )). - arg( QString::number( aGrp->Size() )) ); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )). - arg( QColor( color.R*255., color.G*255., color.B*255. ).name() )); - } - } - } - } - } - else { - // - // show element info - // - const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); - SMESH::Controls::NumericalFunctorPtr afunctor; - if ( !e ) return; - - // Element ID && Type - QString stype; - switch( e->GetType() ) { - case SMDSAbs_0DElement: - stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break; - case SMDSAbs_Ball: - stype = SMESHGUI_ElemInfo::tr( "BALL" ); break; - case SMDSAbs_Edge: - stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break; - case SMDSAbs_Face: - stype = SMESHGUI_ElemInfo::tr( "FACE" ); break; - case SMDSAbs_Volume: - stype = SMESHGUI_ElemInfo::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: - case SMDSEntity_BiQuad_Triangle: - gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break; - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break; - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: - gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break; - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break; - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break; - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break; - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - case SMDSEntity_BiQuad_Penta: - gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break; - case SMDSEntity_Hexagonal_Prism: - gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break; - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: - gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break; - default: - break; - } - if ( !gtype.isEmpty() ) - myInfo->append( QString( "%1: %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype )); - - // Quadratic flag (any element except 0D) - if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) { - myInfo->append( QString( "%1? %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) ); - } - if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast( e )) { - // Ball diameter - myInfo->append( QString( "%1: %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() )); - } - // 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( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() )); - // node coordinates - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::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( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) ); - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con )); - } - else { - myInfo->append( QString( "%1" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id )); - } - } - // separator - myInfo->append( "" ); - - // Controls - myInfo->append( QString( "%1:" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) ); - //Length - if ( e->GetType() == SMDSAbs_Edge ) { - afunctor.reset( new SMESH::Controls::Length() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) ); - } - if( e->GetType() == SMDSAbs_Face ) { - //Area - afunctor.reset( new SMESH::Controls::Area() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Taper - afunctor.reset( new SMESH::Controls::Taper() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //AspectRatio2D - afunctor.reset( new SMESH::Controls::AspectRatio() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Minimum angle - afunctor.reset( new SMESH::Controls::MinimumAngle() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Warping angle - afunctor.reset( new SMESH::Controls::Warping() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Skew - afunctor.reset( new SMESH::Controls::Skew() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //ElemDiam2D - afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) ); - //min edge length - afunctor.reset( new SMESH::Controls::Length2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MIN_ELEM_EDGE" )).arg( afunctor->GetValue( id )) ); - } - if( e->GetType() == SMDSAbs_Volume ) { - //AspectRatio3D - afunctor.reset( new SMESH::Controls::AspectRatio3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Volume - afunctor.reset( new SMESH::Controls::Volume() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //ElementDiameter3D - afunctor.reset( new SMESH::Controls::Volume() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) ); - } - // separator - myInfo->append( "" ); - - // Gravity center - XYZ gc = gravityCenter( e ); - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() )); - - // Normal vector - if( e->GetType() == SMDSAbs_Face ) { - XYZ gc = normal( e ); - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() )); - } - - // Element position - if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ElementPosition pos = aMesh->GetElementPosition( id ); - int shapeID = pos.shapeID; - if ( shapeID > 0 ) { - myInfo->append( "" ); // separator - QString shapeType; - switch ( pos.shapeType ) { - case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break; - case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break; - case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break; - case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break; - case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break; - default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break; - } - myInfo->append( QString( "%1: %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID )); - } - } - } - - // Groups the element belongs to - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - myInfo->append( "" ); // separator - bool top_created = false; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !top_created ) { - myInfo->append( QString( "%1:" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) ); - top_created = true; - } - myInfo->append( QString( "+ %1:" ).arg( aName.trimmed() )); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - if ( !CORBA::is_nil( aStdGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) ); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) ); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - myInfo->append( QString( " - %1: %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() )); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) ); - } - - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )). - arg( QString::number( aGrp->Size() )) ); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )). - arg( QColor( color.R*255., color.G*255., color.B*255. ).name() )); - } - } - } - } - } - // separator - if ( ids.count() > 1 ) { - myInfo->append( "" ); - myInfo->append( "------" ); - myInfo->append( "" ); - } - } - } + TextWriter writer( myInfo ); + writeInfo( &writer, ids ); } /*! @@ -1608,21 +2054,19 @@ void SMESHGUI_SimpleElemInfo::clearInternal() myInfo->clear(); } -void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out ) +void SMESHGUI_SimpleElemInfo::connectivityClicked(const QUrl & url) { - out << QString( 12, '-' ) << "\n"; - out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n"; - out << QString( 12, '-' ) << "\n"; - out << myInfo->toPlainText(); - out << "\n"; + int type = ( url.scheme()[0] == 'n' ) ? NodeConnectivity : ElemConnectivity; + QString ids = url.path(); // excess chars will be filtered off by SMESHGUI_IdValidator + emit( itemInfo( type, ids )); } +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_TreeElemInfo::ItemDelegate +/// \brief Item delegate for tree mesh info widget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// -/*! - \class SMESHGUI_TreeElemInfo::ItemDelegate - \brief Item delegate for tree mesh info widget - \internal -*/ class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate { public: @@ -1631,571 +2075,99 @@ public: }; /*! - \brief Constructor + \brief Constructor. \internal */ -SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent ) +SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ): QItemDelegate( parent ) { } /*! - \brief Create item editor widget + \brief Redefined from QItemDelegate. \internal */ QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index ); - if ( qobject_cast( w )) qobject_cast( w )->setReadOnly( true ); + if ( qobject_cast( w ) ) + qobject_cast( w )->setReadOnly( true ); return w; } -/*! - \class SMESHGUI_TreeElemInfo - \brief Represents mesh element information in the tree-like form. -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_TreeElemInfo::ItemCreator +/// \brief Item creator for tree mesh info widget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class SMESHGUI_TreeElemInfo::ItemCreator : public TreeItemCreator +{ + SMESHGUI_TreeElemInfo* myView; +public: + ItemCreator( SMESHGUI_TreeElemInfo* ); + QTreeWidgetItem* createItem( QTreeWidgetItem*, int ); +}; /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param view Parent view. + \internal +*/ +SMESHGUI_TreeElemInfo::ItemCreator::ItemCreator( SMESHGUI_TreeElemInfo* view ): TreeItemCreator(), myView( view ) +{ +} + +/*! + \brief Create new tree item. + \param parent Parent tree item. + \param options Item options. + \return New tree widget item. + \internal +*/ +QTreeWidgetItem* SMESHGUI_TreeElemInfo::ItemCreator::createItem( QTreeWidgetItem* parent, int options ) +{ + return myView->createItem( parent, options ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_TreeElemInfo +/// \brief Show mesh element information as the tree. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent ) : SMESHGUI_ElemInfo( parent ) { - myInfo = new QTreeWidget( frame() ); + myInfo = new QTreeWidget( centralWidget() ); myInfo->setColumnCount( 2 ); - myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" )); + myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) ); myInfo->header()->setStretchLastSection( true ); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); #else myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); #endif - myInfo->setItemDelegate( new ItemDelegate( myInfo )); - QVBoxLayout* l = new QVBoxLayout( frame() ); + myInfo->setItemDelegate( new ItemDelegate( myInfo ) ); + QVBoxLayout* l = new QVBoxLayout( centralWidget() ); l->setMargin( 0 ); l->addWidget( myInfo ); - connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) ); + connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) ); connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) ); connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) ); } /*! - \brief Show mesh element information - \param ids mesh nodes / elements identifiers + \brief Show mesh element information. + \param ids Nodes / elements IDs. */ -void SMESHGUI_TreeElemInfo::information( const QList& ids ) +void SMESHGUI_TreeElemInfo::information( const QList& ids ) { clearInternal(); - - if ( actor() ) { - int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); - int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - int cprecision = -1; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) - cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); - 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, Bold | All ); - nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" )); - nodeItem->setText( 1, QString( "#%1" ).arg( id )); - // coordinates - QTreeWidgetItem* coordItem = createItem( nodeItem, Bold ); - coordItem->setText( 0, SMESHGUI_ElemInfo::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, SMESHGUI_ElemInfo::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, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Ball ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - } - else { - conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" )); - } - // node position - SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMeshPtr )) { - SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id ); - int shapeID = pos->shapeID; - if ( shapeID > 0 ) { - QString shapeType; - double u = 0, v = 0; - switch ( pos->shapeType ) { - case GEOM::EDGE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); - if ( pos->params.length() == 1 ) - u = pos->params[0]; - break; - case GEOM::FACE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); - if ( pos->params.length() == 2 ) { - u = pos->params[0]; - v = pos->params[1]; - } - break; - case GEOM::VERTEX: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); - break; - default: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); - break; - } - QTreeWidgetItem* posItem = createItem( nodeItem, Bold ); - posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") ); - posItem->setText( 1, (shapeType + " #%1").arg( shapeID )); - if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) { - QTreeWidgetItem* uItem = createItem( posItem ); - uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") ); - uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision ))); - if ( pos->shapeType == GEOM::FACE ) { - QTreeWidgetItem* vItem = createItem( posItem ); - vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") ); - vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision ))); - } - } - } - } - // groups node belongs to - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - QTreeWidgetItem* groupsItem = 0; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !groupsItem ) { - groupsItem = createItem( nodeItem, Bold ); - groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" )); - } - QTreeWidgetItem* it = createItem( groupsItem, Bold ); - it->setText( 0, aName.trimmed() ); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - QTreeWidgetItem* typeItem = createItem( it ); - typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" )); - if ( !CORBA::is_nil( aStdGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::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, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )); - } - - // size - QTreeWidgetItem* sizeItem = createItem( it ); - sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" )); - sizeItem->setText( 1, QString::number( aGrp->Size() )); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - QTreeWidgetItem* colorItem = createItem( it ); - colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" )); - colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) )); - } - } - } - } - } - else { - // - // show element info - // - const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); - SMESH::Controls::NumericalFunctorPtr afunctor; - if ( !e ) return; - - // element ID && type - QString stype; - switch( e->GetType() ) { - case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break; - case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break; - case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break; - case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break; - case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break; - default:; - } - 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: - case SMDSEntity_BiQuad_Triangle: - gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break; - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break; - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: - gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break; - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break; - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break; - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break; - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - case SMDSEntity_BiQuad_Penta: - gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break; - case SMDSEntity_Hexagonal_Prism: - gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break; - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: - gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break; - default: - break; - } - if ( !gtype.isEmpty() ) { - QTreeWidgetItem* typeItem = createItem( elemItem, Bold ); - typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" )); - typeItem->setText( 1, gtype ); - } - // quadratic flag (for edges, faces and volumes) - if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - // quadratic flag - QTreeWidgetItem* quadItem = createItem( elemItem, Bold ); - quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" )); - quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )); - } - if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast< SMDS_BallElement >( e )) { - // ball diameter - QTreeWidgetItem* diamItem = createItem( elemItem, Bold ); - diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )); - diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() )); - } - // connectivity - QTreeWidgetItem* conItem = createItem( elemItem, Bold ); - conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )); - - - if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) { - SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); - for ( int idx = 1; nodeIt->more(); idx++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - nodeInfo( node, idx, e->NbNodes(), conItem ); - } - } - else { - SMDS_NodeIteratorPtr nodeIt = e->nodeIterator(); - std::set< const SMDS_MeshNode* > addedNodes; - QList uniqueNodes; - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = nodeIt->next(); - if ( addedNodes.insert( node ).second ) - uniqueNodes.append( nodeIt->next() ); - } - SMDS_VolumeTool vtool( e ); - const int nbFaces = vtool.NbFaces(); - for( int face_id = 0; face_id < nbFaces; face_id++ ) { - QTreeWidgetItem* faceItem = createItem( conItem, Bold ); - faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces )); - faceItem->setExpanded( true ); - - const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id ); - const int nbNodes = vtool.NbFaceNodes ( face_id ); - for( int node_id = 0; node_id < nbNodes; node_id++ ) { - const SMDS_MeshNode* node = aNodeIds[node_id]; - nodeInfo( node, uniqueNodes.indexOf(node) + 1, uniqueNodes.size(), faceItem ); - } - } - } - //Controls - QTreeWidgetItem* cntrItem = createItem( elemItem, Bold ); - cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" )); - //Length - if( e->GetType()==SMDSAbs_Edge){ - afunctor.reset( new SMESH::Controls::Length() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* lenItem = createItem( cntrItem, Bold ); - lenItem->setText( 0, tr( "LENGTH_EDGES" )); - lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - if( e->GetType() == SMDSAbs_Face ) { - //Area - afunctor.reset( new SMESH::Controls::Area() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* areaItem = createItem( cntrItem, Bold ); - areaItem->setText( 0, tr( "AREA_ELEMENTS" )); - areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) )); - //Taper - if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx - { - afunctor.reset( new SMESH::Controls::Taper() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold ); - taperlItem->setText( 0, tr( "TAPER_ELEMENTS" )); - taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //Warping angle - afunctor.reset( new SMESH::Controls::Warping() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* warpItem = createItem( cntrItem, Bold ); - warpItem->setText( 0, tr( "WARP_ELEMENTS" )); - warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //AspectRatio2D - if ( !e->IsPoly() ) - { - afunctor.reset( new SMESH::Controls::AspectRatio() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold ); - ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" )); - ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //Minimum angle - afunctor.reset( new SMESH::Controls::MinimumAngle() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold ); - minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" )); - minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //Skew - if ( e->NbNodes() == 3 || e->NbNodes() == 4 ) - { - afunctor.reset( new SMESH::Controls::Skew() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* skewItem = createItem( cntrItem, Bold ); - skewItem->setText( 0, tr( "SKEW_ELEMENTS" )); - skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //Deflection - if ( hasShapeToMesh() ) - { - afunctor.reset( new SMESH::Controls::Deflection2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* deflItem = createItem( cntrItem, Bold ); - deflItem->setText( 0, tr( "DEFLECTION_2D" )); - deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //ElemDiam2D - if ( !e->IsPoly() ) - { - afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* diamItem = createItem( cntrItem, Bold ); - diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" )); - diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - } - if( e->GetType() == SMDSAbs_Volume ) { - if ( !e->IsPoly() ) - { - //AspectRatio3D - afunctor.reset( new SMESH::Controls::AspectRatio3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold ); - ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" )); - ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //Volume - afunctor.reset( new SMESH::Controls::Volume() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* volItem = createItem( cntrItem, Bold ); - volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" )); - volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //ElementDiameter3D - afunctor.reset( new SMESH::Controls::MaxElementLength3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold ); - diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" )); - diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - - //min edge length - afunctor.reset( new SMESH::Controls::Length2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold ); - minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" )); - SMESH::Controls::TSequenceOfXYZ points; - afunctor->GetPoints( e, points ); // "non-standard" way, to make it work for all elem types - minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( points )) ); - - // gravity center - XYZ gc = gravityCenter( e ); - QTreeWidgetItem* gcItem = createItem( elemItem, Bold ); - gcItem->setText( 0, SMESHGUI_ElemInfo::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 )) ); - - // normal vector - if( e->GetType() == SMDSAbs_Face ) { - XYZ gc = normal( e ); - QTreeWidgetItem* nItem = createItem( elemItem, Bold ); - nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )); - QTreeWidgetItem* xItem = createItem( nItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* yItem = createItem( nItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* zItem = createItem( nItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - } - - // element position - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - if ( !CORBA::is_nil( aMesh )) { - SMESH::ElementPosition pos = aMesh->GetElementPosition( id ); - int shapeID = pos.shapeID; - if ( shapeID > 0 ) { - QTreeWidgetItem* shItem = createItem( elemItem, Bold ); - QString shapeType; - switch ( pos.shapeType ) { - case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break; - case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break; - case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break; - case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break; - case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break; - default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break; - } - shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" )); - shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID )); - } - } - } - // groups element belongs to - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - QTreeWidgetItem* groupsItem = 0; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !groupsItem ) { - groupsItem = createItem( elemItem, Bold ); - groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" )); - } - QTreeWidgetItem* it = createItem( groupsItem, Bold ); - it->setText( 0, aName.trimmed() ); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - QTreeWidgetItem* typeItem = createItem( it ); - typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" )); - if ( !CORBA::is_nil( aStdGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::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, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )); - } - - // size - QTreeWidgetItem* sizeItem = createItem( it ); - sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" )); - sizeItem->setText( 1, QString::number( aGrp->Size() )); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - QTreeWidgetItem* colorItem = createItem( it ); - colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" )); - colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) )); - } - } - } - } - } - } - } + TreeWriter writer( myInfo, new ItemCreator( this ) ); + writeInfo( &writer, ids ); } /*! @@ -2208,66 +2180,66 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index, int nbNodes, QTreeWidgetItem* parentItem ) { - int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - // node number and ID - QTreeWidgetItem* nodeItem = createItem( parentItem, Bold ); - nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes )); - nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() )); - nodeItem->setData( 1, TypeRole, ElemConnectivity ); - nodeItem->setData( 1, IdRole, node->GetID() ); - nodeItem->setExpanded( false ); - // node coordinates - QTreeWidgetItem* coordItem = createItem( nodeItem ); - coordItem->setText( 0, SMESHGUI_ElemInfo::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, SMESHGUI_ElemInfo::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, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Ball ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - } + // int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + // // node number and ID + // QTreeWidgetItem* nodeItem = createItem( parentItem, Bold ); + // nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes )); + // nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() )); + // nodeItem->setData( 1, TypeRole, ElemConnectivity ); + // nodeItem->setData( 1, IdRole, node->GetID() ); + // nodeItem->setExpanded( false ); + // // node coordinates + // QTreeWidgetItem* coordItem = createItem( nodeItem ); + // coordItem->setText( 0, SMESHGUI_ElemInfo::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, SMESHGUI_ElemInfo::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, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )); + // i->setText( 1, con ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Edge ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Ball ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Face ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Volume ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // } } /*! \brief Internal clean-up (reset widget) @@ -2279,35 +2251,22 @@ void SMESHGUI_TreeElemInfo::clearInternal() } /*! - \brief Create new tree item. - \param parent parent tree widget item - \param flags item flag - \return new tree widget item + \brief Create new item and add it to the tree. + \param parent Parent tree widget item. Defaults to 0 (top-level item). + \param options Item flags. Defaults to 0 (none). + \return New tree widget item. */ -QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags ) +QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int options ) { - QTreeWidgetItem* item; - if ( parent ) - item = new QTreeWidgetItem( parent ); - else - item = new QTreeWidgetItem( myInfo ); - - item->setFlags( item->flags() | Qt::ItemIsEditable ); - - QFont f = item->font( 0 ); - f.setBold( true ); - for ( int i = 0; i < myInfo->columnCount(); i++ ) { - if ( ( flags & Bold ) && ( i == 0 || flags & All )) - item->setFont( i, f ); - } + QTreeWidgetItem* item = new QTreeWidgetItem( parent ? parent : myInfo->invisibleRootItem() ); + setTreeItemAttributes( item, options | Expanded | Editable ); if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 ) { QString resName = expandedResource( parent ); parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true )); } - - item->setExpanded( true ); + return item; } @@ -2317,24 +2276,21 @@ void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e ) if ( widgets.isEmpty() ) return; QTreeWidgetItem* aTreeItem = widgets.first(); int type = aTreeItem->data( 1, TypeRole ).toInt(); - int id = aTreeItem->data( 1, IdRole ).toInt(); - QMenu menu; - QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" )); - if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a ) - emit( itemInfo( id )); - else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a ) - emit( itemInfo( aTreeItem->text( 1 )) ); + if (( type == ElemConnectivity || type == NodeConnectivity ) && + ( !aTreeItem->text( 1 ).isEmpty() )) + { + QMenu menu; + QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" )); + if ( menu.exec( e->globalPos() ) == a ) + emit( itemInfo( type, aTreeItem->text( 1 )) ); + } } void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn ) { if ( theItem ) { int type = theItem->data( 1, TypeRole ).toInt(); - int id = theItem->data( 1, IdRole ).toInt(); - if ( type == ElemConnectivity && id > 0 ) - emit( itemInfo( id )); - else if ( type == NodeConnectivity ) - emit( itemInfo( theItem->text( 1 )) ); + emit( itemInfo( type, theItem->text( 1 )) ); } } @@ -2346,482 +2302,527 @@ void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem ) QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem ) { - return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0); + return QString("Expanded_") + ( what()==ShowElements ? "E_" : "N_" ) + theItem->text(0); } -void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out ) -{ - out << QString( 12, '-' ) << "\n"; - out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n"; - out << QString( 12, '-' ) << "\n"; - - QTreeWidgetItemIterator it( myInfo ); - while ( *it ) { - if ( !( *it )->text(0).isEmpty() ) { - out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0); - if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1); - out << "\n"; - } - ++it; - } - out << "\n"; -} +//////////////////////////////////////////////////////////////////////////////// +/// \class InfoComputor +/// \brief Mesh information computor. +/// \internal +/// +/// The class is created for different computation operations. Currently it is +/// used to compute size and number of underlying nodes for given group. +//////////////////////////////////////////////////////////////////////////////// /*! - \class GrpComputor - \brief Mesh information computer + \brief Constructor. + \param parent Parent object. + \param proxy Object to compute information on (group). + \param item Tree widget item, referenced by this computer. + \param operation Value to compute. \internal - - The class is created for different computation operation. Currently it is used - to compute number of underlying nodes for the groups. */ - -/*! - \brief Constructor -*/ -GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, - QTreeWidgetItem* item, - QObject* parent, - bool toComputeSize) - : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize ) +InfoComputor::InfoComputor( QObject* parent, const SMESH::SelectionProxy& proxy, int operation ) + : QObject( parent ), myProxy( proxy ), myOperation( operation ) { - myGroup = SMESH::SMESH_GroupBase::_narrow( grp ); } /*! - \brief Compute function + \brief Compute requested information. + \internal */ -void GrpComputor::compute() +void InfoComputor::compute() { - if ( !CORBA::is_nil( myGroup ) && myItem ) { + if ( myProxy ) + { SUIT_OverrideCursor wc; - QTreeWidgetItem* item = myItem; - myItem = 0; - int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes(); - item->treeWidget()->removeItemWidget( item, 1 ); - item->setText( 1, QString::number( nb )); + switch ( myOperation ) + { + case GrpSize: + myProxy.size( true ); // force size computation + emit computed(); + break; + case GrpNbNodes: + myProxy.nbNodes( true ); // force size computation + emit computed(); + break; + default: + break; + } } } -/*! - \class SMESHGUI_AddInfo - \brief The wigdet shows additional information on the mesh object. -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_AddInfo +/// \brief Show additional information on selected object. +/// +/// Displays an additional information about selected object: mesh, sub-mesh +/// or group. +/// +/// \todo Rewrite saveInfo() method to print all data, not currently shown only. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ) - : QTreeWidget( parent ) +SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ): SMESHGUI_Info( parent ) { - setColumnCount( 2 ); - header()->setStretchLastSection( true ); + QVBoxLayout* l = new QVBoxLayout( this ); + l->setMargin( 0 ); + l->setSpacing( SPACING ); + + myTree = new QTreeWidget( this ); + + myTree->setColumnCount( 2 ); + myTree->header()->setStretchLastSection( true ); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - header()->setResizeMode( 0, QHeaderView::ResizeToContents ); + myTree->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); #else - header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); + myTree->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); #endif - header()->hide(); + myTree->header()->hide(); + + l->addWidget( myTree ); } /*! - \brief Destructor + \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) + \brief Show information on given object. + \param proxy Object to show information on (mesh, sub-mesh, group). */ -void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +void SMESHGUI_AddInfo::showInfo( const SMESH::SelectionProxy& proxy ) { + // reset panel setProperty( "group_index", 0 ); setProperty( "submesh_index", 0 ); myComputors.clear(); - clear(); + myTree->clear(); - if ( CORBA::is_nil( obj )) return; + // then fill panel with data if object is not null + if ( proxy ) + { + myProxy = proxy; - _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); - if ( !sobj ) return; + // name + QTreeWidgetItem* nameItem = createItem( 0, Bold | AllColumns ); + nameItem->setText( 0, tr( "NAME" ) ); + nameItem->setText( 1, proxy.name() ); - // 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 ); + // object info + if ( proxy.type() == SMESH::SelectionProxy::Mesh ) + meshInfo( proxy, nameItem ); + else if ( proxy.type() == SMESH::SelectionProxy::Submesh ) + subMeshInfo( proxy, nameItem ); + else if ( proxy.type() >= SMESH::SelectionProxy::Group ) + groupInfo( proxy, nameItem ); + } } /*! - \brief Create new tree item. - \param parent parent tree widget item - \param flags item flag - \return new tree widget item + \brief Update information in panel. */ -QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags ) +void SMESHGUI_AddInfo::updateInfo() { - QTreeWidgetItem* item; + showInfo( myProxy ); +} - if ( parent ) - item = new QTreeWidgetItem( parent ); - else - item = new QTreeWidgetItem( this ); +/*! + \brief Reset panel (clear all data). +*/ +void SMESHGUI_AddInfo::clear() +{ + myTree->clear(); +} - //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 ); +/*! + \brief Create new item and add it to the tree. + \param parent Parent tree widget item. Defaults to 0 (top-level item). + \param options Item flags. Defaults to 0 (none). + \return New tree widget item. +*/ +QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int options ) +{ + QTreeWidgetItem* item = parent ? new QTreeWidgetItem( parent ) : + new QTreeWidgetItem( myTree->invisibleRootItem() ); + setTreeItemAttributes( item, options | Expanded ); return item; } /*! - \brief Show mesh info - \param mesh mesh object - \param parent parent tree item + \brief Show information on mesh. + \param proxy Proxy object (mesh). + \param parent Parent tree item. */ -void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent ) +void SMESHGUI_AddInfo::meshInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent ) { + if ( !proxy ) + return; + + QString shapeName = proxy.shapeName(); + SMESH::MedInfo inf = proxy.medFileInfo(); + // type - GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh(); - SMESH::MedFileInfo_var 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() ); - } + typeItem->setText( 0, tr( "TYPE" ) ); + if ( !shapeName.isEmpty() ) + { + typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) ); + // shape + QTreeWidgetItem* gobjItem = createItem( parent, Bold ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, shapeName ); } - 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 if ( inf.isValid() ) + { + typeItem->setText( 1, tr( "MESH_FROM_FILE" ) ); + // med file information + QTreeWidgetItem* fileItem = createItem( parent, Bold ); + fileItem->setText( 0, tr( "FILE_NAME" ) ); + fileItem->setText( 1, inf.fileName() ); + QTreeWidgetItem* sizeItem = createItem( parent, Bold ); + sizeItem->setText( 0, tr( "FILE_SIZE" ) ); + sizeItem->setText( 1, QString::number( inf.size() ) ); + QTreeWidgetItem* versionItem = createItem( parent, Bold ); + versionItem->setText( 0, tr( "FILE_VERSION" ) ); + versionItem->setText( 1, inf.version() != "0" ? inf.version() : tr( "VERSION_UNKNOWN" ) ); } - else { - typeItem->setText( 1, tr( "STANDALONE_MESH" )); + else + { + typeItem->setText( 1, tr( "STANDALONE_MESH" ) ); } // groups - myGroups = mesh->GetGroups(); + myGroups = proxy.groups(); showGroups(); // sub-meshes - mySubMeshes = mesh->GetSubMeshes(); + mySubMeshes = proxy.submeshes(); showSubMeshes(); } /*! - \brief Show sub-mesh info - \param subMesh sub-mesh object - \param parent parent tree item + \brief Show information on sub-mesh. + \param proxy Proxy object (sub-mesh). + \param parent Parent tree item. */ -void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent ) +void SMESHGUI_AddInfo::subMeshInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent ) { + if ( !proxy ) + return; + bool isShort = parent->parent() != 0; - if ( !isShort ) { + if ( !isShort ) + { // parent mesh - _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() ); - if ( sobj ) { + SMESH::SelectionProxy meshProxy = proxy.mesh(); + if ( meshProxy ) + { QTreeWidgetItem* nameItem = createItem( parent, Bold ); - nameItem->setText( 0, tr( "PARENT_MESH" )); - nameItem->setText( 1, sobj->GetName().c_str() ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, meshProxy.name() ); } } // shape - GEOM::GEOM_Object_var gobj = subMesh->GetSubShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { + QString shapeName = proxy.shapeName(); + if ( !shapeName.isEmpty() ) + { QTreeWidgetItem* gobjItem = createItem( parent, Bold ); - gobjItem->setText( 0, tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); + gobjItem->setText( 1, shapeName ); } } /*! - \brief Show group info - \param grp mesh group object - \param parent parent tree item + \brief Show information on group. + \param proxy Proxy object (group). + \param parent Parent tree item. */ -void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent ) +void SMESHGUI_AddInfo::groupInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent ) { + if ( !proxy ) + return; + 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 ) { + if ( !isShort ) + { // parent mesh - _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() ); - if ( sobj ) { + SMESH::SelectionProxy meshProxy = proxy.mesh(); + if ( meshProxy ) + { QTreeWidgetItem* nameItem = createItem( parent, Bold ); - nameItem->setText( 0, tr( "PARENT_MESH" )); - nameItem->setText( 1, sobj->GetName().c_str() ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, meshProxy.name() ); } } - // type : group on geometry, standalone group, group on filter + // type + SMESH::SelectionProxy::Type type = proxy.type(); QTreeWidgetItem* typeItem = createItem( parent, Bold ); - typeItem->setText( 0, tr( "TYPE" )); - if ( !CORBA::is_nil( aStdGroup )) { - typeItem->setText( 1, tr( "STANDALONE_GROUP" )); + typeItem->setText( 0, tr( "TYPE" ) ); + if ( type == SMESH::SelectionProxy::GroupStd ) + { + 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 ( type == SMESH::SelectionProxy::GroupGeom ) + { + typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) ); + // shape + QTreeWidgetItem* gobjItem = createItem( parent, Bold ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, proxy.shapeName() ); } - else if ( !CORBA::is_nil( aFltGroup )) { - typeItem->setText( 1, tr( "GROUP_ON_FILTER" )); + else if ( type == SMESH::SelectionProxy::GroupFilter ) + { + typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) ); } - if ( !isShort ) { - // entity type - QString etype = tr( "UNKNOWN" ); - switch( grp->GetType() ) { + // element type + int etype = proxy.groupElementType(); + if ( !isShort ) + { + QString typeName = tr( "UNKNOWN" ); + switch( etype ) + { case SMESH::NODE: - etype = tr( "NODE" ); + typeName = tr( "NODE" ); break; case SMESH::EDGE: - etype = tr( "EDGE" ); + typeName = tr( "EDGE" ); break; case SMESH::FACE: - etype = tr( "FACE" ); + typeName = tr( "FACE" ); break; case SMESH::VOLUME: - etype = tr( "VOLUME" ); + typeName = tr( "VOLUME" ); break; case SMESH::ELEM0D: - etype = tr( "0DELEM" ); + typeName = tr( "0DELEM" ); break; case SMESH::BALL: - etype = tr( "BALL" ); + typeName = tr( "BALL" ); break; default: break; } QTreeWidgetItem* etypeItem = createItem( parent, Bold ); - etypeItem->setText( 0, tr( "ENTITY_TYPE" )); - etypeItem->setText( 1, etype ); + etypeItem->setText( 0, tr( "ENTITY_TYPE" ) ); + etypeItem->setText( 1, typeName ); } - SMESH::SMESH_Mesh_var mesh = grp->GetMesh(); - bool meshLoaded = mesh->IsLoaded(); - - // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831 - int groupSize = -1; - if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup )) - groupSize = grp->Size(); + // size + // note: size is not computed for group on filter for performance reasons, see IPAL52831 + bool meshLoaded = proxy.isMeshLoaded(); + int size = proxy.size(); QTreeWidgetItem* sizeItem = createItem( parent, Bold ); - sizeItem->setText( 0, tr( "SIZE" )); - if ( groupSize > -1 ) { - sizeItem->setText( 1, QString::number( groupSize )); + sizeItem->setText( 0, tr( "SIZE" ) ); + if ( size >= 0 ) + { + sizeItem->setText( 1, QString::number( size ) ); } - else { - QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this ); - setItemWidget( sizeItem, 1, btn ); - GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true ); - connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() )); + else + { + QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this ); + myTree->setItemWidget( sizeItem, 1, btn ); + InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpSize ); + connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) ); + connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) ); myComputors.append( comp ); - if ( !meshLoaded ) - connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() )); } // 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.) )); + colorItem->setText( 0, tr( "COLOR" ) ); + colorItem->setBackground( 1, proxy.color() ); // nb of underlying nodes - if ( grp->GetType() != SMESH::NODE) { + if ( etype != SMESH::NODE ) + { QTreeWidgetItem* nodesItem = createItem( parent, Bold ); - nodesItem->setText( 0, tr( "NB_NODES" )); - int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 ); - bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false; - if ( toShowNodes && meshLoaded ) { - // already calculated and up-to-date - nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() )); + nodesItem->setText( 0, tr( "NB_NODES" ) ); + + int nbNodes = proxy.nbNodes(); + if ( nbNodes >= 0 ) + { + nodesItem->setText( 1, QString::number( nbNodes ) ); } - 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() )); + else + { + QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this ); + myTree->setItemWidget( nodesItem, 1, btn ); + InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpNbNodes ); + connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) ); + connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) ); myComputors.append( comp ); - if ( !meshLoaded ) - connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() )); } } } -void SMESHGUI_AddInfo::showGroups() -{ - myComputors.clear(); - - QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item - if ( !parent ) return; - - int idx = property( "group_index" ).toInt(); - - QTreeWidgetItem* itemGroups = 0; - for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) { - if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) { - itemGroups = parent->child( i ); - ExtraWidget* extra = dynamic_cast( itemWidget( itemGroups, 1 )); - if ( extra ) - extra->updateControls( myGroups->length(), idx ); - while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items - } - } - - QMap grpItems; - for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) { - SMESH::SMESH_GroupBase_var grp = myGroups[i]; - if ( CORBA::is_nil( grp )) continue; - _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp ); - if ( !grpSObj ) continue; - - int grpType = grp->GetType(); - - if ( !itemGroups ) { - // create top-level groups container item - itemGroups = createItem( parent, Bold | All ); - itemGroups->setText( 0, tr( "GROUPS" )); - itemGroups->setData( 0, Qt::UserRole, GROUPS_ID ); - - // total number of groups > 10, show extra widgets for info browsing - if ((int) myGroups->length() > MAXITEMS ) { - ExtraWidget* extra = new ExtraWidget( this, true ); - connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() )); - connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() )); - setItemWidget( itemGroups, 1, extra ); - extra->updateControls( myGroups->length(), idx ); - } - } - - 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, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed - - // group info - groupInfo( grp.in(), grpNameItem ); - } -} - -void SMESHGUI_AddInfo::showSubMeshes() -{ - QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item - if ( !parent ) return; - - int idx = property( "submesh_index" ).toInt(); - - QTreeWidgetItem* itemSubMeshes = 0; - for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) { - if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) { - itemSubMeshes = parent->child( i ); - ExtraWidget* extra = dynamic_cast( itemWidget( itemSubMeshes, 1 )); - if ( extra ) - extra->updateControls( mySubMeshes->length(), idx ); - while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items - } - } - - QMap smItems; - for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) { - SMESH::SMESH_subMesh_var sm = mySubMeshes[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" )); - itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID ); - - // total number of sub-meshes > 10, show extra widgets for info browsing - if ((int) mySubMeshes->length() > MAXITEMS ) { - ExtraWidget* extra = new ExtraWidget( this, true ); - connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() )); - connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() )); - setItemWidget( itemSubMeshes, 1, extra ); - extra->updateControls( mySubMeshes->length(), idx ); - } - } - - 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, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed - - // submesh info - subMeshInfo( sm.in(), smNameItem ); - } -} - /*! - * \brief Change button label of "nb underlying node" group from "Load" to "Compute" - */ -void SMESHGUI_AddInfo::changeLoadToCompute() + \brief Update information on child groups. +*/ +void SMESHGUI_AddInfo::showGroups() { - for ( int i = 0; i < myComputors.count(); ++i ) + // remove all computors + myComputors.clear(); + + // tree root should be the first top level item + QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0; + if ( !parent ) + return; + + int idx = property( "group_index" ).toInt(); + + // find sub-meshes top-level container item + QTreeWidgetItem* itemGroups = 0; + for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) { - if ( QTreeWidgetItem* item = myComputors[i]->getItem() ) + if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GroupsId ) { - if ( QPushButton* btn = qobject_cast( itemWidget ( item, 1 )) ) - btn->setText( tr("COMPUTE") ); + itemGroups = parent->child( i ); + // update controls + ExtraWidget* extra = dynamic_cast( myTree->itemWidget( itemGroups, 1 ) ); + if ( extra ) + extra->updateControls( myGroups.count(), idx ); + // clear: remove all group items + while ( itemGroups->childCount() ) + delete itemGroups->child( 0 ); } } + + QMap grpItems; + for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), (int)myGroups.count() ); i++ ) + { + SMESH::SelectionProxy grp = myGroups[i]; + if ( !grp ) + continue; + + int grpType = grp.groupElementType(); + + // create top-level groups container item if it does not exist + if ( !itemGroups ) + { + itemGroups = createItem( parent, Bold | AllColumns ); + itemGroups->setText( 0, tr( "GROUPS" ) ); + itemGroups->setData( 0, Qt::UserRole, GroupsId ); + + // if necessary, create extra widget to show information by chunks + if ( myGroups.count() > blockSize() ) + { + ExtraWidget* extra = new ExtraWidget( this, true ); + connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) ); + connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) ); + myTree->setItemWidget( itemGroups, 1, extra ); + extra->updateControls( myGroups.count(), idx ); + } + } + + // create container item corresponding to particular element type + if ( !grpItems.contains( grpType ) ) + { + grpItems[ grpType ] = createItem( itemGroups, Bold | AllColumns ); + grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) ); + itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); // -1 needed since 0 corresponds to SMESH::ALL + } + + // name + QTreeWidgetItem* nameItem = createItem( grpItems[ grpType ] ); + nameItem->setText( 0, grp.name().trimmed() ); // trim name + + // group info + groupInfo( grp, nameItem ); + } } +/*! + \brief Update information on child sub-meshes. +*/ +void SMESHGUI_AddInfo::showSubMeshes() +{ + // tree root should be the first top level item + QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0; + if ( !parent ) + return; + + int idx = property( "submesh_index" ).toInt(); + + // find sub-meshes top-level container item + QTreeWidgetItem* itemSubMeshes = 0; + for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) + { + if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SubMeshesId ) + { + itemSubMeshes = parent->child( i ); + // update controls + ExtraWidget* extra = dynamic_cast( myTree->itemWidget( itemSubMeshes, 1 ) ); + if ( extra ) + extra->updateControls( mySubMeshes.count(), idx ); + // clear: remove all sub-mesh items + while ( itemSubMeshes->childCount() ) + delete itemSubMeshes->child( 0 ); + } + } + + QMap smItems; + for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), mySubMeshes.count() ); i++ ) + { + SMESH::SelectionProxy sm = mySubMeshes[i]; + if ( !sm ) + continue; + + int smType = sm.shapeType(); + if ( smType < 0 ) + continue; + else if ( smType == GEOM::COMPSOLID ) + smType = GEOM::COMPOUND; + + // create top-level sub-meshes container item if it does not exist + if ( !itemSubMeshes ) + { + itemSubMeshes = createItem( parent, Bold | AllColumns ); + itemSubMeshes->setText( 0, tr( "SUBMESHES" ) ); + itemSubMeshes->setData( 0, Qt::UserRole, SubMeshesId ); + + // if necessary, create extra widget to show information by chunks + if ( mySubMeshes.count() > blockSize() ) + { + ExtraWidget* extra = new ExtraWidget( this, true ); + connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) ); + connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) ); + myTree->setItemWidget( itemSubMeshes, 1, extra ); + extra->updateControls( mySubMeshes.count(), idx ); + } + } + + // create container item corresponding to particular shape type + if ( !smItems.contains( smType ) ) + { + smItems[ smType ] = createItem( itemSubMeshes, Bold | AllColumns ); + smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) ); + itemSubMeshes->insertChild( smType, smItems[ smType ] ); + } + + // name + QTreeWidgetItem* nameItem = createItem( smItems[ smType ] ); + nameItem->setText( 0, sm.name().trimmed() ); // trim name + + // submesh info + subMeshInfo( sm, nameItem ); + } +} + +/*! + \brief Show previous chunk of information on child groups. +*/ void SMESHGUI_AddInfo::showPreviousGroups() { int idx = property( "group_index" ).toInt(); @@ -2829,6 +2830,9 @@ void SMESHGUI_AddInfo::showPreviousGroups() showGroups(); } +/*! + \brief Show next chunk of information on child groups. +*/ void SMESHGUI_AddInfo::showNextGroups() { int idx = property( "group_index" ).toInt(); @@ -2836,6 +2840,9 @@ void SMESHGUI_AddInfo::showNextGroups() showGroups(); } +/*! + \brief Show previous chunk of information on child sub-meshes. +*/ void SMESHGUI_AddInfo::showPreviousSubMeshes() { int idx = property( "submesh_index" ).toInt(); @@ -2843,6 +2850,9 @@ void SMESHGUI_AddInfo::showPreviousSubMeshes() showSubMeshes(); } +/*! + \brief Show next chunk of information on child sub-meshes. +*/ void SMESHGUI_AddInfo::showNextSubMeshes() { int idx = property( "submesh_index" ).toInt(); @@ -2850,50 +2860,161 @@ void SMESHGUI_AddInfo::showNextSubMeshes() showSubMeshes(); } +/*! + \brief Write information from panel to ouput stream. + \param out Text stream output. +*/ void SMESHGUI_AddInfo::saveInfo( QTextStream &out ) { - out << QString( 15, '-') << "\n"; - out << tr( "ADDITIONAL_INFO" ) << "\n"; - out << QString( 15, '-' ) << "\n"; - QTreeWidgetItemIterator it( this ); - while ( *it ) { - if ( !( ( *it )->text(0) ).isEmpty() ) { - out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0); - if ( ( *it )->text(0) == tr( "COLOR" )) { - out << ": " << ( ( ( *it )->background(1) ).color() ).name(); - } - else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1); - out << "\n"; + // title + QString title = tr( "ADDITIONAL_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + out << endl; + + // info + QTreeWidgetItemIterator it( myTree ); + while ( *it ) + { + if ( !( ( *it )->text(0) ).isEmpty() ) + { + out << indent( itemDepth( *it ) ) << ( *it )->text(0); + if ( ( *it )->text(0) == tr( "COLOR" ) ) + out << ":" << spacing() << ( ( ( *it )->background(1) ).color() ).name(); + else if ( !( ( *it )->text(1) ).isEmpty() ) + out << ":" << spacing() << ( *it )->text(1); + out << endl; } ++it; } - out << "\n"; + out << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class GroupCombo +/// \brief Customized combo box to manage list of mesh groups. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class GroupCombo: public QComboBox +{ + class Item: public QStandardItem + { + public: + SMESH::SelectionProxy myGroup; + Item( const SMESH::SelectionProxy& group ) + { + myGroup = group; + setText( myGroup.name() ); + } + SMESH::SelectionProxy group() + { + return myGroup; + } + }; + + SMESH::SelectionProxy myProxy; + +public: + GroupCombo( QWidget* ); + void setSource( const SMESH::SelectionProxy& ); + SMESH::SelectionProxy currentGroup() const; +}; + +/*! + \brief Contructor. + \param parent Parent widget. + \internal +*/ +GroupCombo::GroupCombo( QWidget* parent ): QComboBox( parent ) +{ + setModel( new QStandardItemModel( this ) ); } /*! - \class SMESHGUI_MeshInfoDlg - \brief Mesh information dialog box + \brief Set mesh source. + \param obj Mesh source. + \internal */ +void GroupCombo::setSource( const SMESH::SelectionProxy& proxy ) +{ + if ( myProxy == proxy ) + return; + + myProxy = proxy; + + bool blocked = blockSignals( true ); + QStandardItemModel* m = dynamic_cast( model() ); + m->clear(); + + if ( myProxy ) + { + if ( myProxy.type() == SMESH::SelectionProxy::Mesh ) + { + QList groups = myProxy.groups(); + for ( int i = 0; i < groups.count(); ++i ) + { + if ( groups[i] ) + { + QString name = groups[i].name(); + if ( !name.isEmpty() ) + m->appendRow( new Item( groups[i] ) ); + } + } + setCurrentIndex( -1 ); // for performance reasons + } + else if ( myProxy.type() >= SMESH::SelectionProxy::Group ) + { + m->appendRow( new Item( myProxy ) ); + setCurrentIndex( 0 ); + } + } + + blockSignals( blocked ); +} + +/*! + \brief Get currently selected group. + \return Selected group. + \internal +*/ +SMESH::SelectionProxy GroupCombo::currentGroup() const +{ + SMESH::SelectionProxy group; + QStandardItemModel* m = dynamic_cast( model() ); + if ( currentIndex() >= 0 ) + group = dynamic_cast( m->item( currentIndex() ) )->group(); + return group; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_MeshInfoDlg +/// \brief Mesh information dialog box +/// +/// \todo Move all business logic for element info to SMESHGUI_ElemInfo class. +/// \todo Add selection button to reactivate selection on move from other dlg. +//////////////////////////////////////////////////////////////////////////////// /*! \brief Constructor - \param parent parent widget - \param page specifies the dialog page to be shown at the start-up + \param parent Parent widget. + \param page Dialog page to show at start-up. Defaults to \c BaseInfo. */ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) - : QDialog( parent ), myActor( 0 ) + : QDialog( parent ) { setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); - setWindowTitle( tr( "MESH_INFO" )); + setWindowTitle( tr( "MESH_INFO" ) ); setSizeGripEnabled( true ); myTabWidget = new QTabWidget( this ); // base info - myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget ); - myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" )); + myBaseInfo = new SMESHGUI_BaseInfo( myTabWidget ); + myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) ); // elem info @@ -2902,40 +3023,47 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) myMode = new QButtonGroup( this ); myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode ); myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode ); + myMode->addButton( new QRadioButton( tr( "GROUP_MODE" ), w ), GroupMode ); myMode->button( NodeMode )->setChecked( true ); myID = new QLineEdit( w ); - myID->setValidator( new SMESHGUI_IdValidator( this )); + myID->setValidator( new SMESHGUI_IdValidator( this ) ); + myGroups = new GroupCombo( w ); + QStackedWidget* stack = new QStackedWidget( w ); + stack->addWidget( myID ); + stack->addWidget( myGroups ); myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w ); - myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() )); + myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ) ); int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 ); - mode = qMin( 1, qMax( 0, mode )); + mode = qMin( 1, qMax( 0, mode ) ); if ( mode == 0 ) myElemInfo = new SMESHGUI_SimpleElemInfo( w ); else myElemInfo = new SMESHGUI_TreeElemInfo( w ); + stack->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ); QGridLayout* elemLayout = new QGridLayout( w ); elemLayout->setMargin( MARGIN ); elemLayout->setSpacing( SPACING ); elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 ); elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 ); - elemLayout->addWidget( myID, 0, 2 ); - elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 ); - elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 ); + elemLayout->addWidget( myMode->button( GroupMode ), 0, 2 ); + elemLayout->addWidget( stack, 0, 3 ); + elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 4 ); + elemLayout->addWidget( myElemInfo, 2, 0, 1, 4 ); - myTabWidget->addTab( w, tr( "ELEM_INFO" )); + myTabWidget->addTab( w, tr( "ELEM_INFO" ) ); // additional info myAddInfo = new SMESHGUI_AddInfo( myTabWidget ); - myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" )); + myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) ); // controls info myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget ); - myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" )); + myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) ); // buttons @@ -2957,33 +3085,41 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) btnLayout->addStretch( 10 ); btnLayout->addWidget( helpBtn ); + // arrange widgets + QVBoxLayout* l = new QVBoxLayout ( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); l->addWidget( myTabWidget ); l->addLayout( btnLayout ); - myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ))); + // set initial page - connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() )); - connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() )); - connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() )); - connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() )); - connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() )); - connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() )); - connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() )); - connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int ))); - connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString ))); + myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) ); - myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false )); + // set-up connections + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); + connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) ); + connect( myGroups, SIGNAL( currentIndexChanged( int ) ), this, SLOT( modeChanged() ) ); + connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) ); + connect( myIDPreviewCheck, SIGNAL( toggled( bool ) ), this, SLOT( idPreviewChange( bool ) ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); + connect( myElemInfo, SIGNAL( itemInfo( int, QString ) ), this, SLOT( showItemInfo( int, QString ) ) ); + connect( this, SIGNAL( switchMode( int ) ), stack, SLOT( setCurrentIndex( int ) ) ); + + // initialize + + myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "id_preview_resource", false ) ); updateSelection(); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() { @@ -2991,66 +3127,105 @@ SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() } /*! - \brief Show mesh information - \param IO interactive object + \brief Show mesh information on given object. + \param io Interactive object. */ -void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) +void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io ) { - if ( !IO.IsNull() ) - myIO = IO; + if ( !io.IsNull() ) + showInfo( SMESH::SelectionProxy( io ) ); +} - SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); - if ( !CORBA::is_nil( obj )) - { - myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo, - myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871) - if ( myTabWidget->currentIndex() == CtrlInfo ) - myCtrlInfo->showInfo( obj ); +/*! + \brief Show mesh information on given object. + \param proxy Selection proxy. +*/ +void SMESHGUI_MeshInfoDlg::showInfo( const SMESH::SelectionProxy& proxy ) +{ + SUIT_OverrideCursor wc; - { - myActor = SMESH::FindActorByEntry( IO->getEntry() ); - SVTK_Selector* selector = SMESH::GetSelector(); - QString ID; - int nb = 0; - if ( myActor && selector ) { - nb = myMode->checkedId() == NodeMode ? - SMESH::GetNameOfSelectedElements( selector, IO, ID ) : - SMESH::GetNameOfSelectedNodes( selector, IO, ID ); - } - myElemInfo->setSource( myActor, obj ) ; - if ( nb > 0 ) { - myID->setText( ID.trimmed() ); - QSet ids; - QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); - foreach ( ID, idTxt ) - ids << ID.trimmed().toLong(); - myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); - } - else { - myID->clear(); - myElemInfo->clear(); - } + if ( !proxy ) + return; + + myProxy = proxy; + + SMESH::SMESH_IDSource_var obj = myProxy.object(); + + // "Base info" tab + myBaseInfo->showInfo( proxy ); + + // "Additional info" tab + myAddInfo->showInfo( proxy ); + + // "Quality info" tab + // Note: for performance reasons we update it only if it is currently active + if ( myTabWidget->currentIndex() == CtrlInfo ) + myCtrlInfo->showInfo( proxy ); + + // "Element info" tab + myGroups->setSource( proxy ); + if ( myMode->checkedId() == GroupMode ) { + SMESH::SelectionProxy group = myGroups->currentGroup(); + if ( group ) + myElemInfo->showInfo( group ); + else + myElemInfo->clear(); + } + else { + SVTK_Selector* selector = SMESH::GetSelector(); + QString ID; + int nb = 0; + if ( myProxy.actor() && selector ) { //todo: actor()? + nb = myMode->checkedId() == NodeMode ? + SMESH::GetNameOfSelectedElements( selector, myProxy.io(), ID ) : + SMESH::GetNameOfSelectedNodes( selector, myProxy.io(), ID ); + } + if ( nb > 0 ) { + myID->setText( ID.trimmed() ); + QSet ids; + QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); + foreach ( ID, idTxt ) + ids << ID.trimmed().toUInt(); + myElemInfo->showInfo( proxy, ids, myMode->checkedId() == ElemMode ); + } + else { + myID->clear(); + myElemInfo->clear(); } } } /*! - \brief Perform clean-up actions on the dialog box closing. + \brief Update information. +*/ +void SMESHGUI_MeshInfoDlg::updateInfo() +{ + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) + showInfo( selected.First() ); + else + showInfo( myProxy ); +} + +/*! + \brief Clean-up on dialog closing. */ void SMESHGUI_MeshInfoDlg::reject() { LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); selMgr->clearFilters(); SMESH::SetPointRepresentation( false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( ActorSelection ); + if ( SVTK_ViewWindow* viewWindow = SMESH::GetViewWindow() ) + viewWindow->SetSelectionMode( ActorSelection ); QDialog::reject(); - myIDPreview->SetPointsLabeled(false); + myIDPreview->SetPointsLabeled( false ); } /*! - \brief Process keyboard event - \param e key press event + \brief Process keyboard event. + \param e Key press event. */ void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e ) { @@ -3062,15 +3237,7 @@ void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e ) } /*! - \brief Reactivate dialog box, when mouse pointer goes into it. -*/ -void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* ) -{ - //activate(); -} - -/*! - \brief Setup selection mode depending on the current dialog box state. + \brief Set-up selection mode for currently selected page. */ void SMESHGUI_MeshInfoDlg::updateSelection() { @@ -3079,86 +3246,60 @@ void SMESHGUI_MeshInfoDlg::updateSelection() disconnect( selMgr, 0, this, 0 ); selMgr->clearFilters(); - if ( myTabWidget->currentIndex() == BaseInfo || - myTabWidget->currentIndex() == AddInfo || - myTabWidget->currentIndex() == CtrlInfo ) { - SMESH::SetPointRepresentation( false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( ActorSelection ); - } - else { - if ( myMode->checkedId() == NodeMode ) { - SMESH::SetPointRepresentation( true ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( NodeSelection ); - } - else { - SMESH::SetPointRepresentation( false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( CellSelection ); - } - } + int selMode = ActorSelection; + if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == NodeMode ) + selMode = NodeSelection; + else if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == ElemMode ) + selMode = CellSelection; + SMESH::SetPointRepresentation( selMode == NodeSelection ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( selMode ); - QString oldID = myID->text().trimmed(); - SMESH_Actor* oldActor = myActor; + SMESH::SelectionProxy previous = myProxy; + QString ids = myID->text().trimmed(); myID->clear(); - connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); updateInfo(); - if ( oldActor == myActor && myActor && !oldID.isEmpty() ) { - myID->setText( oldID ); + if ( myProxy && myProxy == previous && !ids.isEmpty() ) { + myID->setText( ids ); idChanged(); } } /*! - \brief Show help page + \brief Show documentation on selected dialog page. */ void SMESHGUI_MeshInfoDlg::help() { - SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ? - "mesh_infos.html#advanced-mesh-infos-anchor" : - "mesh_infos.html#mesh-element-info-anchor" ); -} - -/*! - \brief Show mesh information -*/ -void SMESHGUI_MeshInfoDlg::updateInfo() -{ - SUIT_OverrideCursor wc; - - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); - - if ( selected.Extent() == 1 ) { - Handle(SALOME_InteractiveObject) IO = selected.First(); - showInfo( IO ); - } - else { - showInfo( myIO ); + QString helpPage = "mesh_infos.html"; + switch ( myTabWidget->currentIndex() ) + { + case BaseInfo: + helpPage += "#advanced-mesh-infos-anchor"; + break; + case ElemInfo: + helpPage += "#mesh-element-info-anchor"; + break; + case AddInfo: + helpPage += "#mesh-addition-info-anchor"; + break; + case CtrlInfo: + helpPage += "#mesh-quality-info-anchor"; + break; + default: + break; } + SMESH::ShowHelpFile( helpPage ); } /*! - \brief Activate dialog box -*/ -void SMESHGUI_MeshInfoDlg::activate() -{ - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); - myTabWidget->setEnabled( true ); - updateSelection(); -} - -/*! - \brief Deactivate dialog box + \brief Deactivate dialog box. */ void SMESHGUI_MeshInfoDlg::deactivate() { - myTabWidget->setEnabled( false ); - disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); } /*! @@ -3166,6 +3307,7 @@ void SMESHGUI_MeshInfoDlg::deactivate() */ void SMESHGUI_MeshInfoDlg::modeChanged() { + emit( switchMode( myMode->checkedId() == GroupMode ? 1 : 0 ) ); myID->clear(); updateSelection(); } @@ -3177,46 +3319,48 @@ void SMESHGUI_MeshInfoDlg::idChanged() { myIDPreview->SetPointsLabeled( false ); - SVTK_Selector* selector = SMESH::GetSelector(); - if ( myActor && selector ) { - Handle(SALOME_InteractiveObject) IO = myActor->getIO(); + if ( myProxy ) { TColStd_MapOfInteger ID; - QSet ids; + QSet ids; std::vector idVec; std::list< gp_XYZ > aGrCentersXYZ; + SMESH::XYZ xyz; + const bool isElem = ( myMode->checkedId() == ElemMode ); 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 ) { + long id = tid.toUInt(); + if ( isElem ? myProxy.hasElement( id ) : myProxy.hasNode( id )) + { ID.Add( id ); ids << id; - if ( myMode->checkedId() == ElemMode ) + if ( isElem && myProxy.actor() && myProxy.elementGravityCenter( id, xyz )) { idVec.push_back( id ); - aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e )); + aGrCentersXYZ.push_back( xyz ); } } } - selector->AddOrRemoveIndex( IO, ID, false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) { + SVTK_Selector* selector = SMESH::GetSelector(); + if ( myProxy.actor() && selector ) { + Handle(SALOME_InteractiveObject) IO = myProxy.actor()->getIO(); + selector->AddOrRemoveIndex( IO, ID, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + { + if ( myMode->checkedId() == NodeMode ) + myIDPreview->SetPointsData( myProxy.actor()->GetObject()->GetMesh(), ID ); + else + myIDPreview->SetElemsData( idVec, aGrCentersXYZ ); - if ( myMode->checkedId() == NodeMode ) - myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID ); - else - myIDPreview->SetElemsData( idVec, aGrCentersXYZ ); + bool showIDs = ( !ID.IsEmpty() && + myIDPreviewCheck->isChecked() && + myTabWidget->currentIndex() == ElemInfo ); + myIDPreview->SetPointsLabeled( showIDs, myProxy.actor()->GetVisibility() ); - bool showIDs = ( !ID.IsEmpty() && - myIDPreviewCheck->isChecked() && - myTabWidget->currentIndex() == ElemInfo ); - myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() ); - - aViewWindow->highlight( IO, true, true ); - aViewWindow->Repaint(); + aViewWindow->highlight( IO, true, true ); + aViewWindow->Repaint(); + } } - myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); + myElemInfo->showInfo( myProxy, ids, isElem ); } } @@ -3226,145 +3370,112 @@ void SMESHGUI_MeshInfoDlg::idChanged() void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn ) { myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() ); - SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn ); + SMESHGUI::resourceMgr()->setValue("SMESH", "id_preview_resource", isOn ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->Repaint(); } -void SMESHGUI_MeshInfoDlg::showItemInfo( int id ) +void SMESHGUI_MeshInfoDlg::showItemInfo( int type, const QString& ids ) { - if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) { - myMode->button( NodeMode )->click(); - myID->setText( QString::number( id )); - } -} - -void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr ) -{ - if ( !theStr.isEmpty() ) { - myMode->button( ElemMode )->click(); - myID->setText( theStr ); + if ( !ids.isEmpty() && ( type == NodeConnectivity || type == ElemConnectivity )) { + myMode->button( type - NodeConnectivity )->click(); + myID->setText( ids ); } } +/*! + \brief Dump information to file. +*/ void SMESHGUI_MeshInfoDlg::dump() { - QStringList aFilters; - aFilters.append( tr( "TEXT_FILES" )); - - bool anIsBase = true; - bool anIsElem = true; - bool anIsAdd = true; - bool anIsCtrl = true; - - if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) { - anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase ); - anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem ); - anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd ); - anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl ); - } - DumpFileDlg fd( this ); - fd.setWindowTitle( tr( "SAVE_INFO" )); - fd.setNameFilters( aFilters ); - fd.myBaseChk->setChecked( anIsBase ); - fd.myElemChk->setChecked( anIsElem ); - fd.myAddChk ->setChecked( anIsAdd ); - fd.myCtrlChk->setChecked( anIsCtrl ); + fd.setWindowTitle( tr( "SAVE_INFO" ) ); + fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) ); + fd.setChecked( BaseInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_base", true ) ); + fd.setChecked( ElemInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_elem", true ) ); + fd.setChecked( AddInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_add", true ) ); + fd.setChecked( CtrlInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_ctrl", true ) ); if ( fd.exec() == QDialog::Accepted ) { - QString aFileName = fd.selectedFile(); - - bool toBase = fd.myBaseChk->isChecked(); - bool toElem = fd.myElemChk->isChecked(); - bool toAdd = fd.myAddChk->isChecked(); - bool toCtrl = fd.myCtrlChk->isChecked(); - - if ( !aFileName.isEmpty() ) { - QFileInfo aFileInfo( aFileName ); - if ( aFileInfo.isDir() ) + QString fileName = fd.selectedFile(); + if ( !fileName.isEmpty() ) { + QFile file( fileName ); + if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) return; - - QFile aFile( aFileName ); - if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text )) - return; - - QTextStream out( &aFile ); - - if ( toBase ) myBaseInfo->saveInfo( out ); - if ( toElem ) myElemInfo->saveInfo( out ); - if ( toAdd ) myAddInfo ->saveInfo( out ); - if ( toCtrl ) myCtrlInfo->saveInfo( out ); + + QTextStream out( &file ); + if ( fd.isChecked( BaseInfo ) ) myBaseInfo->saveInfo( out ); + if ( fd.isChecked( ElemInfo ) ) myElemInfo->saveInfo( out ); + if ( fd.isChecked( AddInfo ) ) myAddInfo->saveInfo( out ); + if ( fd.isChecked( CtrlInfo ) ) myCtrlInfo->saveInfo( out ); } } } -/*! - \class SMESHGUI_CtrlInfo - \brief Class for the mesh controls information widget. -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_CtrlInfo +/// \brief Show quality statistics information on selected object. +/// +/// Displays quality controls statistics about selected object: mesh, sub-mesh, +/// group or arbitrary ID source. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) - : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 ) +SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ): SMESHGUI_Info( parent ) { - setFrameStyle( StyledPanel | Sunken ); + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); - myMainLayout = new QGridLayout( this ); - myMainLayout->setMargin( MARGIN ); - myMainLayout->setSpacing( SPACING ); + QIcon aComputeIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) ); + SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); // name - QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); - QLabel* aName = createField(); + QLabel* aNameLab = createLabel( tr( "NAME_LAB" ), this, Bold ); + QLabel* aName = createField( this, "ctrlName" ); aName->setMinimumWidth( 150 ); myWidgets << aName; - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) ); - - SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); - // nodes info - QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this ); + QLabel* aNodesLab = createLabel( tr( "NODES_INFO" ), this, Bold ); QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this ); - QLabel* aNodesFree = createField(); + QLabel* aNodesFree = createField( this, "ctrlNodesFree" ); myWidgets << aNodesFree; myPredicates << aFilterMgr->CreateFreeNodes(); // QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this ); - QLabel* aNodesNbConn = createField(); + QLabel* aNodesNbConn = createField( this, "ctrlNodesCnty" ); myWidgets << aNodesNbConn; myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber(); // QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this ); - QLabel* aNodesDouble = createField(); + QLabel* aNodesDouble = createField( this, "ctrlNodesDouble" ); myWidgets << aNodesDouble; myPredicates << aFilterMgr->CreateEqualNodes(); QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this ); myToleranceWidget = new SMESHGUI_SpinBox( this ); myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" ); myToleranceWidget->setAcceptNames( false ); - myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 )); + myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) ); // edges info - QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this ); + QLabel* anEdgesLab = createLabel( tr( "EDGES_INFO" ), this, Bold ); QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this ); - QLabel* anEdgesDouble = createField(); + QLabel* anEdgesDouble = createField( this, "ctrlEdgesDouble" ); myWidgets << anEdgesDouble; myPredicates << aFilterMgr->CreateEqualEdges(); // faces info - QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this ); + QLabel* aFacesLab = createLabel( tr( "FACES_INFO" ), this, Bold ); QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this ); - QLabel* aFacesDouble = createField(); + QLabel* aFacesDouble = createField( this, "ctrlFacesDouble" ); myWidgets << aFacesDouble; myPredicates << aFilterMgr->CreateEqualFaces(); QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this ); - QLabel* aFacesOver = createField(); + QLabel* aFacesOver = createField( this, "ctrlFacesOver" ); myWidgets << aFacesOver; myPredicates << aFilterMgr->CreateOverConstrainedFace(); QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this ); @@ -3372,13 +3483,13 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) myAspectRatio = aFilterMgr->CreateAspectRatio(); // volumes info - QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this ); + QLabel* aVolumesLab = createLabel( tr( "VOLUMES_INFO" ), this, Bold ); QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this ); - QLabel* aVolumesDouble = createField(); + QLabel* aVolumesDouble = createField( this, "ctrlVolumesDouble" ); myWidgets << aVolumesDouble; myPredicates << aFilterMgr->CreateEqualVolumes(); QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this ); - QLabel* aVolumesOver = createField(); + QLabel* aVolumesOver = createField( this, "ctrlVolumesOver" ); myWidgets << aVolumesOver; myPredicates << aFilterMgr->CreateOverConstrainedVolume(); QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this ); @@ -3425,112 +3536,77 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) aComputeVolumeBtn->setIcon(aComputeIcon); myButtons << aComputeVolumeBtn; //9 - connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() )); - connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() )); - connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() )); - connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() )); - connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() )); - connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() )); - connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() )); - connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() )); - connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() )); - connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() )); - connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double ))); + connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) ); + connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) ); + connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) ); + connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) ); + connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) ); + connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) ); + connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) ); + connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) ); + connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) ); + connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) ); + connect( myToleranceWidget, SIGNAL( valueChanged( double ) ), this, SLOT( setTolerance( double ) ) ); - setFontAttributes( aNameLab ); - setFontAttributes( aNodesLab ); - setFontAttributes( anEdgesLab ); - setFontAttributes( aFacesLab ); - setFontAttributes( aVolumesLab ); - - myMainLayout->addWidget( aNameLab, 0, 0 ); //0 - myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1 - myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2 - myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3 - myMainLayout->addWidget( aNodesFree, 2, 1 ); //4 - myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5 - myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6 - myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7 - myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8 - myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9 - myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10 - myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11 - myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12 - myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13 - myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14 - myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15 - myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16 - myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17 - myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18 - myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19 - myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20 - myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21 - myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22 - myMainLayout->addWidget( aFacesOver, 10, 1 ); //23 - myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24 - myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25 - myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26 - myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27 - myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28 - myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29 - myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30 - myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31 - myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32 - myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33 - myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34 - myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35 - myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36 - myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37 + l->addWidget( aNameLab, 0, 0 ); //0 + l->addWidget( aName, 0, 1, 1, 2 ); //1 + l->addWidget( aNodesLab, 1, 0, 1, 3 ); //2 + l->addWidget( aNodesFreeLab, 2, 0 ); //3 + l->addWidget( aNodesFree, 2, 1 ); //4 + l->addWidget( aFreeNodesBtn, 2, 2 ); //5 + l->addWidget( aNodesNbConnLab, 3, 0 ); //6 + l->addWidget( aNodesNbConn, 3, 1 ); //7 + l->addWidget( aNodesNbConnBtn, 3, 2 ); //8 + l->addWidget( aNodesDoubleLab, 4, 0 ); //9 + l->addWidget( aNodesDouble, 4, 1 ); //10 + l->addWidget( aDoubleNodesBtn, 4, 2 ); //11 + l->addWidget( aToleranceLab, 5, 0 ); //12 + l->addWidget( myToleranceWidget, 5, 1 ); //13 + l->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14 + l->addWidget( anEdgesDoubleLab, 7, 0 ); //15 + l->addWidget( anEdgesDouble, 7, 1 ); //16 + l->addWidget( aDoubleEdgesBtn, 7, 2 ); //17 + l->addWidget( aFacesLab, 8, 0, 1, 3 ); //18 + l->addWidget( aFacesDoubleLab, 9, 0 ); //19 + l->addWidget( aFacesDouble, 9, 1 ); //20 + l->addWidget( aDoubleFacesBtn, 9, 2 ); //21 + l->addWidget( aFacesOverLab, 10, 0 ); //22 + l->addWidget( aFacesOver, 10, 1 ); //23 + l->addWidget( aOverContFacesBtn, 10, 2 ); //24 + l->addWidget( anAspectRatioLab, 11, 0 ); //25 + l->addWidget( aComputeFaceBtn, 11, 2 ); //26 + l->addWidget( myPlot, 12, 0, 1, 3 );//27 + l->addWidget( aVolumesLab, 13, 0, 1, 3 );//28 + l->addWidget( aVolumesDoubleLab, 14, 0 ); //29 + l->addWidget( aVolumesDouble, 14, 1 ); //30 + l->addWidget( aDoubleVolumesBtn, 14, 2 ); //31 + l->addWidget( aVolumesOverLab, 15, 0 ); //32 + l->addWidget( aVolumesOver, 15, 1 ); //33 + l->addWidget( aOverContVolumesBtn,15, 2 ); //34 + l->addWidget( anAspectRatio3DLab, 16, 0 ); //35 + l->addWidget( aComputeVolumeBtn, 16, 2 ); //36 + l->addWidget( myPlot3D, 17, 0, 1, 3 );//37 - myMainLayout->setColumnStretch( 0, 0 ); - myMainLayout->setColumnStretch( 1, 5 ); - myMainLayout->setRowStretch ( 12, 5 ); - myMainLayout->setRowStretch ( 17, 5 ); - myMainLayout->setRowStretch ( 18, 1 ); + l->setColumnStretch( 0, 0 ); + l->setColumnStretch( 1, 5 ); + l->setRowStretch ( 12, 5 ); + l->setRowStretch ( 17, 5 ); + l->setRowStretch ( 18, 1 ); clearInternal(); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo() -{} - -/*! - \brief Change widget font attributes (bold, ...). - \param w widget - \param attr font attributes (XORed flags) -*/ -void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w ) { - if ( w ) { - QFont f = w->font(); - f.setBold( true ); - w->setFont( f ); - } } /*! - \brief Create info field - \return new info field -*/ -QLabel* SMESHGUI_CtrlInfo::createField() -{ - QLabel* lab = new QLabel( this ); - lab->setFrameStyle( StyledPanel | Sunken ); - lab->setAlignment( Qt::AlignCenter ); - lab->setAutoFillBackground( true ); - QPalette pal = lab->palette(); - pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base )); - lab->setPalette( pal ); - lab->setMinimumWidth( 60 ); - return lab; -} - -/*! - \brief Create QwtPlot - \return new QwtPlot + \brief Create plot widget. + \param parent Parent widget. + \return New plot widget. */ QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent ) { @@ -3547,17 +3623,20 @@ QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent ) } /*! - \brief Show controls information on the selected object + \brief Show information on given object. + \param proxy Object to show information on (mesh, sub-mesh, group, ID source). */ -void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy ) { clearInternal(); - myObject = SMESH::SMESH_IDSource::_duplicate( obj ); - if ( myObject->_is_nil() ) return; + if ( !proxy ) + return; - if ( _PTR(SObject) aSO = SMESH::FindSObject( obj )) - myWidgets[0]->setText( aSO->GetName().c_str() ); + myProxy = proxy; + SMESH::SMESH_IDSource_var obj = proxy.object(); + + myWidgets[0]->setText( proxy.name() ); SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); if ( mesh->_is_nil() ) return; @@ -3596,7 +3675,7 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) } else { for( int i=2; i<=13; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } // edges info @@ -3609,9 +3688,9 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) } else { for( int i=14; i<=17; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } - + // faces info if ( nbElemsByType[ SMESH::FACE ] > 0 ) { if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) { @@ -3629,12 +3708,12 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) } #ifdef DISABLE_PLOT2DVIEWER for( int i=25; i<=27; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); #endif } else { for( int i=18; i<=27; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } // volumes info @@ -3654,12 +3733,12 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) } #ifdef DISABLE_PLOT2DVIEWER for( int i=35; i<=37; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); #endif } else { for( int i=28; i<=37; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } } @@ -3676,15 +3755,19 @@ void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg ) { myButtons[ iBut ]->setEnabled( false ); myWidgets[ iWdg ]->setText( "" ); - if ( myObject->_is_nil() ) return; + + if ( !myProxy ) + return; SUIT_OverrideCursor wc; - SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->_is_nil() && !mesh->IsLoaded() ) { mesh->Load(); - this->showInfo( myObject ); // try to show all values + showInfo( myProxy ); // try to show all values if ( !myWidgets[ iWdg ]->text().isEmpty() ) return; // predicate already computed } @@ -3692,8 +3775,8 @@ void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg ) for ( int i = 0; i < myPredicates.count(); ++i ) if ( myPredicates[i]->GetFunctorType() == ft ) { - CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject ); - myWidgets[ iWdg ]->setText( QString::number( nb )); + CORBA::Long nb = myPredicates[i]->NbSatisfying( obj ); + myWidgets[ iWdg ]->setText( QString::number( nb ) ); } } @@ -3736,20 +3819,27 @@ void SMESHGUI_CtrlInfo::computeNodesNbConnInfo() { myButtons[ 1 ]->setEnabled( false ); myWidgets[ 2 ]->setText( "" ); - SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); - if ( mesh->_is_nil() ) return; + + if ( !myProxy ) + return; + + SUIT_OverrideCursor wc; + + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->IsLoaded() ) { mesh->Load(); - this->showInfo( myObject ); // try to show all values + showInfo( myProxy ); // try to show all values if ( !myWidgets[ 2 ]->text().isEmpty() ) return; // already computed } myNodeConnFunctor->SetMesh( mesh ); SMESH::Histogram_var histogram = - myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject ); + myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, obj ); - myWidgets[ 2 ]->setText( QString::number( histogram[0].max )); + myWidgets[ 2 ]->setText( QString::number( histogram[0].max ) ); } void SMESHGUI_CtrlInfo::computeAspectRatio() @@ -3757,10 +3847,14 @@ void SMESHGUI_CtrlInfo::computeAspectRatio() #ifndef DISABLE_PLOT2DVIEWER myButtons[6]->setEnabled( false ); - if ( myObject->_is_nil() ) return; + if ( !myProxy ) + return; SUIT_OverrideCursor wc; + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio ); if ( aHistogram && !aHistogram->isEmpty() ) { QwtPlotItem* anItem = aHistogram->createPlotItem(); @@ -3776,10 +3870,14 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D() #ifndef DISABLE_PLOT2DVIEWER myButtons[9]->setEnabled( false ); - if ( myObject->_is_nil() ) return; + if ( !myProxy ) + return; SUIT_OverrideCursor wc; + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D ); if ( aHistogram && !aHistogram->isEmpty() ) { QwtPlotItem* anItem = aHistogram->createPlotItem(); @@ -3796,7 +3894,7 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D() void SMESHGUI_CtrlInfo::clearInternal() { for( int i=0; i<=37; i++) - myMainLayout->itemAt(i)->widget()->setVisible( true ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( true ); for( int i=0; i<=9; i++) myButtons[i]->setEnabled( false ); myPlot->detachItems(); @@ -3818,14 +3916,17 @@ void SMESHGUI_CtrlInfo::setTolerance( double theTolerance ) #ifndef DISABLE_PLOT2DVIEWER Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun ) { - SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); - if ( mesh->_is_nil() ) return 0; + SUIT_OverrideCursor wc; + + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->IsLoaded() ) mesh->Load(); aNumFun->SetMesh( mesh ); CORBA::Long cprecision = 6; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) + if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ) cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); aNumFun->SetPrecision( cprecision ); @@ -3833,9 +3934,9 @@ Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr a SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals, /*isLogarithmic=*/false, - myObject ); + obj ); Plot2d_Histogram* aHistogram = new Plot2d_Histogram(); - aHistogram->setColor( palette().color( QPalette::Highlight )); + aHistogram->setColor( palette().color( QPalette::Highlight ) ); if ( &histogramVar.in() ) { for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ ) @@ -3847,28 +3948,35 @@ Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr a } #endif -void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) { - out << QString( 20, '-' ) << "\n"; - out << tr( "CTRL_INFO" ) << "\n"; - out << QString( 20, '-' ) << "\n"; - out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n"; - out << tr( "NODES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n"; - out << tr( "EDGES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n"; - out << tr( "FACES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n"; - out << tr( "VOLUMES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n"; +void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) +{ + // title + QString title = tr( "CTRL_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + out << endl; + + // info + out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << endl; + out << tr( "NODES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << endl; + out << tr( "EDGES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << endl; + out << tr( "FACES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << endl; + out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << endl; + out << tr( "VOLUMES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << endl; + out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << endl; } -/*! - \class SMESHGUI_CtrlInfoDlg - \brief Controls information dialog box -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_CtrlInfoDlg +/// \brief Overall Mesh Quality dialog. +/// \todo Add selection button to reactivate selection on move from other dlg. +//////////////////////////////////////////////////////////////////////////////// /*! \brief Constructor @@ -3878,7 +3986,7 @@ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) : QDialog( parent ) { setAttribute( Qt::WA_DeleteOnClose, true ); - setWindowTitle( tr( "CTRL_INFO" )); + setWindowTitle( tr( "CTRL_INFO" ) ); setMinimumSize( 400, 600 ); myCtrlInfo = new SMESHGUI_CtrlInfo( this ); @@ -3903,16 +4011,16 @@ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) btnLayout->addWidget( helpBtn ); QVBoxLayout* l = new QVBoxLayout ( this ); - l->setMargin( MARGIN ); + l->setMargin( 0 ); l->setSpacing( SPACING ); l->addWidget( myCtrlInfo ); l->addLayout( btnLayout ); - connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() )); - connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() )); - connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() )); + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); updateSelection(); } @@ -3925,13 +4033,42 @@ SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg() } /*! - \brief Show controls information - \param IO interactive object + \brief Show mesh quality information on given object. + \param io Interactive object. */ -void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) +void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io ) { - if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO )) - myCtrlInfo->showInfo( obj ); + if ( !io.IsNull() ) + showInfo( SMESH::SelectionProxy( io ) ); +} + +/*! + \brief Show mesh quality information on given object. + \param proxy Selection proxy. +*/ +void SMESHGUI_CtrlInfoDlg::showInfo( const SMESH::SelectionProxy& proxy ) +{ + SUIT_OverrideCursor wc; + + if ( !proxy ) + return; + + myProxy = proxy; + myCtrlInfo->showInfo( proxy ); +} + +/*! + \brief Show mesh information +*/ +void SMESHGUI_CtrlInfoDlg::updateInfo() +{ + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) + showInfo( selected.First() ); + else + showInfo( myProxy ); } /*! @@ -3951,81 +4088,44 @@ void SMESHGUI_CtrlInfoDlg::updateSelection() LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); disconnect( selMgr, 0, this, 0 ); SMESH::SetPointRepresentation( false ); - connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); updateInfo(); } /*! - \brief Show mesh information -*/ -void SMESHGUI_CtrlInfoDlg::updateInfo() -{ - SUIT_OverrideCursor wc; - - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); - - if ( selected.Extent() == 1 ) { - Handle(SALOME_InteractiveObject) IO = selected.First(); - showInfo( IO ); - } -} - -/*! - \brief Activate dialog box -*/ -void SMESHGUI_CtrlInfoDlg::activate() -{ - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); - updateSelection(); -} - -/*! - \brief Deactivate dialog box + \brief Deactivate dialog box. */ void SMESHGUI_CtrlInfoDlg::deactivate() { - disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); } /*! - * \brief Dump contents into a file - */ + \brief Dump information to file. +*/ void SMESHGUI_CtrlInfoDlg::dump() { - QStringList aFilters; - aFilters.append( tr( "TEXT_FILES" )); - - DumpFileDlg fd( this ); - fd.setWindowTitle( tr( "SAVE_INFO" )); - fd.setNameFilters( aFilters ); - fd.myBaseChk->hide(); - fd.myElemChk->hide(); - fd.myAddChk ->hide(); - fd.myCtrlChk->hide(); + DumpFileDlg fd( this, false ); + fd.setWindowTitle( tr( "SAVE_INFO" ) ); + fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) ); if ( fd.exec() == QDialog::Accepted ) { - QString aFileName = fd.selectedFile(); - if ( !aFileName.isEmpty() ) { - QFileInfo aFileInfo( aFileName ); - if ( aFileInfo.isDir() ) + QString fileName = fd.selectedFile(); + if ( !fileName.isEmpty() ) { + QFile file( fileName ); + if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) return; - - QFile aFile( aFileName ); - if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text )) - return; - - QTextStream out( &aFile ); + + QTextStream out( &file ); myCtrlInfo->saveInfo( out ); } } } /*! - * \brief Show help - */ + \brief Show documentation on dialog. +*/ void SMESHGUI_CtrlInfoDlg::help() { - SMESH::ShowHelpFile("mesh_infos.html#mesh_quality_info_anchor"); + SMESH::ShowHelpFile( "mesh_infos.html#mesh-quality-info-anchor" ); } diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h index 85edb6001..cba180978 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.h +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.h @@ -19,14 +19,12 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : SMESHGUI_MeshInfo.h -// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) #ifndef SMESHGUI_MESHINFO_H #define SMESHGUI_MESHINFO_H #include "SMESH_SMESHGUI.hxx" -#include "SMESH_ControlsDef.hxx" +#include "SMESHGUI_SelectionProxy.h" #ifndef DISABLE_PLOT2DVIEWER #include @@ -34,17 +32,12 @@ #include #endif -#include #include #include #include #include -#include -#include #include -#include CORBA_SERVER_HEADER(SMESH_Mesh) -#include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_Filter) #include @@ -54,51 +47,65 @@ class QAbstractButton; class QButtonGroup; class QCheckBox; class QContextMenuEvent; -class QGridLayout; class QLabel; class QLineEdit; -class QPushButton; class QTabWidget; class QTextBrowser; +class QTreeWidget; +class QTreeWidgetItem; class SMDS_MeshElement; class SMDS_MeshNode; class SMESHGUI_IdPreview; class SMESHGUI_SpinBox; -class SMESH_Actor; class ExtraWidget; +class GroupCombo; +class InfoWriter; -class SMESHGUI_EXPORT SMESHGUI_MeshInfo : public QFrame +class SMESHGUI_EXPORT SMESHGUI_Info : public QWidget +{ +public: + SMESHGUI_Info( QWidget* = 0 ); + virtual void saveInfo( QTextStream& ) = 0; +}; + +class SMESHGUI_EXPORT SMESHGUI_BaseInfo : public SMESHGUI_Info { Q_OBJECT; - enum { - iName, + enum + { + iStart, + iObjectStart = iStart, + iName = iObjectStart, iObject, - iNodesStart, + iObjectEnd, + iNodesStart = iObjectEnd, iNodes, iNodesEnd, - iElementsStart = iNodesEnd, - iElements, - iNbStart, - iNb, - iNbEnd, - i0DStart = iNbEnd, + iElementsStart = iNodesEnd, + iElementsTitleStart = iElementsStart, + iElementsTitle, + iElementsTitleEnd, + iElementsTotalStart = iElementsTitleEnd, + iElementsTotal, + iElementsTotalEnd, + i0DStart = iElementsTotalEnd, i0D, i0DEnd, iBallsStart = i0DEnd, iBalls, iBallsEnd, - i1DStart = iBallsEnd, + i1DStart = iBallsEnd, i1D, i1DEnd, - i2DStart = i1DEnd, + i2DStart = i1DEnd, i2D, i2DTriangles, i2DQuadrangles, i2DPolygons, i2DEnd, - i3DStart = i2DEnd, + i3DStart = i2DEnd, i3D, i3DTetrahedrons, i3DHexahedrons, @@ -107,45 +114,49 @@ class SMESHGUI_EXPORT SMESHGUI_MeshInfo : public QFrame i3DHexaPrisms, i3DPolyhedrons, i3DEnd, - iElementsEnd = i3DEnd + iElementsEnd = i3DEnd, + iEnd, + iOther = iEnd }; - enum { - iSingle = 1, - iTotal = iSingle, + enum + { + iLabel, + iSingle, + iTotal = iSingle, iLinear, iQuadratic, - iBiQuadratic + iBiQuadratic, + iNbColumns }; - typedef QList wlist; - typedef QVector iwlist; + typedef QMap wlist; + typedef QMap iwlist; public: - SMESHGUI_MeshInfo( QWidget* = 0 ); - ~SMESHGUI_MeshInfo(); + SMESHGUI_BaseInfo( QWidget* = 0 ); + ~SMESHGUI_BaseInfo(); - void showInfo( SMESH::SMESH_IDSource_ptr ); - void clear(); - void saveInfo( QTextStream &out ); + void showInfo( const SMESH::SelectionProxy& ); + void clear(); + void saveInfo( QTextStream& ); private: - enum { Bold = 0x01, Italic = 0x02 }; - - QLabel* createField(); - QWidget* createLine(); - void setFontAttributes( QWidget*, int, bool = true ); - void setFieldsVisible( int, int, bool ); + QWidget* addWidget( QWidget*, int, int, int = 1 ); + QWidget* widget( int, int ) const; + QString value( int, int ) const; + void setFieldsVisible( int, int, bool ); private slots: + void updateInfo(); void loadMesh(); private: - iwlist myWidgets; - QPushButton* myLoadBtn; + iwlist myWidgets; + SMESH::SelectionProxy myProxy; }; -class SMESHGUI_EXPORT SMESHGUI_ElemInfo : public QWidget +class SMESHGUI_EXPORT SMESHGUI_ElemInfo : public SMESHGUI_Info { Q_OBJECT; @@ -153,74 +164,60 @@ public: SMESHGUI_ElemInfo( QWidget* = 0 ); ~SMESHGUI_ElemInfo(); - void setSource( SMESH_Actor*, SMESH::SMESH_IDSource_var ); - void showInfo( long, bool ); - void showInfo( QSet, bool ); - void clear(); - virtual void saveInfo( QTextStream &out ) = 0; - - gp_XYZ getGravityCenter( const SMDS_MeshElement* e ) { return gravityCenter(e); } + void showInfo( const SMESH::SelectionProxy&, uint, bool ); + void showInfo( const SMESH::SelectionProxy&, QSet, bool ); + void showInfo( const SMESH::SelectionProxy& ); + void clear(); + void saveInfo( QTextStream& ); protected: - struct XYZ - { - double myX, myY, myZ; - XYZ() { myX = myY = myZ = 0.0; } - XYZ(double x, double y, double z) { myX = x; myY = y; myZ = z; } - void add( double x, double y, double z ) { myX += x; myY += y; myZ += z; } - void divide( double a ) { if ( a != 0.) { myX /= a; myY /= a; myZ /= a; } } - double x() const { return myX; } - double y() const { return myY; } - double z() const { return myZ; } - operator gp_XYZ() const { return gp_XYZ( myX, myY, myZ ); } - }; - typedef QMap< int, QList > Connectivity; + enum { ShowNone, ShowNodes, ShowElements }; - QWidget* frame() const; - SMESH_Actor* actor() const; - bool isElements() const; - bool hasShapeToMesh() const { return myMeshHasShape; } + QWidget* centralWidget() const; - virtual void information( const QList& ) = 0; + SMESH::SelectionProxy proxy() const; + int what() const; + + QString type2str( int, bool = false ); + QString stype2str( int ); + QString etype2str( int ); + QString ctrl2str( int ); + void writeInfo( InfoWriter*, const QList& ); + virtual void information( const QList& ) = 0; virtual void clearInternal(); - Connectivity nodeConnectivity( const SMDS_MeshNode* ); - QString formatConnectivity( Connectivity, int ); - XYZ gravityCenter( const SMDS_MeshElement* ); - XYZ normal( const SMDS_MeshElement* ); - signals: - void itemInfo( int ); - void itemInfo( const QString& ); + void itemInfo( int type, const QString& ids ); private slots: - void showPrevious(); - void showNext(); - void updateControls(); + void showPrevious(); + void showNext(); + void updateControls(); private: - SMESH_Actor* myActor; - QList myIDs; - int myIsElement; - QWidget* myFrame; - ExtraWidget* myExtra; - int myIndex; - bool myMeshHasShape; + QWidget* myFrame; + ExtraWidget* myExtra; + SMESH::SelectionProxy myProxy; + int myWhat; + QList myIDs; + int myIndex; }; class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo { - Q_OBJECT + Q_OBJECT; public: SMESHGUI_SimpleElemInfo( QWidget* = 0 ); - void saveInfo( QTextStream &out ); protected: - void information( const QList& ); - void clearInternal(); + void information( const QList& ); + void clearInternal(); -private: +private slots: + void connectivityClicked(const QUrl &); + + private: QTextBrowser* myInfo; }; @@ -229,85 +226,86 @@ class SMESHGUI_EXPORT SMESHGUI_TreeElemInfo : public SMESHGUI_ElemInfo Q_OBJECT; class ItemDelegate; - - enum { Bold = 0x01, All = 0x80 }; + class ItemCreator; public: SMESHGUI_TreeElemInfo( QWidget* = 0 ); - void saveInfo( QTextStream &out ); protected: - void contextMenuEvent( QContextMenuEvent* e ); - void information( const QList& ); - void nodeInfo( const SMDS_MeshNode*, int, int, QTreeWidgetItem* ); - void clearInternal(); + void contextMenuEvent( QContextMenuEvent* ); + void information( const QList& ); + void nodeInfo( const SMDS_MeshNode*, int, int, QTreeWidgetItem* ); + void clearInternal(); private slots: - void itemDoubleClicked( QTreeWidgetItem*, int ); - void saveExpanded( QTreeWidgetItem* ); - + void itemDoubleClicked( QTreeWidgetItem*, int ); + void saveExpanded( QTreeWidgetItem* ); + private: QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 0 ); QString expandedResource( QTreeWidgetItem* ); private: - QTreeWidget* myInfo; + QTreeWidget* myInfo; }; -class GrpComputor: public QObject +class InfoComputor: public QObject { Q_OBJECT; public: - GrpComputor( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem*, QObject*, bool = false); - QTreeWidgetItem* getItem() { return myItem; } + enum { GrpSize, GrpNbNodes }; + + InfoComputor( QObject*, const SMESH::SelectionProxy&, int ); + +signals: + void computed(); public slots: void compute(); private: - SMESH::SMESH_GroupBase_var myGroup; - QTreeWidgetItem* myItem; - bool myToComputeSize; + SMESH::SelectionProxy myProxy; + int myOperation; }; -class SMESHGUI_EXPORT SMESHGUI_AddInfo : public QTreeWidget +class SMESHGUI_EXPORT SMESHGUI_AddInfo : public SMESHGUI_Info { Q_OBJECT; - enum { Bold = 0x01, All = 0x80 }; - public: SMESHGUI_AddInfo( QWidget* = 0 ); ~SMESHGUI_AddInfo(); - void showInfo( SMESH::SMESH_IDSource_ptr ); - // void clear(); - void saveInfo( QTextStream &out ); + void showInfo( const SMESH::SelectionProxy& ); + void clear(); + void saveInfo( QTextStream& ); private slots: - void changeLoadToCompute(); - void showPreviousGroups(); - void showNextGroups(); - void showPreviousSubMeshes(); - void showNextSubMeshes(); + void updateInfo(); + void showPreviousGroups(); + void showNextGroups(); + void showPreviousSubMeshes(); + void showNextSubMeshes(); private: QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 0 ); - void meshInfo( SMESH::SMESH_Mesh_ptr, QTreeWidgetItem* ); - void subMeshInfo( SMESH::SMESH_subMesh_ptr, QTreeWidgetItem* ); - void groupInfo( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem* ); + void meshInfo( const SMESH::SelectionProxy&, QTreeWidgetItem* ); + void subMeshInfo( const SMESH::SelectionProxy&, QTreeWidgetItem* ); + void groupInfo( const SMESH::SelectionProxy&, QTreeWidgetItem* ); - void showGroups(); - void showSubMeshes(); + void showGroups(); + void showSubMeshes(); private: - QList myComputors; - SMESH::ListOfGroups_var myGroups; - SMESH::submesh_array_var mySubMeshes; + SMESH::SelectionProxy myProxy; + QTreeWidget* myTree; + QList myComputors; + QList myGroups; + QList mySubMeshes; }; -class SMESHGUI_EXPORT SMESHGUI_CtrlInfo : public QFrame +class SMESHGUI_EXPORT SMESHGUI_CtrlInfo : public SMESHGUI_Info { Q_OBJECT; @@ -315,62 +313,59 @@ public: SMESHGUI_CtrlInfo( QWidget* = 0 ); ~SMESHGUI_CtrlInfo(); - void showInfo( SMESH::SMESH_IDSource_ptr ); - void saveInfo( QTextStream &out ); + void showInfo( const SMESH::SelectionProxy& ); + void saveInfo( QTextStream& ); private: enum ObjectType { Mesh, SubMesh, Group }; - QLabel* createField(); - QwtPlot* createPlot( QWidget* ); - void setFontAttributes( QWidget* ); - void clearInternal(); + QwtPlot* createPlot( QWidget* ); + void clearInternal(); #ifndef DISABLE_PLOT2DVIEWER - Plot2d_Histogram* getHistogram( SMESH::NumericalFunctor_ptr functor ); + Plot2d_Histogram* getHistogram( SMESH::NumericalFunctor_ptr ); #endif - void computeNb( int ft, int iBut, int iWdg ); + void computeNb( int, int, int ); private slots: - void computeAspectRatio(); - void computeAspectRatio3D(); - void computeFreeNodesInfo(); - void computeNodesNbConnInfo(); - void computeDoubleNodesInfo(); - void computeDoubleEdgesInfo(); - void computeDoubleFacesInfo(); - void computeOverConstrainedFacesInfo(); - void computeDoubleVolumesInfo(); - void computeOverConstrainedVolumesInfo(); - void setTolerance( const double theTolerance ); - + void computeAspectRatio(); + void computeAspectRatio3D(); + void computeFreeNodesInfo(); + void computeNodesNbConnInfo(); + void computeDoubleNodesInfo(); + void computeDoubleEdgesInfo(); + void computeDoubleFacesInfo(); + void computeOverConstrainedFacesInfo(); + void computeDoubleVolumesInfo(); + void computeOverConstrainedVolumesInfo(); + void setTolerance( double ); private: - typedef SALOME::GenericObj_wrap< SMESH::Predicate > TPredicate; + typedef SALOME::GenericObj_wrap< SMESH::Predicate > TPredicate; typedef SALOME::GenericObj_wrap< SMESH::NumericalFunctor > TNumFunctor; - SMESH::SMESH_IDSource_var myObject; - ObjectType myObjectType; - SMESHGUI_SpinBox* myToleranceWidget; - QList myWidgets; - QGridLayout* myMainLayout; - QwtPlot* myPlot; - QwtPlot* myPlot3D; - QList myButtons; - QList myPredicates; - TNumFunctor myAspectRatio, myAspectRatio3D, myNodeConnFunctor; + SMESH::SelectionProxy myProxy; + ObjectType myObjectType; + SMESHGUI_SpinBox* myToleranceWidget; + QList myWidgets; + QwtPlot* myPlot; + QwtPlot* myPlot3D; + QList myButtons; + QList myPredicates; + TNumFunctor myAspectRatio, myAspectRatio3D, myNodeConnFunctor; }; class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog { Q_OBJECT; - enum { NodeMode, ElemMode }; + enum { NodeMode, ElemMode, GroupMode }; public: //! Information type - enum { + enum + { BaseInfo, //!< base mesh information ElemInfo, //!< mesh element information AddInfo, //!< additional information - CtrlInfo //!< controls information + CtrlInfo //!< controls information }; SMESHGUI_MeshInfoDlg( QWidget* = 0, int = BaseInfo ); @@ -381,33 +376,35 @@ public: protected: void keyPressEvent( QKeyEvent* ); - void enterEvent( QEvent* ); + +signals: + void switchMode( int ); private slots: void help(); void updateSelection(); void updateInfo(); - void activate(); void deactivate(); void modeChanged(); void idChanged(); - void idPreviewChange(bool); - void showItemInfo( int ); - void showItemInfo( const QString& ); + void idPreviewChange( bool ); + void showItemInfo( int type, const QString& ids ); void dump(); private: - QTabWidget* myTabWidget; - SMESHGUI_MeshInfo* myBaseInfo; - QButtonGroup* myMode; - QLineEdit* myID; - QCheckBox* myIDPreviewCheck; - SMESHGUI_IdPreview* myIDPreview; - SMESHGUI_ElemInfo* myElemInfo; - SMESHGUI_AddInfo* myAddInfo; - SMESHGUI_CtrlInfo* myCtrlInfo; - SMESH_Actor* myActor; - Handle(SALOME_InteractiveObject) myIO; + void showInfo( const SMESH::SelectionProxy& ); + + SMESH::SelectionProxy myProxy; + QTabWidget* myTabWidget; + SMESHGUI_BaseInfo* myBaseInfo; + SMESHGUI_ElemInfo* myElemInfo; + SMESHGUI_AddInfo* myAddInfo; + SMESHGUI_CtrlInfo* myCtrlInfo; + QButtonGroup* myMode; + QLineEdit* myID; + QCheckBox* myIDPreviewCheck; + GroupCombo* myGroups; + SMESHGUI_IdPreview* myIDPreview; }; class SMESHGUI_EXPORT SMESHGUI_CtrlInfoDlg : public QDialog @@ -423,14 +420,16 @@ public: private slots: void updateInfo(); - void activate(); void deactivate(); void updateSelection(); void help(); void dump(); private: - SMESHGUI_CtrlInfo* myCtrlInfo; + void showInfo( const SMESH::SelectionProxy& ); + + SMESH::SelectionProxy myProxy; + SMESHGUI_CtrlInfo* myCtrlInfo; }; #endif // SMESHGUI_MESHINFO_H diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 19a08d1b9..5008c9cb8 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -1622,7 +1622,7 @@ SMESHGUI_SplitVolumesDlg::SMESHGUI_SplitVolumesDlg(SMESHGUI* theModule) } if ( myEntityTypeGrp ) { - myEntityTypeGrp->button(0)->setText( tr("SMESH_TETRAS")); + myEntityTypeGrp->button(0)->setText( tr("SMESH_TETRAHEDRON")); myEntityTypeGrp->button(1)->setText( tr("SMESH_PRISM")); if ( QGroupBox* gb = qobject_cast< QGroupBox* >( myEntityTypeGrp->button(0)->parent() )) gb->setTitle( tr("TARGET_ELEM_TYPE")); diff --git a/src/SMESHGUI/SMESHGUI_SelectionProxy.cxx b/src/SMESHGUI/SMESHGUI_SelectionProxy.cxx new file mode 100644 index 000000000..8986852c9 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_SelectionProxy.cxx @@ -0,0 +1,1585 @@ +// Copyright (C) 2007-2016 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 +// +// 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, or (at your option) any later version. +// +// 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 +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMESHGUI_SelectionProxy.h" + +#include "SMDS_Mesh.hxx" +#include "SMDS_VolumeTool.hxx" +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESH_Actor.h" +#include "SMESH_ControlsDef.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_Filter) +#include CORBA_SERVER_HEADER(SMESH_Group) + +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESH::SelectionProxy +/// \brief Provide operations over the selected object. +/// +/// The selection proxy class is aimed to use in dialogs to access mesh object +/// data either from actor or directly from CORBA reference, depending on what +/// of them is accessible. +/// This is useful in situations when some information is needed, but an actor +/// was not created yet. +/// +/// Selection proxy can be constructed in two ways: +/// - From interactive object: this performs full proxy initialization including +/// pick-up of an actor from the current viewer if it exists. +/// - From mesh source object (CORBA reference); for performance reasons in this +/// case full initialization is not immediately done and performed only when +/// needed. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Default constructor. Creates null proxy. +*/ +SMESH::SelectionProxy::SelectionProxy(): myActor(0), myDirty(false) +{ +} + +/*! + \brief Constructor. + \param io Interactive object. +*/ +SMESH::SelectionProxy::SelectionProxy( const Handle(SALOME_InteractiveObject)& io ): myActor(0), myDirty(true) +{ + myObject = SMESH::IObjectToInterface( io ); + init(); +} + +/*! + \brief Constructor. + \param object Mesh source. +*/ +SMESH::SelectionProxy::SelectionProxy( SMESH::SMESH_IDSource_ptr object ): myActor(0), myDirty(true) +{ + if ( !CORBA::is_nil( object ) ) + myObject = SMESH::SMESH_IDSource::_duplicate( object ); +} + +/*! + \brief Copy constructor. + \param other Proxy being copied. +*/ +SMESH::SelectionProxy::SelectionProxy( const SelectionProxy& other ) +{ + myIO = other.myIO; + myObject = other.myObject; + myActor = other.myActor; + myDirty = other.myDirty; +} + +/*! + \brief Perform internal initialization. + \internal +*/ +void SMESH::SelectionProxy::init() +{ + if ( myIO.IsNull() ) + myIO = new SALOME_InteractiveObject(); // create dummy IO to avoid crashes when accesing it + + if ( !CORBA::is_nil( myObject ) ) + { + if ( !myIO->hasEntry() ) + { + _PTR(SObject) sobj = SMESH::ObjectToSObject( myObject.in() ); + if ( sobj ) + myIO = new SALOME_InteractiveObject( sobj->GetID().c_str(), "SMESH", sobj->GetName().c_str() ); + } + if ( !myActor && myIO->hasEntry() ) + myActor = SMESH::FindActorByEntry( myIO->getEntry() ); + } + myDirty = false; +} + +/*! + \brief Assignment operator. + \param other Proxy being copied. +*/ +SMESH::SelectionProxy& SMESH::SelectionProxy::operator= ( const SMESH::SelectionProxy& other ) +{ + myIO = other.myIO; + myObject = other.myObject; + myActor = other.myActor; + myDirty = other.myDirty; + return *this; +} + +/*! + \brief Equality comparison operator. + \param other Proxy to compare with. + \return \c true if two proxies are equal; \c false otherwise. +*/ +bool SMESH::SelectionProxy::operator== ( const SMESH::SelectionProxy& other ) +{ + return !CORBA::is_nil( myObject ) && !CORBA::is_nil( other.myObject ) && + myObject->_is_equivalent( other.myObject ); +} + +/*! + \brief Re-initialize proxy. +*/ +void SMESH::SelectionProxy::refresh() +{ + init(); +} + +/*! + \brief Check if proxy is null. + \return \c true if proxy is null; \c false otherwise. +*/ +bool SMESH::SelectionProxy::isNull() const +{ + return CORBA::is_nil( myObject ); +} + +/*! + \brief Boolean conversion operator. + \return \c true if proxy is not null; \c false otherwise. +*/ +SMESH::SelectionProxy::operator bool() const +{ + return !isNull(); +} + +/*! + \brief Get interactive object. + \return Interactive object referenced by proxy. +*/ +const Handle(SALOME_InteractiveObject)& SMESH::SelectionProxy::io() const +{ + if ( myDirty ) + const_cast(this)->init(); + return myIO; +} + +/*! + \brief Get mesh object. + \return Mesh object (mesh, sub-mesh, group, etc.) referenced by proxy. +*/ +SMESH::SMESH_IDSource_ptr SMESH::SelectionProxy::object() const +{ + return SMESH::SMESH_IDSource::_duplicate( myObject ); +} + +/*! + \brief Get actor. + \return Actor referenced by proxy. +*/ +SMESH_Actor* SMESH::SelectionProxy::actor() const +{ + if ( myDirty ) + const_cast(this)->init(); + return myActor; +} + +/*! + \brief Get object's validity. + + Mesh object is valid if it is not null and information stored in it is valid. + + \return \c true if object is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::isValid() const +{ + return !isNull() && myObject->IsMeshInfoCorrect(); +} + +/*! + \brief Load mesh object from study file. +*/ +void SMESH::SelectionProxy::load() +{ + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + mesh->Load(); + } +} + +/*! + \brief Get name. + \return Mesh object's name. +*/ +QString SMESH::SelectionProxy::name() const +{ + QString value; + if ( !isNull() ) + value = io()->getName(); + return value; +} + +/*! + \brief Get type. + \return Mesh object's type. +*/ +SMESH::SelectionProxy::Type SMESH::SelectionProxy::type() const +{ + Type value = Unknown; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject ); + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( myObject ); + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject ); + SMESH::SMESH_Group_var sGroup = SMESH::SMESH_Group::_narrow( myObject ); + SMESH::SMESH_GroupOnGeom_var gGroup = SMESH::SMESH_GroupOnGeom::_narrow( myObject ); + SMESH::SMESH_GroupOnFilter_var fGroup = SMESH::SMESH_GroupOnFilter::_narrow( myObject ); + + if ( !CORBA::is_nil( mesh ) ) + value = Mesh; + else if ( !CORBA::is_nil( submesh ) ) + value = Submesh; + else if ( !CORBA::is_nil( sGroup ) ) + value = GroupStd; + else if ( !CORBA::is_nil( gGroup ) ) + value = GroupGeom; + else if ( !CORBA::is_nil( fGroup ) ) + value = GroupFilter; + else if ( !CORBA::is_nil( group ) ) + value = Group; + } + return value; +} + +/*! + \brief Get mesh information. + \return Statistics on stored mesh object. +*/ +SMESH::MeshInfo SMESH::SelectionProxy::meshInfo() const +{ + SMESH::MeshInfo info; + if ( !isNull() ) + { + SMESH::long_array_var data = myObject->GetMeshInfo(); + for ( uint type = SMESH::Entity_Node; type < SMESH::Entity_Last; type++ ) + { + if ( type < data->length() ) + info.addInfo( type, data[ type ] ); + } + } + return info; +} + +/*! + \brief Get parent mesh. + \return Proxy object that stores parent mesh object. + \note For proxy that stores a mesh, returns its copy. +*/ +SMESH::SelectionProxy SMESH::SelectionProxy::mesh() const +{ + SMESH::SelectionProxy parent; + if ( !isNull() ) + parent = SMESH::SelectionProxy( (SMESH::SMESH_Mesh_var) myObject->GetMesh() ); // cast to var to avoid leaks + return parent; +} + +/*! + \brief Check if parent mesh has shape to mesh. + \return \c true if Parent mesh is built on a shape; \c false otherwise. + \note For group or submesh, this method checks that parent mesh has a shape. +*/ +bool SMESH::SelectionProxy::hasShapeToMesh() const +{ + bool result = false; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + result = mesh->HasShapeToMesh(); + } + return result; +} + +/*! + \brief Get referenced GEOM object. + \return GEOM object referenced by selection proxy. + + The result contains valid pointer only if proxy refers to mesh, sub-mesh + or group created on a geometry. +*/ +GEOM::GEOM_Object_ptr SMESH::SelectionProxy::shape() const +{ + GEOM::GEOM_Object_var shape; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject ); + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( myObject ); + SMESH::SMESH_GroupOnGeom_var group = SMESH::SMESH_GroupOnGeom::_narrow( myObject ); + if ( !CORBA::is_nil( mesh ) ) + shape = mesh->GetShapeToMesh(); + else if ( !CORBA::is_nil( submesh ) ) + shape = submesh->GetSubShape(); + else if ( !CORBA::is_nil( group ) ) + shape = group->GetShape(); + } + return shape._retn(); +} + +/*! + \brief Get name of referenced GEOM object. + \return Name of GEOM object referenced by selection proxy. + + The result contains non-empty name only if proxy refers to mesh, sub-mesh + or group created on a geometry, and if that geometry has valid name. +*/ +QString SMESH::SelectionProxy::shapeName() const +{ + QString name; + if ( !isNull() ) + { + GEOM::GEOM_Object_var gobj = shape(); + _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); + if ( sobj ) + name = QString::fromStdString( sobj->GetName() ); + } + return name; +} + +/*! + \brief Get type of referenced GEOM object. + \return Type of GEOM object referenced by selection proxy. + + The result contains valid type only if proxy refers to mesh, sub-mesh + or group created on a geometry. +*/ +int SMESH::SelectionProxy::shapeType() const +{ + int type = -1; + if ( !isNull() ) + { + GEOM::GEOM_Object_var gobj = shape(); + if ( !CORBA::is_nil( gobj ) ) + type = gobj->GetShapeType(); + } + return type; +} + +/*! + \brief Check if mesh has been loaded from study file. + \return \c true if mesh was loaded; \c false otherwise. +*/ +bool SMESH::SelectionProxy::isMeshLoaded() const +{ + bool result = true; // set default to true to avoid side effects + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + result = mesh->IsLoaded(); + } + return result; +} + +/*! + \brief Check if node with given ID is present in the mesh. + \param id Mesh node ID. + \return \c true if mesh contains node; \c false otherwise. +*/ +bool SMESH::SelectionProxy::hasNode( int id ) +{ + bool result = false; + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id ); + result = node != 0; + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::double_array_var coords = mesh->GetNodeXYZ( id ); + result = coords->length() >= 3; + } + } + } + return result; +} + +/*! + \brief Get node coordinates. + \param id Mesh node ID. + \param xyz Returned node coordinates. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::nodeCoordinates( int id, SMESH::XYZ& xyz ) +{ + bool result = false; + xyz = SMESH::XYZ(); + + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id ); + if ( node ) + { + xyz = SMESH::XYZ( node->X(), node->Y(), node->Z() ); + result = true; + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::double_array_var coords = mesh->GetNodeXYZ( id ); + if ( coords->length() >= 3 ) + { + xyz = SMESH::XYZ( coords[0], coords[1], coords[2] ); + result = true; + } + } + } + } + return result; +} + +/*! + \brief Get node connectivity. + \param id Mesh node ID. + \param connectivity Returned node connectivity. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::nodeConnectivity( int id, SMESH::Connectivity& connectivity ) +{ + bool result = false; + connectivity.clear(); + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id ); + if ( node ) + { + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while ( it && it->more() ) + { + const SMDS_MeshElement* ne = it->next(); + connectivity[ ne->GetType() ] << ne->GetID(); + } + result = true; + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::long_array_var elements = mesh->GetNodeInverseElements( id, SMESH::ALL ); + for ( int i = 0, n = elements->length(); i < n; i++ ) + { + SMESH::ElementType type = mesh->GetElementType( elements[i], true ); + connectivity[ type ] << elements[i]; + } + result = true; + } + } + } + return result; +} + +/*! + \brief Get node position on a shape. + \param id Mesh node ID. + \param position Returned node position. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::nodePosition( int id, Position& position ) +{ + bool result = false; + position = Position(); + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::NodePosition_var pos = mesh->GetNodePosition( id ); + position.setShapeId( pos->shapeID ); + if ( pos->shapeID > 0 ) + { + position.setShapeType( pos->shapeType ); + if ( pos->shapeType == GEOM::EDGE && pos->params.length() > 0 ) + { + position.setU( pos->params[0] ); + } + if ( pos->shapeType == GEOM::FACE && pos->params.length() > 1 ) + { + position.setU( pos->params[0] ); + position.setV( pos->params[1] ); + } + result = true; + } + } + } + return result; +} + +/*! + \brief Get groups given node belongs to. + \param id Mesh node ID. + \return List of groups containing given node. +*/ +QList SMESH::SelectionProxy::nodeGroups( int id ) const +{ + QList result; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::ListOfGroups_var groups = mesh->GetGroups(); + for ( uint i = 0 ; i < groups->length(); i++ ) + { + if ( groups[i]->GetType() == SMESH::NODE && groups[i]->Contains( id ) ) + { + result << SMESH::SelectionProxy( groups[i].in() ); + } + } + } + } + return result; +} + +/*! + \brief Check if element with given ID is present in the mesh. + \param id Mesh element ID. + \return \c true if mesh contains element; \c false otherwise. +*/ +bool SMESH::SelectionProxy::hasElement( int id ) +{ + bool result = false; + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + result = element != 0; + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::long_array_var nodes = mesh->GetElemNodes( id ); + result = nodes->length() > 0; + } + } + } + return result; +} + +/*! + \brief Get type of given mesh element. + \param id Mesh element ID. + \return Element type. +*/ +SMESH::ElementType SMESH::SelectionProxy::elementType( int id ) const +{ + SMESH::ElementType value = SMESH::ALL; + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( element ) + { + value = (SMESH::ElementType)element->GetType(); + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + value = mesh->GetElementType( id, true ); + } + } + } + return value; +} + +/*! + \brief Get entity type of given mesh element. + \param id Mesh element ID. + \return Entity type. +*/ +int SMESH::SelectionProxy::elementEntityType( int id ) const +{ + SMESH::EntityType value = SMESH::Entity_Last; + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( element ) + { + value = (SMESH::EntityType)element->GetEntityType(); + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + value = mesh->GetElementGeomType( id ); + } + } + } + return value; +} + +/*! + \brief Get element connectivity. + \param id Mesh element ID. + \param connectivity Return element connectivity. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::elementConnectivity( int id, Connectivity& connectivity ) +{ + bool result = false; + connectivity.clear(); + if ( !isNull() ) + { + QSet nodes; // order of nodes is important + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( element ) + if ( SMDS_NodeIteratorPtr it = element->nodeIterator()) + { + while ( it->more() ) + { + int n = it->next()->GetID(); + if ( !nodes.contains( n )) + { + connectivity[ SMDSAbs_Node ] << n; + nodes << n; + } + } + result = true; + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::long_array_var nn = mesh->GetElemNodes( id ); + for ( int i = 0, nb = nn->length(); i < nb; i++ ) + { + if ( !nodes.contains( nn[i] )) + { + connectivity[ SMDSAbs_Node ] << nn[i]; + nodes << nn[i]; + } + } + result = true; + } + } + } + return result; +} + +/*! + \brief Get volume element connectivity. + \param id Mesh element ID. + \param connectivity Return nodal connectivity of each facet numbered from 1 + \param nbNodes Return number of unique nodes. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::perFaceConnectivity( int id, Connectivity& connectivity, int& nbNodes ) +{ + bool result = false; + connectivity.clear(); + nbNodes = 0; + if ( !isNull() ) + { + QSet nodeSet; + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + SMDS_VolumeTool volTool; + if ( volTool.Set( element )) + { + for ( int iF = 0; iF < volTool.NbFaces(); ++iF ) + { + const SMDS_MeshNode** nn = volTool.GetFaceNodes( iF ); + int nbN = volTool.NbFaceNodes( iF ); + for ( int iN = 0; iN < nbN; ++iN ) + { + connectivity[ iF+1 ] << ( nn[ iN ]->GetID() ); + nodeSet << ( nn[ iN ]->GetID() ); + } + } + result = true; + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + CORBA::Long nbFaces = mesh->ElemNbFaces( id ); + for ( CORBA::Long iF = 0; iF < nbFaces; ++iF ) + { + SMESH::long_array_var nodes = mesh->GetElemFaceNodes( id, iF ); + for ( CORBA::ULong iN = 0; iN < nodes->length(); ++iN ) + { + connectivity[ iF ] << nodes[iN]; + nodeSet << nodes[iN]; + } + } + result = ( nbFaces > 0 ); + } + } + nbNodes = nodeSet.size(); + } + return result; +} + +/*! + \brief Get element position on a shape. + \param id Mesh element ID. + \param position Returned element position. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::elementPosition( int id, Position& position ) +{ + bool result = false; + position = Position(); + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::ElementPosition_var pos = mesh->GetElementPosition( id ); + position.setShapeId( pos->shapeID ); + if ( pos->shapeID > 0 ) + { + position.setShapeType( pos->shapeType ); + result = true; + } + } + } + return result; +} + +/*! + \brief Get gravity center of given element. + \param id Mesh element ID. + \param xyz Returned gravity center. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::elementGravityCenter( int id, SMESH::XYZ& xyz ) +{ + bool result = false; + xyz = SMESH::XYZ(); + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( element ) + { + SMDS_ElemIteratorPtr it = element->nodesIterator(); + while ( it->more() ) + { + const SMDS_MeshNode* node = static_cast( it->next() ); + xyz.add( node->X(), node->Y(), node->Z() ); + } + xyz.divide( element->NbNodes() ); + result = true; + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::long_array_var nodes = mesh->GetElemNodes( id ); + for ( int i = 0, n = nodes->length(); i < n; i++ ) + { + SMESH::double_array_var coords = mesh->GetNodeXYZ( nodes[i] ); + if ( coords->length() >= 3 ) + { + xyz.add( coords[0], coords[1], coords[2] ); + } + } + xyz.divide( nodes->length() ); + result = true; + } + } + } + return result; +} + +/*! + \brief Get normal vector to given element (face). + \param id Mesh element ID. + \param xyz Returned normal vector. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::elementNormal( int id, SMESH::XYZ& xyz ) +{ + bool result = false; + xyz = SMESH::XYZ(); + if ( !isNull() ) + { + if ( actor() ) + { + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( element && element->GetType() == SMDSAbs_Face ) + { + xyz = SMESH::getNormale( SMDS_Mesh::DownCast( element ) ); + result = true; + } + } + else + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::double_array_var normal = mesh->GetFaceNormal( id, true ); + if ( normal->length() >= 3 ) + { + xyz = SMESH::XYZ( normal[0], normal[1], normal[2] ); + result = true; + } + } + } + } + return result; +} + +/*! + \brief Get quality control's value for given element. + \param id Mesh element ID. + \param control Quality control type. + \param precision Precision for control's value. + \param value Returned quality control's value. + \return \c true if result is valid; \c false otherwise. +*/ +bool SMESH::SelectionProxy::elementControl( int id, int control, double precision, double& value ) const +{ + bool result = false; + value = 0.; + if ( !isNull() ) + { + if ( actor() ) + { + SMESH::Controls::NumericalFunctorPtr functor; + switch ( control ) + { + case SMESH::FT_AspectRatio: + functor.reset( new SMESH::Controls::AspectRatio() ); + break; + case SMESH::FT_AspectRatio3D: + functor.reset( new SMESH::Controls::AspectRatio3D() ); + break; + case SMESH::FT_Warping: + functor.reset( new SMESH::Controls::Warping() ); + break; + case SMESH::FT_MinimumAngle: + functor.reset( new SMESH::Controls::MinimumAngle() ); + break; + case SMESH::FT_Taper: + functor.reset( new SMESH::Controls::Taper() ); + break; + case SMESH::FT_Skew: + functor.reset( new SMESH::Controls::Skew() ); + break; + case SMESH::FT_Area: + functor.reset( new SMESH::Controls::Area() ); + break; + case SMESH::FT_Volume3D: + functor.reset( new SMESH::Controls::Volume() ); + break; + case SMESH::FT_MaxElementLength2D: + functor.reset( new SMESH::Controls::MaxElementLength2D() ); + break; + case SMESH::FT_MaxElementLength3D: + functor.reset( new SMESH::Controls::MaxElementLength3D() ); + break; + case SMESH::FT_Length: + functor.reset( new SMESH::Controls::Length() ); + break; + case SMESH::FT_Length2D: + functor.reset( new SMESH::Controls::Length2D() ); + break; + case SMESH::FT_Length3D: + functor.reset( new SMESH::Controls::Length3D() ); + break; + case SMESH::FT_BallDiameter: + functor.reset( new SMESH::Controls::BallDiameter() ); + break; + default: + break; + } + const SMDS_MeshElement* element = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( element && functor && element->GetType() == functor->GetType() ) + { + functor->SetMesh( actor()->GetObject()->GetMesh() ); + if ( functor->IsApplicable( element )) + { + functor->SetPrecision( precision ); + value = functor->GetValue( id ); + result = true; + } + } + } + else + { + SMESH::SMESH_Gen_var smeshGen = SMESHGUI::GetSMESHGen(); + if ( smeshGen->_is_nil() ) + return false; + SMESH::FilterManager_var manager = smeshGen->CreateFilterManager(); + if ( manager->_is_nil() ) + return false; + SMESH::NumericalFunctor_var functor; + switch ( control ) + { + case SMESH::FT_AspectRatio: + functor = manager->CreateAspectRatio(); + break; + case SMESH::FT_AspectRatio3D: + functor = manager->CreateAspectRatio3D(); + break; + case SMESH::FT_Warping: + functor = manager->CreateWarping(); + break; + case SMESH::FT_MinimumAngle: + functor = manager->CreateMinimumAngle(); + break; + case SMESH::FT_Taper: + functor = manager->CreateTaper(); + break; + case SMESH::FT_Skew: + functor = manager->CreateSkew(); + break; + case SMESH::FT_Area: + functor = manager->CreateArea(); + break; + case SMESH::FT_Volume3D: + functor = manager->CreateVolume3D(); + break; + case SMESH::FT_MaxElementLength2D: + functor = manager->CreateMaxElementLength2D(); + break; + case SMESH::FT_MaxElementLength3D: + functor = manager->CreateMaxElementLength3D(); + break; + case SMESH::FT_Length: + functor = manager->CreateLength(); + break; + case SMESH::FT_Length2D: + functor = manager->CreateLength2D(); + break; + case SMESH::FT_Length3D: + functor = manager->CreateLength3D(); + break; + case SMESH::FT_BallDiameter: + functor = manager->CreateBallDiameter(); + break; + default: + break; + } + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !functor->_is_nil() && !mesh->_is_nil() ) + { + functor->SetMesh( mesh ); + if ( functor->IsApplicable( id )) + { + functor->SetPrecision( precision ); + value = functor->GetValue( id ); + result = true; + } + } + manager->UnRegister(); + } + } + return result; +} + +/*! + \brief Get groups given element belongs to. + \param id Mesh element ID. + \return List of groups containing element. +*/ +QList SMESH::SelectionProxy::elementGroups( int id ) const +{ + QList result; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::ListOfGroups_var groups = mesh->GetGroups(); + for ( uint i = 0 ; i < groups->length(); i++ ) + { + if ( groups[i]->GetType() != SMESH::NODE && groups[i]->Contains( id ) ) + { + result << SMESH::SelectionProxy( groups[i].in() ); + } + } + } + } + return result; +} + +/*! + \brief Get MED file information. + \return MED file information. + + The result contains valid data only if proxy refers to mesh object + which has been imported from the MED file. +*/ +SMESH::MedInfo SMESH::SelectionProxy::medFileInfo() const +{ + SMESH::MedInfo info; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject ); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo(); + info.setFileName( inf->fileName.in() ); + info.setSize( inf->fileSize ); + info.setVersion( inf->major, inf->minor, inf->release ); + } + } + return info; +} + +/*! + \brief Get child sub-meshes. + \return List of sub-meshes for mesh object; empty list for other types. +*/ +QList SMESH::SelectionProxy::submeshes() const +{ + QList lst; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject ); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::submesh_array_var array = mesh->GetSubMeshes(); + for ( uint i = 0 ; i < array->length(); i++ ) + lst << SMESH::SelectionProxy( array[i].in() ); + } + } + return lst; +} + +/*! + \brief Get child groups. + \return List of groups for mesh object; empty list for other types. +*/ +QList SMESH::SelectionProxy::groups() const +{ + QList lst; + if ( !isNull() ) + { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject ); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::ListOfGroups_var array = mesh->GetGroups(); + for ( uint i = 0 ; i < array->length(); i++ ) + lst << SMESH::SelectionProxy( array[i].in() ); + } + } + return lst; +} + +/*! + \brief Get element type (for group). For other mesh objects result is undefined. + \return Group's element type. +*/ +SMESH::ElementType SMESH::SelectionProxy::groupElementType() const +{ + SMESH::ElementType value = SMESH::ALL; + if ( !isNull() ) + { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject ); + if ( !CORBA::is_nil( group ) ) + value = group->GetType(); + } + return value; +} + +/*! + \brief Get color (for group). For other mesh objects result is undefined. + \return Group's color. +*/ +QColor SMESH::SelectionProxy::color() const +{ + QColor result; + if ( !isNull() ) + { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject ); + if ( !CORBA::is_nil( group ) ) + { + SALOMEDS::Color c = group->GetColor(); + result = QColor::fromRgbF( c.R, c.G, c.B ); + } + } + return result; +} + +/*! + \brief Get size (for group). For other mesh objects result is undefined. + \param autoCompute Compute size if it is unavailable. Defaults to \c false. + \return Group's size. +*/ +int SMESH::SelectionProxy::size( bool autoCompute ) const +{ + // note: size is not computed for group on filter for performance reasons, see IPAL52831 + int result = -1; + if ( !isNull() ) + { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject ); + if ( !CORBA::is_nil( group ) ) + { + if ( type() == GroupFilter ) + // for group on filter we check if value is already computed and cached + autoCompute |= group->IsNodeInfoAvailable(); + else + // for other groups we force autoCompute to true + autoCompute = true; + if ( autoCompute ) + result = group->Size(); + } + } + return result; +} + +/*! + \brief Get number of underlying nodes (for group of elements). For other + mesh objects result is undefined. + \param autoCompute Compute size if it is unavailable. Defaults to \c false. + \return Number of nodes contained in group. +*/ +int SMESH::SelectionProxy::nbNodes( bool autoCompute ) const +{ + // note: nb of nodes is not computed automatically for performance reasons + int result = -1; + if ( !isNull() ) + { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject ); + if ( !CORBA::is_nil( group ) && ( autoCompute || isMeshLoaded() ) ) + { + int groupSize = size( autoCompute ); + if ( groupSize >= 0 ) + { + int limit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 ); + if ( group->IsNodeInfoAvailable() || limit <= 0 || groupSize <= limit ) + result = group->GetNumberOfNodes(); + } + } + } + return result; +} + +/*! + \brief Get list of nodes / elements IDs for the mesh group. + \return List of IDs for group object; empty list for other types. +*/ +QSet SMESH::SelectionProxy::ids() const +{ + QSet result; + if ( !isNull() ) + { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject ); + if ( !CORBA::is_nil( group ) ) + { + SMESH::long_array_var seq = group->GetListOfID(); + for ( int i = 0, n = seq->length(); i < n; i++ ) + result << (uint)seq[i]; + } + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESH::MeshInfo +/// \brief Store statistics on mesh object. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Constructor. +*/ +SMESH::MeshInfo::MeshInfo() +{ +} + +/*! + \brief Add information on given entity type. + \param type Entity type. + \param value Number of entities. +*/ +void SMESH::MeshInfo::addInfo( int type, long value ) +{ + myInfo[type] = value; +} + +/*! + \brief Get number of entities of given type. + \param type Entity type. + \return Number of entities. +*/ +uint SMESH::MeshInfo::info( int type ) const +{ + return myInfo.value( type, 0U ); +} + +/*! + \brief Access operator. + \param type Entity type. + \return Number of entities. +*/ +uint SMESH::MeshInfo::operator[] ( int type ) +{ + return (uint)info( type ); +} + +/*! + \brief Get total number of entities for types in given range. + \param fromType Lower entity type. + \param toType Upper entity type. + \return Number of entities. +*/ +uint SMESH::MeshInfo::count( int fromType, int toType ) const +{ + uint value = 0; + for ( int type = fromType; type <= toType; type++ ) + value += info( type ); + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESH::MedInfo +/// \brief Provide operations over the selected object +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Constructor. +*/ +SMESH::MedInfo::MedInfo() +{ +} + +/*! + \brief Get validity status. + + MED file information is valid if at least stored file name is not null. + + \return \c true if MED file info is valid; \c false otherwise. +*/ +bool SMESH::MedInfo::isValid() const +{ + return !myFileName.isEmpty(); +} + +/*! + \brief Get file name for mesh imported from MED file. + \return MED file name. +*/ +QString SMESH::MedInfo::fileName() const +{ + return myFileName; +} + +/*! + \brief Set file name for mesh imported from MED file. + \param fileName MED file name. +*/ +void SMESH::MedInfo::setFileName( const QString& fileName ) +{ + myFileName = fileName; +} + +/*! + \brief Get file size for mesh imported from MED file. + \return MED file size. +*/ +uint SMESH::MedInfo::size() const +{ + return mySize; +} + +/*! + \brief Set file size for mesh imported from MED file. + \param size MED file size. +*/ +void SMESH::MedInfo::setSize( uint size ) +{ + mySize = size; +} + +/*! + \brief Get version of format for mesh imported from MED file. + \return MED file format version. +*/ +QString SMESH::MedInfo::version() const +{ + QString v = QString( "%1" ).arg( myMajor ); + if ( myMinor > 0 || myRelease > 0 ) v += QString( ".%1" ).arg( myMinor ); + else if ( myMajor > 0 ) v += ".0"; + if ( myRelease > 0 ) v += QString( ".%1" ).arg( myRelease ); + return v; +} + +/*! + \brief Set version of format for mesh imported from MED file. + \param major Major version number. + \param minor Minor version number. + \param release Release version number. +*/ +void SMESH::MedInfo::setVersion( uint major, uint minor, uint release ) +{ + myMajor = major; + myMinor = minor; + myRelease = release; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESH::Position +/// \brief Describes position of mesh node or element on a reference shape. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Contructor. Creates invalid position. +*/ +SMESH::Position::Position(): + myShapeId(-1), myShapeType(-1), myU(0), myV(0), myHasU(false), myHasV(false) +{ +} + +/*! + \brief Check if position is valid. + \return \c true if position is valid; \c false otherwise. +*/ +bool SMESH::Position::isValid() const +{ + return myShapeId > 0 && myShapeType != -1; +} + +/*! + \brief Get reference shape ID. + \return Shape / sub-shape ID. +*/ +int SMESH::Position::shapeId() const +{ + return myShapeId; +} + +/*! + \brief Set reference shape ID. + \param id Shape / sub-shape ID. +*/ +void SMESH::Position::setShapeId( int id ) +{ + myShapeId = id; +} + +/*! + \brief Get reference shape type. + \return Shape type. +*/ +int SMESH::Position::shapeType() const +{ + return myShapeType; +} + +/*! + \brief Set reference shape type. + \param type Shape type. +*/ +void SMESH::Position::setShapeType( int type ) +{ + myShapeType = type; +} + +/*! + \brief Check if there is U position on a shape. + \return \c true if U position is valid; \c false otherwise. +*/ +bool SMESH::Position::hasU() const +{ + return myHasU; +} + +/*! + \brief Get U position on a shape. + \return U position. +*/ +double SMESH::Position::u() const +{ + return myU; +} + +/*! + \brief Set U position on a shape. + \parm u U position. +*/ +void SMESH::Position::setU( double u ) +{ + myU = u; + myHasU = true; +} + +/*! + \brief Check if there is V position on a shape. + \return \c true if V position is valid; \c false otherwise. +*/ +bool SMESH::Position::hasV() const +{ + return myHasV; +} + +/*! + \brief Get V position on a shape. + \return V position. +*/ +double SMESH::Position::v() const +{ + return myV; +} + +/*! + \brief Set V position on a shape. + \parm v V position. +*/ +void SMESH::Position::setV( double v) +{ + myV = v; + myHasV = true; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESH::XYZ +/// \brief Simple structure to manage 3D coordinate. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Default constructor. +*/ +SMESH::XYZ::XYZ() +{ + myX = myY = myZ = 0.0; +} + +/*! + \brief Base constructor. + \param parameter x X coordinate. + \param parameter y Y coordinate. + \param parameter z Z coordinate. +*/ +SMESH::XYZ::XYZ( double x, double y, double z ) +{ + myX = x; + myY = y; + myZ = z; +} + +/*! + \brief Construction from geometrical point. + \param parameter p Geometrical point. +*/ +SMESH::XYZ::XYZ( const gp_XYZ& p ) +{ + myX = p.X(); + myY = p.Y(); + myZ = p.Z(); +} + +/*! + \brief Add a point. + \param parameter x X coordinate. + \param parameter y Y coordinate. + \param parameter z Z coordinate. +*/ +void SMESH::XYZ::add( double x, double y, double z ) +{ + myX += x; + myY += y; + myZ += z; +} + +/*! + \brief Divide point to given coefficient. + \param parameter a Divider coefficient. +*/ +void SMESH::XYZ::divide( double a ) +{ + if ( a != 0.) + { + myX /= a; + myY /= a; + myZ /= a; + } +} + +/*! + \brief Get X coordinate. + \return X coordinate. +*/ +double SMESH::XYZ::x() const +{ + return myX; +} + +/*! + \brief Get Y coordinate. + \return Y coordinate. +*/ +double SMESH::XYZ::y() const +{ + return myY; +} + +/*! + \brief Get Z coordinate. + \return Z coordinate. +*/ +double SMESH::XYZ::z() const +{ + return myZ; +} + +/*! + \brief Conversion to geometrical point. + \return Geometrical point. +*/ +SMESH::XYZ::operator gp_XYZ() const +{ + return gp_XYZ( myX, myY, myZ ); +} diff --git a/src/SMESHGUI/SMESHGUI_SelectionProxy.h b/src/SMESHGUI/SMESHGUI_SelectionProxy.h new file mode 100644 index 000000000..a7bceefe7 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_SelectionProxy.h @@ -0,0 +1,204 @@ +// Copyright (C) 2007-2016 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 +// +// 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, or (at your option) any later version. +// +// 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 +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef SMESHGUI_SELECTIONPROXY_H +#define SMESHGUI_SELECTIONPROXY_H + +#include "SMESH_SMESHGUI.hxx" + +#include +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(GEOM_Gen) + +#include +#include +#include +#include +#include + +#include + +class SMESH_Actor; + +namespace SMESH +{ + class SMESHGUI_EXPORT MeshInfo + { + QMap myInfo; + public: + MeshInfo(); + uint info( int ) const; + uint operator[] ( int ); + uint count( int, int ) const; + private: + void addInfo( int, long ); + friend class SelectionProxy; + }; + + class SMESHGUI_EXPORT MedInfo + { + QString myFileName; + uint mySize; + uint myMajor, myMinor, myRelease; + public: + MedInfo(); + bool isValid() const; + QString fileName() const; + uint size() const; + QString version() const; + private: + void setFileName( const QString& ); + void setSize( uint ); + void setVersion( uint, uint, uint ); + friend class SelectionProxy; + }; + + class SMESHGUI_EXPORT Position + { + int myShapeId; + int myShapeType; + double myU, myV; + bool myHasU, myHasV; + public: + Position(); + bool isValid() const; + int shapeId() const; + int shapeType() const; + bool hasU() const; + double u() const; + bool hasV() const; + double v() const; + private: + void setShapeId( int ); + void setShapeType( int ); + void setU( double ); + void setV( double ); + friend class SelectionProxy; + }; + + class XYZ + { + double myX, myY, myZ; + public: + XYZ(); + XYZ( double, double, double ); + XYZ( const gp_XYZ& ); + void add( double, double, double ); + void divide( double ); + double x() const; + double y() const; + double z() const; + operator gp_XYZ() const; + }; + + typedef QMap< int, QList > Connectivity; + + class SMESHGUI_EXPORT SelectionProxy + { + Handle(SALOME_InteractiveObject) myIO; + SMESH::SMESH_IDSource_var myObject; + SMESH_Actor* myActor; + bool myDirty; + + public: + enum Type + { + Unknown, + Mesh, + Submesh, + Group, + GroupStd, + GroupGeom, + GroupFilter + }; + + // construction + SelectionProxy(); + SelectionProxy( const Handle(SALOME_InteractiveObject)& ); + SelectionProxy( SMESH::SMESH_IDSource_ptr ); + SelectionProxy( const SelectionProxy& ); + + SelectionProxy& operator= ( const SelectionProxy& ); + + // comparison + bool operator== ( const SelectionProxy& ); + + // general purpose methods + void refresh(); + + bool isNull() const; + operator bool() const; + + SMESH::SMESH_IDSource_ptr object() const; + const Handle(SALOME_InteractiveObject)& io() const; + SMESH_Actor* actor() const; + + bool isValid() const; + void load(); + + // methods common to all types of proxy + QString name() const; + Type type() const; + MeshInfo meshInfo() const; + SelectionProxy mesh() const; + bool hasShapeToMesh() const; + GEOM::GEOM_Object_ptr shape() const; + QString shapeName() const; + int shapeType() const; + bool isMeshLoaded() const; + + bool hasNode( int ); + bool nodeCoordinates( int, XYZ& ); + bool nodeConnectivity( int, Connectivity& ); + bool nodePosition( int, Position& ); + QList nodeGroups( int ) const; + + bool hasElement( int ); + SMESH::ElementType elementType( int ) const; + int elementEntityType( int ) const; + bool elementConnectivity( int, Connectivity& ); + bool perFaceConnectivity( int, Connectivity&, int& ); + bool elementPosition( int, Position& ); + bool elementGravityCenter( int, XYZ& ); + bool elementNormal( int, XYZ& ); + bool elementControl( int, int, double, double& ) const; + QList elementGroups( int ) const; + + // methods that work for mesh only + MedInfo medFileInfo() const; + QList submeshes() const; + QList groups() const; + + // methods that work for group only + SMESH::ElementType groupElementType() const; + QColor color() const; + int size( bool = false ) const; + int nbNodes( bool = false ) const; + QSet ids() const; + + private: + void init(); + }; +} + +#endif // SMESHGUI_SELECTIONPROXY_H diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index ac6bcd036..7cc9294ef 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -1940,7 +1940,7 @@ add the exported data to its contents? Height: - SMESH_HEXAS + SMESH_HEXAHEDRON Hexahedron @@ -2790,7 +2790,7 @@ Check algorithm documentation for supported geometry Symmetry - SMESH_TETRAS + SMESH_TETRAHEDRON Tetrahedron @@ -4551,6 +4551,10 @@ It can't be deleted SMESH_3D_ALGO_GROUP_ADVANCED Advanced + + SMESH_HEX_PRISM + Hexagonal Prism + SMESHGUI_FieldSelectorWdg @@ -5997,6 +6001,10 @@ Please enter correct value and try again LENGTH2D Length 2D + + LENGTH3D + Length 3D + DEFLECTION2D Deflection 2D @@ -7442,7 +7450,7 @@ as they are of improper type: - SMESHGUI_MeshInfo + SMESHGUI_BaseInfo BASE_INFO Base information @@ -7571,6 +7579,18 @@ as they are of improper type: OBJECT_GROUP_BALLS Group of balls + + OBJECT_GROUP_STANDALONE + (standalone) + + + OBJECT_GROUP_GEOM + (on geometry) + + + OBJECT_GROUP_FILTER + (on filter) + BUT_LOAD_MESH Load mesh from server @@ -7606,6 +7626,10 @@ as they are of improper type: ELEM_MODE Element + + GROUP_MODE + Group + SHOW_IDS Show IDs @@ -7637,6 +7661,10 @@ as they are of improper type: COORDINATES Coordinates + + NB_NODES + Nb nodes + CONNECTIVITY Connectivity @@ -7935,6 +7963,18 @@ as they are of improper type: FILE_NAME File name + + FILE_SIZE + Size + + + FILE_VERSION + Version + + + VERSION_UNKNOWN + Unknown + STANDALONE_MESH Standalone diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index b8e73dc1f..562418f91 100755 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -1919,7 +1919,7 @@ les données exportées ? Hauteur : - SMESH_HEXAS + SMESH_HEXAHEDRON Hexaèdre @@ -2765,7 +2765,7 @@ Référez-vous à la documentation sur l'algorithme et la géométrie suppo Symétrie - SMESH_TETRAS + SMESH_TETRAHEDRON Tétraèdre @@ -4519,6 +4519,10 @@ Il ne peut pas être supprimé. SMESH_3D_ALGO_GROUP_ADVANCED Avancé + + SMESH_HEX_PRISM + Prisme hexagonal + SMESHGUI_FieldSelectorWdg @@ -7377,7 +7381,7 @@ en raison de leurs types incompatibles: - SMESHGUI_MeshInfo + SMESHGUI_BaseInfo BASE_INFO Informations de base @@ -7506,6 +7510,18 @@ en raison de leurs types incompatibles: OBJECT_GROUP_BALLS Groupe d'éléments particulaires + + OBJECT_GROUP_STANDALONE + (autonome) + + + OBJECT_GROUP_GEOM + (lié à une géométrie) + + + OBJECT_GROUP_FILTER + (lié à un filtre) + BUT_LOAD_MESH Charger un maillage depuis un serveur @@ -7541,6 +7557,10 @@ en raison de leurs types incompatibles: ELEM_MODE Elément + + GROUP_MODE + Groupe + SHOW_IDS Montre les IDs @@ -7870,6 +7890,14 @@ en raison de leurs types incompatibles: FILE_NAME Nom du fichier + + FILE_SIZE + Taille du fichier + + + FILE_VERSION + Format du fichier + STANDALONE_MESH Autonome diff --git a/src/SMESHGUI/SMESH_msg_ja.ts b/src/SMESHGUI/SMESH_msg_ja.ts index 3b32bdd8c..ca15aebf9 100644 --- a/src/SMESHGUI/SMESH_msg_ja.ts +++ b/src/SMESHGUI/SMESH_msg_ja.ts @@ -1868,7 +1868,7 @@ 高さ: - SMESH_HEXAS + SMESH_HEXAHEDRON 六面体 @@ -2704,7 +2704,7 @@ オブジェクトの反転 - SMESH_TETRAS + SMESH_TETRAHEDRON 四面体 @@ -4427,6 +4427,10 @@ SMESH_3D_ALGO_GROUP_ADVANCED アドバンス + + SMESH_HEX_PRISM + 六角形プリズム + SMESHGUI_FieldSelectorWdg @@ -7202,7 +7206,7 @@ - SMESHGUI_MeshInfo + SMESHGUI_BaseInfo BASE_INFO 基本情報 @@ -7331,6 +7335,18 @@ OBJECT_GROUP_BALLS 粒子状物質の要素のグループ + + OBJECT_GROUP_STANDALONE + (standalone) + + + OBJECT_GROUP_GEOM + (on geometry) + + + OBJECT_GROUP_FILTER + (on filter) + BUT_LOAD_MESH サーバーからメッシュをロード @@ -7366,6 +7382,10 @@ ELEM_MODE 要素 + + GROUP_MODE + Group + SHOW_IDS IDの表示 @@ -7695,6 +7715,14 @@ FILE_NAME ファイルの名前 + + FILE_SIZE + Size + + + FILE_VERSION + Version + STANDALONE_MESH 自律 diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 7a9b20bd3..7f3c7a6ab 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -217,6 +217,11 @@ CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId ) return myNumericalFunctorPtr->GetValue( theId ); } +CORBA::Boolean NumericalFunctor_i::IsApplicable( CORBA::Long theElementId ) +{ + return myNumericalFunctorPtr->IsApplicable( theElementId ); +} + SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic) { std::vector nbEvents; @@ -521,6 +526,46 @@ SMESH::Length2D::Values* Length2D_i::GetValues() return aResult._retn(); } + +/* + Class : Length3D_i + Description : Functor for calculating length of edge +*/ +Length3D_i::Length3D_i() +{ + myNumericalFunctorPtr.reset( new Controls::Length3D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType Length3D_i::GetFunctorType() +{ + return SMESH::FT_Length3D; +} + +// SMESH::Length3D::Values* Length3D_i::GetValues() +// { +// SMESH::Controls::Length3D::TValues aValues; +// (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + +// long i = 0, iEnd = aValues.size(); + +// SMESH::Length3D::Values_var aResult = new SMESH::Length3D::Values(iEnd); +// aResult->length(iEnd); + +// SMESH::Controls::Length3D::TValues::const_iterator anIter; +// for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) +// { +// const SMESH::Controls::Length3D::Value& aVal = *anIter; +// SMESH::Length3D::Value &aValue = aResult[ i ]; + +// aValue.myLength = aVal.myLength; +// aValue.myPnt1 = aVal.myPntId[ 0 ]; +// aValue.myPnt2 = aVal.myPntId[ 1 ]; +// } + +// return aResult._retn(); +// } + /* Class : Deflection2D_i Description : Functor for calculating distance between a face and geometry @@ -2107,11 +2152,19 @@ Length2D_ptr FilterManager_i::CreateLength2D() return anObj._retn(); } +Length3D_ptr FilterManager_i::CreateLength3D() +{ + SMESH::Length3D_i* aServant = new SMESH::Length3D_i(); + SMESH::Length3D_var anObj = aServant->_this(); + TPythonDump()<_this(); - TPythonDump()<CreateLength2D(); break; + case SMESH::FT_Length3D: + aFunctor = aFilterMgr->CreateLength3D(); + break; case SMESH::FT_Deflection2D: aFunctor = aFilterMgr->CreateDeflection2D(); break; @@ -3489,6 +3545,7 @@ static inline LDOMString toString( CORBA::Long theType ) case FT_MultiConnection2D : return "Borders at multi-connections 2D"; case FT_Length : return "Length"; case FT_Length2D : return "Length 2D"; + case FT_Length3D : return "Length 3D"; case FT_Deflection2D : return "Deflection 2D"; case FT_LessThan : return "Less than"; case FT_MoreThan : return "More than"; @@ -3538,6 +3595,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) // else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D; else if ( theStr.equals( "Length" ) ) return FT_Length; // else if ( theStr.equals( "Length2D" ) ) return FT_Length2D; + // else if ( theStr.equals( "Length3D" ) ) return FT_Length3D; else if ( theStr.equals( "Deflection" ) ) return FT_Deflection2D; else if ( theStr.equals( "Range of IDs" ) ) return FT_RangeOfIds; else if ( theStr.equals( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume; @@ -4104,6 +4162,7 @@ static const char** getFunctNames() "FT_MultiConnection2D", "FT_Length", "FT_Length2D", + "FT_Length3D", "FT_Deflection2D", "FT_NodeConnectivityNumber", "FT_BelongToMeshGroup", diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx index 9d976ef08..72d0c3c10 100644 --- a/src/SMESH_I/SMESH_Filter_i.hxx +++ b/src/SMESH_I/SMESH_Filter_i.hxx @@ -99,6 +99,7 @@ namespace SMESH { public: CORBA::Double GetValue( CORBA::Long theElementId ); + CORBA::Boolean IsApplicable( CORBA::Long theElementId ); SMESH::Histogram* GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic); SMESH::Histogram* GetLocalHistogram(CORBA::Short nbIntervals, @@ -271,6 +272,22 @@ namespace SMESH Controls::Length2DPtr myLength2DPtr; }; + /* + Class : Length3D_i + Description : Functor for calculating length of edge + */ + class SMESH_I_EXPORT Length3D_i: public virtual POA_SMESH::Length3D, + public virtual NumericalFunctor_i + { + public: + Length3D_i(); + //SMESH::Length2D::Values* GetValues(); + FunctorType GetFunctorType(); + + protected: + Controls::Length3DPtr myLength3DPtr; + }; + /* Class : Deflection2D_i Description : Functor for calculating distance between a face and geometry @@ -1103,6 +1120,7 @@ namespace SMESH MaxElementLength3D_ptr CreateMaxElementLength3D(); Length_ptr CreateLength(); Length2D_ptr CreateLength2D(); + Length3D_ptr CreateLength3D(); Deflection2D_ptr CreateDeflection2D(); NodeConnectivityNumber_ptr CreateNodeConnectivityNumber(); MultiConnection_ptr CreateMultiConnection(); diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 016bf658b..c61a7da9d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -4720,8 +4720,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) ) { aResult->length( elem->NbNodes() ); - for ( int i = 0; i < elem->NbNodes(); ++i ) - aResult[ i ] = elem->GetNode( i )->GetID(); + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) + if ( const SMDS_MeshNode* n = elem->GetNode( i )) + aResult[ i ] = n->GetID(); } } return aResult._retn(); @@ -4837,7 +4838,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, { if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) ) { - SMDS_VolumeTool vtool( elem ); + SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false ); if ( faceIndex < vtool.NbFaces() ) { aResult->length( vtool.NbFaceNodes( faceIndex )); diff --git a/src/SMESH_I/SMESH_PythonDump.cxx b/src/SMESH_I/SMESH_PythonDump.cxx index 76a23315a..4b48c7beb 100644 --- a/src/SMESH_I/SMESH_PythonDump.cxx +++ b/src/SMESH_I/SMESH_PythonDump.cxx @@ -426,6 +426,7 @@ namespace SMESH case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break; case FT_Length: myStream<< "aLength"; break; case FT_Length2D: myStream<< "aLength2D"; break; + case FT_Length3D: myStream<< "aLength3D"; break; case FT_Deflection2D: myStream<< "aDeflection2D"; break; case FT_NodeConnectivityNumber:myStream<< "aNodeConnectivityNumber";break; case FT_BelongToMeshGroup: myStream<< "aBelongToMeshGroup"; break;