X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_MeshInfo.cxx;h=d040c01cf0ea3f9afb86dd2183f9c4e4df90f4b2;hp=574fd58a9a7e40e9bc07d4dfe5b667addaedf59a;hb=e26ffcc005221f12d4ff91e074c4c8464ca044e4;hpb=15006895772bd79abdcbee0cd22d8bb80a21e1c4 diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 574fd58a9..d040c01cf 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 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 @@ -6,7 +6,7 @@ // 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. +// 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 @@ -24,17 +24,19 @@ #include "SMESHGUI_MeshInfo.h" -#include "SMESH_Actor.h" -#include "SMESHGUI.h" -#include "SMESHGUI_IdValidator.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" #include "SMDSAbs_ElementType.hxx" -#include "SMDS_Mesh.hxx" #include "SMDS_BallElement.hxx" #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" +#include "SMDS_Mesh.hxx" #include "SMESHDS_Mesh.hxx" +#include "SMESHGUI.h" +#include "SMESHGUI_FilterUtils.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESH_Actor.h" #include #include @@ -59,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +73,8 @@ #include #include CORBA_SERVER_HEADER(GEOM_Gen) +namespace { + const int SPACING = 6; const int MARGIN = 9; const int MAXITEMS = 10; @@ -86,12 +91,12 @@ enum InfoType { NodeConnectivity = 100, ElemConnectivity, }; +} // namesapce /*! \class ExtraWidget \internal */ - class ExtraWidget : public QWidget { public: @@ -461,27 +466,13 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) 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; + 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 ); } @@ -497,7 +488,7 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; - myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) ); + myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic )); myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) ); myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) ); myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) ); @@ -2244,7 +2235,7 @@ void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* pa { // type GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh(); - SMESH::MedFileInfo* inf = mesh->GetMEDFileInfo(); + SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo(); QTreeWidgetItem* typeItem = createItem( parent, Bold ); typeItem->setText( 0, tr( "TYPE" ) ); if ( !CORBA::is_nil( shape ) ) { @@ -2999,9 +2990,9 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* 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 ); // name QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); @@ -3009,54 +3000,109 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) 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* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this ); QLabel* aNodesFree = createField(); myWidgets << aNodesFree; + myPredicates << aFilterMgr->CreateFreeNodes(); + // QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this ); QLabel* aNodesDouble = createField(); 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 ) ); // edges info QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this ); QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this ); QLabel* anEdgesDouble = createField(); myWidgets << anEdgesDouble; + myPredicates << aFilterMgr->CreateEqualEdges(); // faces info QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this ); QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this ); QLabel* aFacesDouble = createField(); myWidgets << aFacesDouble; + myPredicates << aFilterMgr->CreateEqualFaces(); QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this ); QLabel* aFacesOver = createField(); myWidgets << aFacesOver; + myPredicates << aFilterMgr->CreateOverConstrainedFace(); QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this ); myPlot = createPlot( this ); + myAspectRatio = aFilterMgr->CreateAspectRatio(); // volumes info QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this ); QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this ); QLabel* aVolumesDouble = createField(); myWidgets << aVolumesDouble; + myPredicates << aFilterMgr->CreateEqualVolumes(); QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this ); QLabel* aVolumesOver = createField(); myWidgets << aVolumesOver; + myPredicates << aFilterMgr->CreateOverConstrainedVolume(); QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this ); myPlot3D = createPlot( this ); - - myComputeFaceBtn = new QPushButton( tr( "BUT_COMPUTE" ), this ); - myComputeFaceBtn->setAutoDefault( true ); - myComputeFaceBtn->setFixedWidth( 80 ); - myComputeFaceBtn->setVisible( false ); - myComputeVolumeBtn = new QPushButton( tr( "BUT_COMPUTE" ), this ); - myComputeVolumeBtn->setAutoDefault( true ); - myComputeVolumeBtn->setFixedWidth( 80 ); - myComputeVolumeBtn->setVisible( false ); - - connect( myComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeFaceInfo() ) ); - connect( myComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeVolumeInfo() ) ); + myAspectRatio3D = aFilterMgr->CreateAspectRatio3D(); + + QToolButton* aFreeNodesBtn = new QToolButton( this ); + aFreeNodesBtn->setIcon(aComputeIcon); + myButtons << aFreeNodesBtn; //0 + + QToolButton* aDoubleNodesBtn = new QToolButton( this ); + aDoubleNodesBtn->setIcon(aComputeIcon); + myButtons << aDoubleNodesBtn; //1 + + QToolButton* aDoubleEdgesBtn = new QToolButton( this ); + aDoubleEdgesBtn->setIcon(aComputeIcon); + myButtons << aDoubleEdgesBtn; //2 + + QToolButton* aDoubleFacesBtn = new QToolButton( this ); + aDoubleFacesBtn->setIcon(aComputeIcon); + myButtons << aDoubleFacesBtn; //3 + + QToolButton* aOverContFacesBtn = new QToolButton( this ); + aOverContFacesBtn->setIcon(aComputeIcon); + myButtons << aOverContFacesBtn; //4 + + QToolButton* aComputeFaceBtn = new QToolButton( this ); + aComputeFaceBtn->setIcon(aComputeIcon); + myButtons << aComputeFaceBtn; //5 + + QToolButton* aDoubleVolumesBtn = new QToolButton( this ); + aDoubleVolumesBtn->setIcon(aComputeIcon); + myButtons << aDoubleVolumesBtn; //6 + + QToolButton* aOverContVolumesBtn = new QToolButton( this ); + aOverContVolumesBtn->setIcon(aComputeIcon); + myButtons << aOverContVolumesBtn; //7 + + QToolButton* aComputeVolumeBtn = new QToolButton( this ); + aComputeVolumeBtn->setIcon(aComputeIcon); + myButtons << aComputeVolumeBtn; //8 + + connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) ); + connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) ); + connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) ); + 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 ); @@ -3064,37 +3110,47 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) setFontAttributes( aFacesLab ); setFontAttributes( aVolumesLab ); - l->addWidget( aNameLab, 0, 0 ); - l->addWidget( aName, 0, 1 ); - l->addWidget( aNodesLab, 1, 0, 1, 2 ); - l->addWidget( aNodesFreeLab, 2, 0 ); - l->addWidget( aNodesFree, 2, 1 ); - l->addWidget( aNodesDoubleLab, 3, 0 ); - l->addWidget( aNodesDouble, 3, 1 ); - l->addWidget( anEdgesLab, 4, 0, 1, 2 ); - l->addWidget( anEdgesDoubleLab, 5, 0 ); - l->addWidget( anEdgesDouble, 5, 1 ); - l->addWidget( aFacesLab, 6, 0, 1, 2 ); - l->addWidget( aFacesDoubleLab, 7, 0 ); - l->addWidget( aFacesDouble, 7, 1 ); - l->addWidget( aFacesOverLab, 8, 0 ); - l->addWidget( aFacesOver, 8, 1 ); - l->addWidget( anAspectRatioLab, 9, 0 ); - l->addWidget( myComputeFaceBtn, 9, 1 ); - l->addWidget( myPlot, 10, 0, 1, 2 ); - l->addWidget( aVolumesLab, 11, 0, 1, 2 ); - l->addWidget( aVolumesDoubleLab, 12, 0 ); - l->addWidget( aVolumesDouble, 12, 1 ); - l->addWidget( aVolumesOverLab, 13, 0 ); - l->addWidget( aVolumesOver, 13, 1 ); - l->addWidget( anAspectRatio3DLab, 14, 0 ); - l->addWidget( myComputeVolumeBtn, 14, 1 ); - l->addWidget( myPlot3D, 15, 0, 1, 2 ); + 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( aNodesDoubleLab, 3, 0 ); //6 + myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7 + myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8 + myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9 + myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10 + myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11 + myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12 + myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13 + myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14 + myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15 + myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16 + myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17 + myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18 + myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19 + myMainLayout->addWidget( aFacesOver, 9, 1 ); //20 + myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21 + myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22 + myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23 + myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24 + myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25 + myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26 + myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27 + myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28 + myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28 + myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30 + myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31 + myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32 + myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33 + myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34 - l->setColumnStretch( 0, 0 ); - l->setColumnStretch( 1, 5 ); - l->setRowStretch ( 10, 5 ); - l->setRowStretch ( 15, 5 ); + myMainLayout->setColumnStretch( 0, 0 ); + myMainLayout->setColumnStretch( 1, 5 ); + myMainLayout->setRowStretch ( 11, 5 ); + myMainLayout->setRowStretch ( 16, 5 ); + myMainLayout->setRowStretch ( 17, 1 ); clearInternal(); } @@ -3103,8 +3159,7 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) \brief Destructor */ SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo() -{ -} +{} /*! \brief Change widget font attributes (bold, ...). @@ -3155,162 +3210,215 @@ QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent ) return aPlot; } - /*! \brief Show controls information on the selected object */ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) { clearInternal(); - SMESH::long_array_var anElems; - long ctrlLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ); - if ( CORBA::is_nil( obj ) ) return; - _PTR(SObject) aSO = SMESH::FindSObject( obj ); - if ( !aSO ) return; - myWidgets[0]->setText( aSO->GetName().c_str() ); - - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); - if ( selected.Extent() < 1 ) return; - Handle(SALOME_InteractiveObject) IO = selected.First(); - SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() ); - if ( !anActor ) anActor = SMESH::CreateActor( aSO->GetStudy(), aSO->GetID().c_str(), true ); - if ( !anActor ) return; + myObject = SMESH::SMESH_IDSource::_duplicate( obj ); + if ( myObject->_is_nil() ) return; + + if ( _PTR(SObject) aSO = SMESH::FindSObject( obj )) + myWidgets[0]->setText( aSO->GetName().c_str() ); + + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( mesh->_is_nil() ) return; + + const bool meshLoaded = mesh->IsLoaded(); + if ( !meshLoaded ) // mesh not yet loaded from the hdf file + // enable Compute buttons, just in case obj->GetNbElementsByType() fails + for ( int i = 0; i < myButtons.count(); ++i ) + myButtons[i]->setEnabled( true ); - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); - if ( aMesh->_is_nil() ) return; + SMESH::long_array_var nbElemsByType = obj->GetNbElementsByType(); + if ( ! &nbElemsByType.in() ) return; - SMESH::Controls::FunctorPtr aFunctor; + const CORBA::Long ctrlLimit = + meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1; // nodes info - if ( aMesh->NbNodes() ) { - // free nodes - aFunctor.reset( new SMESH::Controls::FreeNodes() ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - anElems = aMesh->GetElementsByType( SMESH::NODE ); - myWidgets[1]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); - // double nodes - SMESH::Controls::CoincidentNodes* aNodes = new SMESH::Controls::CoincidentNodes(); - double tol = SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ); - aNodes->SetTolerance( tol ); - aFunctor.reset( aNodes ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - myWidgets[2]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); + const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ]; + const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] + + nbElemsByType[ SMESH::FACE ] + + nbElemsByType[ SMESH::VOLUME ] ); + if ( nbNodes + nbElems > 0 ) { + if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) { + // free nodes + computeFreeNodesInfo(); + // double nodes + computeDoubleNodesInfo(); + } + else { + myButtons[0]->setEnabled( true ); + myButtons[1]->setEnabled( true ); + } + } + else { + for( int i=2; i<=10; i++) + myMainLayout->itemAt(i)->widget()->setVisible( false ); } // edges info - if ( aMesh->NbEdges() ) { + if ( nbElemsByType[ SMESH::EDGE ] > 0 ) { // double edges - aFunctor.reset( new SMESH::Controls::CoincidentElements1D() ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - anElems = aMesh->GetElementsByType( SMESH::EDGE ); - myWidgets[3]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); + if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit ) + computeDoubleEdgesInfo(); + else + myButtons[2]->setEnabled( true ); + } + else { + for( int i=11; i<=14; i++) + myMainLayout->itemAt(i)->widget()->setVisible( false ); } // faces info - if ( aMesh->NbFaces() ) { - // double faces - aFunctor.reset( new SMESH::Controls::CoincidentElements2D() ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - anElems = aMesh->GetElementsByType( SMESH::FACE ); - myWidgets[4]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); - // over constrained faces - aFunctor.reset( new SMESH::Controls::OverConstrainedFace() ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - myWidgets[5]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); - // aspect Ratio histogram - if ( aMesh->NbFaces() <= ctrlLimit ) - computeFaceInfo(); - else - myComputeFaceBtn->setVisible( true ); + if ( nbElemsByType[ SMESH::FACE ] > 0 ) { + if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) { + // double faces + computeDoubleFacesInfo(); + // over constrained faces + computeOverConstrainedFacesInfo(); + // aspect Ratio histogram + computeAspectRatio(); + } + else { + myButtons[3]->setEnabled( true ); + myButtons[4]->setEnabled( true ); + myButtons[5]->setEnabled( true ); + } + } + else { + myMainLayout->setRowStretch(11,0); + for( int i=15; i<=24; i++) + myMainLayout->itemAt(i)->widget()->setVisible( false ); } // volumes info - if ( aMesh->NbVolumes() ) { - // double volumes - aFunctor.reset( new SMESH::Controls::CoincidentElements3D() ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - anElems = aMesh->GetElementsByType( SMESH::VOLUME ); - myWidgets[6]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); - // over constrained volumes - aFunctor.reset( new SMESH::Controls::OverConstrainedVolume() ); - aFunctor->SetMesh( anActor->GetObject()->GetMesh() ); - myWidgets[7]->setText( QString::number( nbElemsControl( anElems, aFunctor ) ) ); - // aspect Ratio 3D histogram - if ( aMesh->NbVolumes() <= ctrlLimit ) - computeVolumeInfo(); - else - myComputeVolumeBtn->setVisible( true ); + if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) { + if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) { + // double volumes + computeDoubleVolumesInfo(); + // over constrained volumes + computeOverConstrainedVolumesInfo(); + // aspect Ratio 3D histogram + computeAspectRatio3D(); + } + else { + myButtons[6]->setEnabled( true ); + myButtons[7]->setEnabled( true ); + myButtons[8]->setEnabled( true ); + } + } + else { + myMainLayout->setRowStretch(16,0); + for( int i=25; i<=34; i++) + myMainLayout->itemAt(i)->widget()->setVisible( false ); } } -void SMESHGUI_CtrlInfo::computeFaceInfo() { - myComputeFaceBtn->setVisible( false ); +//================================================================================ +/*! + * \brief Computes and shows nb of elements satisfying a given predicate + * \param [in] ft - a predicate type (SMESH::FunctorType) + * \param [in] iBut - index of one of myButtons to disable + * \param [in] iWdg - index of one of myWidgets to show the computed number + */ +//================================================================================ + +void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg ) +{ + myButtons[ iBut ]->setEnabled( false ); + myWidgets[ iWdg ]->setText( "" ); + if ( myObject->_is_nil() ) return; SUIT_OverrideCursor wc; - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); - if ( selected.Extent() < 1 ) return; - SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( selected.First() ); - if ( CORBA::is_nil( obj ) ) return; - _PTR(SObject) aSO = SMESH::FindSObject( obj ); - if ( !aSO ) return; - SMESH_Actor* anActor = SMESH::FindActorByEntry( selected.First()->getEntry() ); - if ( !anActor ) anActor = SMESH::CreateActor( aSO->GetStudy(), aSO->GetID().c_str(), true ); - if ( !anActor ) return; - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); - if ( aMesh->_is_nil() ) return; - - SMESH::long_array_var anElems; - anElems = aMesh->GetElementsByType( SMESH::FACE ); - SMESH::Controls::NumericalFunctorPtr anAspectRatio( new SMESH::Controls::AspectRatio() ); - int cprecision = 6; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ) - cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); - anAspectRatio->SetPrecision( cprecision ); - anAspectRatio->SetMesh( anActor->GetObject()->GetMesh() ); - Plot2d_Histogram* aHistogram = getHistogram( anElems, anAspectRatio ); - - if ( !aHistogram->isEmpty() ) { + + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( !mesh->_is_nil() && !mesh->IsLoaded() ) + { + mesh->Load(); + this->showInfo( myObject ); // try to show all values + if ( !myWidgets[ iWdg ]->text().isEmpty() ) + return; // predicate already computed + } + // look for a predicate of type + 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 )); + } +} + +void SMESHGUI_CtrlInfo::computeFreeNodesInfo() +{ + computeNb( SMESH::FT_FreeNodes, 0, 1 ); +} + +void SMESHGUI_CtrlInfo::computeDoubleNodesInfo() +{ + computeNb( SMESH::FT_EqualNodes, 1, 2 ); +} + +void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo() +{ + computeNb( SMESH::FT_EqualEdges, 2, 3 ); +} + +void SMESHGUI_CtrlInfo::computeDoubleFacesInfo() +{ + computeNb( SMESH::FT_EqualFaces, 3, 4 ); +} + +void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo() +{ + computeNb( SMESH::FT_OverConstrainedFace, 4, 5 ); +} + +void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo() +{ + computeNb( SMESH::FT_EqualVolumes, 6, 6 ); +} + +void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo() +{ + computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 ); +} + +void SMESHGUI_CtrlInfo::computeAspectRatio() +{ + myButtons[5]->setEnabled( false ); + + if ( myObject->_is_nil() ) return; + + SUIT_OverrideCursor wc; + + Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio ); + if ( aHistogram && !aHistogram->isEmpty() ) { QwtPlotItem* anItem = aHistogram->createPlotItem(); anItem->attach( myPlot ); myPlot->replot(); } + delete aHistogram; } -void SMESHGUI_CtrlInfo::computeVolumeInfo() { - myComputeVolumeBtn->setVisible( false ); +void SMESHGUI_CtrlInfo::computeAspectRatio3D() +{ + myButtons[8]->setEnabled( false ); + + if ( myObject->_is_nil() ) return; SUIT_OverrideCursor wc; - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); - if ( selected.Extent() < 1 ) return; - SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( selected.First() ); - if ( CORBA::is_nil( obj ) ) return; - _PTR(SObject) aSO = SMESH::FindSObject( obj ); - if ( !aSO ) return; - SMESH_Actor* anActor = SMESH::FindActorByEntry( selected.First()->getEntry() ); - if ( !anActor ) anActor = SMESH::CreateActor( aSO->GetStudy(), aSO->GetID().c_str(), true ); - if ( !anActor ) return; - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); - if ( aMesh->_is_nil() ) return; - - SMESH::long_array_var anElems; - anElems = aMesh->GetElementsByType( SMESH::VOLUME ); - SMESH::Controls::NumericalFunctorPtr anAspectRatio3D( new SMESH::Controls::AspectRatio3D() ); - int cprecision = 6; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ) - cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); - anAspectRatio3D->SetPrecision( cprecision ); - anAspectRatio3D->SetMesh( anActor->GetObject()->GetMesh() ); - Plot2d_Histogram* aHistogram = getHistogram( anElems, anAspectRatio3D ); - - if ( !aHistogram->isEmpty() ) { + + Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D ); + if ( aHistogram && !aHistogram->isEmpty() ) { QwtPlotItem* anItem = aHistogram->createPlotItem(); anItem->attach( myPlot3D ); myPlot3D->replot(); } + delete aHistogram; } /*! @@ -3318,49 +3426,55 @@ void SMESHGUI_CtrlInfo::computeVolumeInfo() { */ void SMESHGUI_CtrlInfo::clearInternal() { - myComputeFaceBtn->setVisible( false ); - myComputeVolumeBtn->setVisible( false ); + for( int i=0; i<=34; i++) + myMainLayout->itemAt(i)->widget()->setVisible( true ); + for( int i=0; i<=8; i++) + myButtons[i]->setEnabled( false ); myPlot->detachItems(); myPlot3D->detachItems(); myPlot->replot(); myPlot3D->replot(); myWidgets[0]->setText( QString() ); for ( int i = 1; i < myWidgets.count(); i++ ) - myWidgets[i]->setText( QString::number( 0 ) ); + myWidgets[i]->setText( "" ); + myMainLayout->setRowStretch(11,5); + myMainLayout->setRowStretch(16,5); } -int SMESHGUI_CtrlInfo::nbElemsControl( SMESH::long_array_var& elems, SMESH::Controls::FunctorPtr theFunctor ) { - int nbElems = 0; - for( int i = 0; i < elems->length(); i++ ) { - if ( SMESH::Controls::Predicate* aPredicate = dynamic_cast( theFunctor.get() ) ) - if ( aPredicate->IsSatisfy( elems[i] ) ) nbElems++; - } - return nbElems; +void SMESHGUI_CtrlInfo::setTolerance( double theTolerance ) +{ + //SMESH::long_array_var anElems = getElementsByType( SMESH::NODE ); + myButtons[1]->setEnabled( true ); + myWidgets[2]->setText(""); } -Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::long_array_var& elems, SMESH::Controls::NumericalFunctorPtr aNumFun ) { - Plot2d_Histogram* aHistogram = new Plot2d_Histogram(); - std::vector elements; - elements.resize( elems->length() ); - for ( unsigned i = 0; i < elements.size(); i++ ) - elements[i] = elems[i]; +Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun ) +{ + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( mesh->_is_nil() ) return 0; + if ( !mesh->IsLoaded() ) + mesh->Load(); + aNumFun->SetMesh( mesh ); + + CORBA::Long cprecision = 6; + if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ) + cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); + aNumFun->SetPrecision( cprecision ); + int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false ); - double* range = new double[2]; - range[0] = aNumFun->GetValue( elems[0] ); - range[1] = aNumFun->GetValue( elems[0] ); - for( int i = 1; i < elems->length(); i++ ) { - if ( range[0] > aNumFun->GetValue( elems[i] ) ) range[0] = aNumFun->GetValue( elems[i] ); - if ( range[1] < aNumFun->GetValue( elems[i] ) ) range[1] = aNumFun->GetValue( elems[i] ); - } - std::vector nbEvents; - std::vector funValues; - aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, range ); - for ( int i = 0; i < std::min( nbEvents.size(), funValues.size() -1 ); i++ ) - aHistogram->addPoint( funValues[i] + ( funValues[i+1] - funValues[i] ) / 2.0, static_cast( nbEvents[i] ) ); - if ( funValues.size() >= 2 ) - aHistogram->setWidth( ( funValues[1] - funValues[0] ) * 0.8 ); - aHistogram->setColor( palette().color( QPalette::Highlight ) ); + SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals, + /*isLogarithmic=*/false, + myObject ); + Plot2d_Histogram* aHistogram = new Plot2d_Histogram(); + aHistogram->setColor( palette().color( QPalette::Highlight ) ); + if ( &histogramVar.in() ) + { + for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ ) + aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents ); + if ( histogramVar->length() >= 2 ) + aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 ); + } return aHistogram; } @@ -3406,16 +3520,29 @@ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) okBtn->setAutoDefault( true ); okBtn->setDefault( true ); okBtn->setFocus(); + QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this ); + dumpBtn->setAutoDefault( true ); + QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); + helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setSpacing( SPACING ); + btnLayout->setMargin( 0 ); - QGridLayout* l = new QGridLayout ( this ); + btnLayout->addWidget( okBtn ); + btnLayout->addWidget( dumpBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( helpBtn ); + + QVBoxLayout* l = new QVBoxLayout ( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); - l->addWidget( myCtrlInfo, 0, 0, 1, 3 ); - l->addWidget( okBtn, 1, 1 ); - l->setColumnStretch( 0, 5 ); - l->setColumnStretch( 2, 5 ); + l->addWidget( myCtrlInfo ); + l->addLayout( btnLayout ); - connect( okBtn, SIGNAL( clicked() ), 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() ) ); @@ -3494,4 +3621,49 @@ void SMESHGUI_CtrlInfoDlg::deactivate() disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); } +/*! + * \brief Dump contents into a file + */ +void SMESHGUI_CtrlInfoDlg::dump() +{ + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() ); + if ( !appStudy ) return; + _PTR( Study ) aStudy = appStudy->studyDS(); + + QStringList aFilters; + aFilters.append( tr( "TEXT_FILES" ) ); + + DumpFileDlg fd( this ); + fd.setWindowTitle( tr( "SAVE_INFO" ) ); + fd.setFilters( aFilters ); + fd.myBaseChk->hide(); + fd.myElemChk->hide(); + fd.myAddChk ->hide(); + fd.myCtrlChk->hide(); + if ( fd.exec() == QDialog::Accepted ) + { + QString aFileName = fd.selectedFile(); + if ( !aFileName.isEmpty() ) { + QFileInfo aFileInfo( aFileName ); + if ( aFileInfo.isDir() ) + return; + + QFile aFile( aFileName ); + if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) + return; + + QTextStream out( &aFile ); + myCtrlInfo->saveInfo( out ); + } + } +} +/*! + * \brief Show help + */ +void SMESHGUI_CtrlInfoDlg::help() +{ + SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor"); +}