0020976: EDF 1471 SMESH: New ergonomy to display quality controls

fix v1
This commit is contained in:
kga 2013-06-19 07:46:33 +00:00
parent 51aa4c4a2d
commit 14570f80e3
10 changed files with 841 additions and 10 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -15,11 +15,13 @@ in the toolbar.
The <b>Mesh Information</b> dialog box provides three tab pages:
- <b>\ref advanced_mesh_infos_anchor "Base Info"</b> - to show base
information about the selected mesh object
information about the selected mesh object.
- <b>\ref mesh_element_info_anchor "Element Info"</b> - to show
detailed information about the selected mesh node or element.
- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show additional information available
for the selected mesh, sub-mesh or group object.
- <b>\ref mesh_quality_info_anchor "Quality Info"</b> - to show
overall quality information about the selected mesh, sub-mesh or group object.
\anchor advanced_mesh_infos_anchor
<h2>Base Information</h2>
@ -119,6 +121,36 @@ automatically calculated if the size of the group does not exceed
the "Automatic nodes compute limit" set via the "Mesh information"
preferences (zero value means no limit).
\anchor mesh_quality_info_anchor
<h2>Quality Information</h2>
The <b>Quality Info</b> tab page of the dialog box provides overal
mesh quality controls information on the selected object - mesh,
sub-mesh or mesh group:
- Name;
- Nodes information:
- Number of the free nodes;
- Number of double nodes;
- Edges information:
- Number of double edges;
- Faces information:
- Number of double faces;
- Number of over-constrained faces;
- Aspect Ratio histogram;
- Volume information:
- Number of double volumes;
- Number of over-constrained volumes;
- Aspect Ratio 3D histogram.
<center>\image html ctrlinfo.png
<em>"Quality Info" page</em></center>
\note For the perfomance reason, the Aspect Ratio histogram for the big meshes is
computed only by demand. For this, the user should press the "Compute"
button (see picture). Also, histogram is automatically computed if the size of the
elements does not exceed the "Automatic controls compute limit" set
via the "Mesh information" preferences (zero value means no limit).
The button \b "Dump" allows printing the information displayed in the
dialog box to a .txt file.

View File

@ -74,6 +74,12 @@ automatically. If the group size exceeds the value set in the preferences,
the user will have to press \em Compute button explicitly. Zero value
means "no limit". By default the value is set to 100 000 mesh elements.
</li>
<li><b>Automatic controls compute limit</b></li> - allows to define the size limit for the
mesh elements for which the Aspect Ratio histogram is calculated
automatically. If the mesh elements size exceeds the value set in the preferences,
the user will have to press \em Compute button explicitly. Zero value
means "no limit". By default the value is set to 3 000 mesh elements.
</li>
<li><b>Show details on groups in element information tab</b> - when
this option is switched off (default), only the names of groups, to which the node
or element belongs, are shown in the \ref mesh_element_info_anchor "Info Tab"
@ -85,6 +91,8 @@ file, see \ref mesh_infos_page.</li>
file, see \ref mesh_infos_page.</li>
<li><b>Dump additional information</b> - allows to dump additional mesh
information to the file, see \ref mesh_infos_page.</li>
<li><b>Dump controls information</b> - allows to dump quality mesh
information to the file, see \ref mesh_infos_page.</li>
</ul>
<li><b>Automatic Parameters</b></li>
<ul>

View File

@ -85,9 +85,11 @@
<parameter name="mesh_elem_info" value="1"/>
<parameter name="elem_info_grp_details" value="false"/>
<parameter name="info_groups_nodes_limit" value="100000"/>
<parameter name="info_controls_limit" value="3000"/>
<parameter name="info_dump_base" value="true" />
<parameter name="info_dump_elem" value="true" />
<parameter name="info_dump_add" value="true" />
<parameter name="info_dump_ctrl" value="true" />
<parameter name="segmentation" value="10"/>
<parameter name="nb_segments_per_edge" value="15"/>
<parameter name="forget_mesh_on_hyp_modif" value="true"/>

View File

@ -996,6 +996,22 @@
SMESH::RepaintCurrentView();
}
void OverallMeshQuality() {
SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
SALOME_ListIO selected;
if( aSel )
aSel->selectedObjects( selected );
if ( selected.IsEmpty() ) return;
SALOME_ListIteratorOfListIO It( selected );
for ( ; It.More(); It.Next() ) {
SMESHGUI_CtrlInfoDlg* ctrlDlg = new SMESHGUI_CtrlInfoDlg( SMESHGUI::desktop() );
ctrlDlg->showInfo( It.Value() );
ctrlDlg->show();
}
}
QString functorToString( SMESH::Controls::FunctorPtr f )
{
QString type = QObject::tr( "UNKNOWN_CONTROL" );
@ -3403,6 +3419,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
tr( "NOT_A_VTK_VIEWER" ) );
}
break;
case 6032:
OverallMeshQuality();
break;
case 9010:
{
LightApp_SelectionMgr* mgr = selectionMgr();
@ -3630,6 +3649,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 6029, "EQUAL_EDGE", "ICON_EQUAL_EDGE", 0, true );
createSMESHAction( 6030, "EQUAL_FACE", "ICON_EQUAL_FACE", 0, true );
createSMESHAction( 6031, "EQUAL_VOLUME", "ICON_EQUAL_VOLUME", 0, true );
createSMESHAction( 6032, "OVERALL_MESH_QUALITY" );
createSMESHAction( 6003, "FREE_BORDER", "ICON_FREE_EDGE_2D", 0, true );
createSMESHAction( 6004, "CONNECTION", "ICON_CONNECTION", 0, true );
createSMESHAction( 6005, "FREE_NODE", "ICON_FREE_NODE", 0, true );
@ -3841,6 +3861,8 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 6024, volumeId, -1 );
createMenu( 6026, volumeId, -1 );
createMenu( 6031, volumeId, -1 );
createMenu( separator(), ctrlId, -1 );
createMenu( 6032, ctrlId, -1 );
createMenu( 4000, addId, -1 );
createMenu( 4009, addId, -1 );
@ -4085,6 +4107,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createPopupItem( 214, OB, mesh_part ); // UPDATE
createPopupItem( 900, OB, mesh_part ); // ADV_INFO
createPopupItem( 904, OB, mesh_group ); // FIND_ELEM
createPopupItem( 6032, OB, mesh_part ); // CTRL_INFO
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( 801, OB, mesh ); // CREATE_GROUP
createPopupItem( 806, OB, mesh ); // CREATE_GEO_GROUP
@ -4746,10 +4769,15 @@ void SMESHGUI::createPreferences()
setPreferenceProperty( nodesLim, "max", 10000000 );
setPreferenceProperty( nodesLim, "step", 10000 );
setPreferenceProperty( nodesLim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
int ctrlLim = addPreference( tr( "PREF_CTRL_LIMIT" ), infoGroup, LightApp_Preferences::IntSpin, "SMESH", "info_controls_limit" );
setPreferenceProperty( ctrlLim, "min", 0 );
setPreferenceProperty( ctrlLim, "max", 10000000 );
setPreferenceProperty( ctrlLim, "step", 1000 );
addPreference( tr( "PREF_ELEM_INFO_GRP_DETAILS" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "elem_info_grp_details" );
addPreference( tr( "PREF_DUMP_BASE_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_base" );
addPreference( tr( "PREF_DUMP_ELEM_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_elem" );
addPreference( tr( "PREF_DUMP_ADD_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_add" );
addPreference( tr( "PREF_DUMP_CTRL_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_ctrl" );
int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab );
setPreferenceProperty( segGroup, "columns", 2 );

View File

@ -35,7 +35,6 @@
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_ControlsDef.hxx"
#include <LightApp_SelectionMgr.h>
#include <SUIT_FileDlg.h>
@ -150,6 +149,7 @@ public:
QCheckBox* myBaseChk;
QCheckBox* myElemChk;
QCheckBox* myAddChk;
QCheckBox* myCtrlChk;
};
/*!
@ -164,11 +164,13 @@ DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true,
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 );
QHBoxLayout* layout = new QHBoxLayout( hB );
layout->addWidget( myBaseChk );
layout->addWidget( myElemChk );
layout->addWidget( myAddChk );
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 );
QPushButton* pb = new QPushButton( this );
@ -418,13 +420,13 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
l->addWidget( a3DHexPriTotal, 25, 1 );
l->addWidget( a3DPolLab, 26, 0 );
l->addWidget( a3DPolTotal, 26, 1 );
l->addWidget( myLoadBtn, 27, 1, 1, 3 );
l->addWidget( myLoadBtn, 28, 1, 1, 3 );
l->setColumnStretch( 0, 0 );
l->setColumnStretch( 1, 5 );
l->setColumnStretch( 2, 5 );
l->setColumnStretch( 3, 5 );
l->setRowStretch( 23, 5 );
l->setRowStretch( 27, 5 );
clear();
}
@ -2653,6 +2655,11 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
// controls info
myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
// buttons
QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
@ -2712,6 +2719,7 @@ void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO
if ( !CORBA::is_nil( obj ) ) {
myBaseInfo->showInfo( obj );
myAddInfo->showInfo( obj );
myCtrlInfo->showInfo( obj );
myActor = SMESH::FindActorByEntry( IO->getEntry() );
SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
@ -2782,7 +2790,7 @@ void SMESHGUI_MeshInfoDlg::updateSelection()
disconnect( selMgr, 0, this, 0 );
selMgr->clearFilters();
if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) {
if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo || myTabWidget->currentIndex() == CtrlInfo ) {
SMESH::SetPointRepresentation( false );
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
aViewWindow->SetSelectionMode( ActorSelection );
@ -2933,11 +2941,13 @@ void SMESHGUI_MeshInfoDlg::dump()
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 );
@ -2946,6 +2956,7 @@ void SMESHGUI_MeshInfoDlg::dump()
fd.myBaseChk->setChecked( anIsBase );
fd.myElemChk->setChecked( anIsElem );
fd.myAddChk ->setChecked( anIsAdd );
fd.myCtrlChk->setChecked( anIsCtrl );
if ( fd.exec() == QDialog::Accepted )
{
QString aFileName = fd.selectedFile();
@ -2953,6 +2964,7 @@ void SMESHGUI_MeshInfoDlg::dump()
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 );
@ -2968,6 +2980,518 @@ void SMESHGUI_MeshInfoDlg::dump()
if ( toBase ) myBaseInfo->saveInfo( out );
if ( toElem ) myElemInfo->saveInfo( out );
if ( toAdd ) myAddInfo ->saveInfo( out );
if ( toCtrl ) myCtrlInfo->saveInfo( out );
}
}
}
/*!
\class SMESHGUI_CtrlInfo
\brief Class for the mesh controls information widget.
*/
/*!
\brief Constructor
\param parent parent widget
*/
SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent )
: QFrame( parent ), myPlot( 0 ), myPlot3D( 0 )
{
setFrameStyle( StyledPanel | Sunken );
QGridLayout* l = new QGridLayout( this );
l->setMargin( MARGIN );
l->setSpacing( SPACING );
// name
QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this );
QLabel* aName = createField();
aName->setMinimumWidth( 150 );
myWidgets << aName;
// 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;
QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
QLabel* aNodesDouble = createField();
myWidgets << aNodesDouble;
// 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;
// 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;
QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
QLabel* aFacesOver = createField();
myWidgets << aFacesOver;
QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
myPlot = createPlot( this );
// 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;
QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
QLabel* aVolumesOver = createField();
myWidgets << aVolumesOver;
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() ) );
setFontAttributes( aNameLab );
setFontAttributes( aNodesLab );
setFontAttributes( anEdgesLab );
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 );
l->setColumnStretch( 0, 0 );
l->setColumnStretch( 1, 5 );
l->setRowStretch ( 10, 5 );
l->setRowStretch ( 15, 5 );
clearInternal();
}
/*!
\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
*/
QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
{
QwtPlot* aPlot = new QwtPlot( parent );
aPlot->setMinimumSize( 100, 100 );
QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
xFont.setPointSize( 5 );
QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
yFont.setPointSize( 5 );
aPlot->setAxisFont( QwtPlot::xBottom, xFont );
aPlot->setAxisFont( QwtPlot::yLeft, yFont );
aPlot->replot();
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;
SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj );
if ( aMesh->_is_nil() ) return;
SMESH::Controls::FunctorPtr aFunctor;
// 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 ) ) );
}
// edges info
if ( aMesh->NbEdges() ) {
// 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 ) ) );
}
// 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 );
}
// 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 );
}
}
void SMESHGUI_CtrlInfo::computeFaceInfo() {
myComputeFaceBtn->setVisible( false );
SUIT_OverrideCursor wc;
SALOME_ListIO selected;
SMESHGUI::selectionMgr()->selectedObjects( selected );
if ( selected.Extent() < 1 ) return;
SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( 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() ) {
QwtPlotItem* anItem = aHistogram->createPlotItem();
anItem->attach( myPlot );
myPlot->replot();
}
}
void SMESHGUI_CtrlInfo::computeVolumeInfo() {
myComputeVolumeBtn->setVisible( false );
SUIT_OverrideCursor wc;
SALOME_ListIO selected;
SMESHGUI::selectionMgr()->selectedObjects( selected );
if ( selected.Extent() < 1 ) return;
SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( 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() ) {
QwtPlotItem* anItem = aHistogram->createPlotItem();
anItem->attach( myPlot3D );
myPlot3D->replot();
}
}
/*!
\brief Internal clean-up (reset widget)
*/
void SMESHGUI_CtrlInfo::clearInternal()
{
myComputeFaceBtn->setVisible( false );
myComputeVolumeBtn->setVisible( 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 ) );
}
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<SMESH::Controls::Predicate*>( theFunctor.get() ) )
if ( aPredicate->IsSatisfy( elems[i] ) ) nbElems++;
}
return nbElems;
}
Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::long_array_var& elems, SMESH::Controls::NumericalFunctorPtr aNumFun ) {
Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
std::vector<int> elements;
elements.resize( elems->length() );
for ( unsigned i = 0; i < elements.size(); i++ )
elements[i] = elems[i];
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<int> nbEvents;
std::vector<double> 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<double>( nbEvents[i] ) );
if ( funValues.size() >= 2 )
aHistogram->setWidth( ( funValues[1] - funValues[0] ) * 0.8 );
aHistogram->setColor( palette().color( QPalette::Highlight ) );
return aHistogram;
}
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";
}
/*!
\class SMESHGUI_CtrlInfoDlg
\brief Controls information dialog box
*/
/*!
\brief Constructor
\param parent parent widget
\param page specifies the dialog page to be shown at the start-up
*/
SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
: QDialog( parent )
{
setAttribute( Qt::WA_DeleteOnClose, true );
setWindowTitle( tr( "CTRL_INFO" ) );
setMinimumSize( 400, 600 );
myCtrlInfo = new SMESHGUI_CtrlInfo( this );
// buttons
QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
okBtn->setAutoDefault( true );
okBtn->setDefault( true );
okBtn->setFocus();
QGridLayout* l = new QGridLayout ( 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 );
connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
updateSelection();
}
/*!
\brief Destructor
*/
SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
{
}
/*!
\brief Show controls information
\param IO interactive object
*/
void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
{
if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO ) )
myCtrlInfo->showInfo( obj );
}
/*!
\brief Perform clean-up actions on the dialog box closing.
*/
void SMESHGUI_CtrlInfoDlg::reject()
{
SMESH::SetPointRepresentation( false );
QDialog::reject();
}
/*!
\brief Setup selection mode depending on the current dialog box state.
*/
void SMESHGUI_CtrlInfoDlg::updateSelection()
{
LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
disconnect( selMgr, 0, this, 0 );
SMESH::SetPointRepresentation( false );
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
*/
void SMESHGUI_CtrlInfoDlg::deactivate()
{
disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
}

View File

@ -27,6 +27,9 @@
#include "SMESH_SMESHGUI.hxx"
#include <SALOME_InteractiveObject.hxx>
#include "SMESH_ControlsDef.hxx"
#include <Plot2d_Histogram.h>
#include <QFrame>
#include <QDialog>
@ -280,6 +283,37 @@ private:
SMESH::submesh_array_var mySubMeshes;
};
class SMESHGUI_EXPORT SMESHGUI_CtrlInfo : public QFrame
{
Q_OBJECT;
public:
SMESHGUI_CtrlInfo( QWidget* = 0 );
~SMESHGUI_CtrlInfo();
void showInfo( SMESH::SMESH_IDSource_ptr );
void saveInfo( QTextStream &out );
private:
QLabel* createField();
QwtPlot* createPlot( QWidget* );
void setFontAttributes( QWidget* );
void clearInternal();
int nbElemsControl( SMESH::long_array_var&, SMESH::Controls::FunctorPtr );
Plot2d_Histogram* getHistogram( SMESH::long_array_var&, SMESH::Controls::NumericalFunctorPtr );
private slots:
void computeFaceInfo();
void computeVolumeInfo();
private:
QList<QLabel*> myWidgets;
QwtPlot* myPlot;
QwtPlot* myPlot3D;
QPushButton* myComputeFaceBtn;
QPushButton* myComputeVolumeBtn;
};
class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog
{
Q_OBJECT;
@ -291,7 +325,8 @@ public:
enum {
BaseInfo, //!< base mesh information
ElemInfo, //!< mesh element information
AddInfo //!< additional information
AddInfo, //!< additional information
CtrlInfo //!< controls information
};
SMESHGUI_MeshInfoDlg( QWidget* = 0, int = BaseInfo );
@ -323,7 +358,29 @@ private:
QLineEdit* myID;
SMESHGUI_ElemInfo* myElemInfo;
SMESHGUI_AddInfo* myAddInfo;
SMESHGUI_CtrlInfo* myCtrlInfo;
SMESH_Actor* myActor;
};
class SMESHGUI_EXPORT SMESHGUI_CtrlInfoDlg : public QDialog
{
Q_OBJECT;
public:
SMESHGUI_CtrlInfoDlg( QWidget* = 0 );
~SMESHGUI_CtrlInfoDlg();
void showInfo( const Handle(SALOME_InteractiveObject)& );
void reject();
private slots:
void updateInfo();
void activate();
void deactivate();
void updateSelection();
private:
SMESHGUI_CtrlInfo* myCtrlInfo;
};
#endif // SMESHGUI_MESHINFO_H

View File

@ -828,6 +828,10 @@
<source>MEN_RESET</source>
<translation>Reset</translation>
</message>
<message>
<source>MEN_OVERALL_MESH_QUALITY</source>
<translation>Overall Mesh Quality</translation>
</message>
<message>
<source>MEN_DISTRIBUTION_CTRL</source>
<translation>Distribution</translation>
@ -4267,10 +4271,18 @@ Please, create VTK viewer and try again</translation>
<source>PREF_DUMP_ADD_INFO</source>
<translation>Dump additional information</translation>
</message>
<message>
<source>PREF_DUMP_CTRL_INFO</source>
<translation>Dump controls information</translation>
</message>
<message>
<source>PREF_GPP_NODES_LIMIT</source>
<translation>Automatic nodes compute limit</translation>
</message>
<message>
<source>PREF_CTRL_LIMIT</source>
<translation>Automatic controls compute limit</translation>
</message>
<message>
<source>SMESH_PREF_GROUP_PRECISION</source>
<translation>Input fields precision</translation>
@ -6747,6 +6759,10 @@ as they are of improper type:
<source>ADDITIONAL_INFO</source>
<translation>Additional Info</translation>
</message>
<message>
<source>CTRL_INFO</source>
<translation>Quality Info</translation>
</message>
<message>
<source>NODE_MODE</source>
<translation>Node</translation>
@ -7113,6 +7129,80 @@ as they are of improper type:
<translation>Vertex</translation>
</message>
</context>
<context>
<name>SMESHGUI_CtrlInfo</name>
<message>
<source>CTRL_INFO</source>
<translation>Quality information</translation>
</message>
<message>
<source>NAME_LAB</source>
<translation>Name:</translation>
</message>
<message>
<source>VALUE</source>
<translation>Value</translation>
</message>
<message>
<source>BUT_COMPUTE</source>
<translation>Compute</translation>
</message>
<message>
<source>NODES_INFO</source>
<translation>Nodes Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_FREE_NODES</source>
<translation>Number of the free nodes</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_NODES</source>
<translation>Number of the double nodes</translation>
</message>
<message>
<source>EDGES_INFO</source>
<translation>Edges Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_EDGES</source>
<translation>Number of the double edges</translation>
</message>
<message>
<source>FACES_INFO</source>
<translation>Faces Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_FACES</source>
<translation>Number of the double faces</translation>
</message>
<message>
<source>ASPECT_RATIO_HISTOGRAM</source>
<translation>Aspect Ratio histogram</translation>
</message>
<message>
<source>VOLUMES_INFO</source>
<translation>Volumes Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_VOLUMES</source>
<translation>Number of the double volumes</translation>
</message>
<message>
<source>NUMBER_OF_THE_OVER_CONSTRAINED</source>
<translation>Number of the over-constrained</translation>
</message>
<message>
<source>ASPECT_RATIO_3D_HISTOGRAM</source>
<translation>Aspect Ratio 3D histogram</translation>
</message>
</context>
<context>
<name>SMESHGUI_CtrlInfoDlg</name>
<message>
<source>CTRL_INFO</source>
<translation>Quality Info</translation>
</message>
</context>
<context>
<name>SMESHGUI_MinDistance</name>
<message>

View File

@ -824,6 +824,10 @@
<source>MEN_RESET</source>
<translation>Restaurer</translation>
</message>
<message>
<source>MEN_OVERALL_MESH_QUALITY</source>
<translation type="unfinished">Overall Mesh Quality</translation>
</message>
<message>
<source>MEN_DISTRIBUTION_CTRL</source>
<translation>Distribution</translation>
@ -4235,10 +4239,18 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
<source>PREF_DUMP_ADD_INFO</source>
<translation>Copier les informations additionelles</translation>
</message>
<message>
<source>PREF_DUMP_CTRL_INFO</source>
<translation type="unfinished">Dump controls information</translation>
</message>
<message>
<source>PREF_GPP_NODES_LIMIT</source>
<translation>Calcul automatique du nombre de nœuds: limite</translation>
</message>
<message>
<source>PREF_CTRL_LIMIT</source>
<translation type="unfinished">Automatic controls compute limit</translation>
</message>
<message>
<source>SMESH_PREF_GROUP_PRECISION</source>
<translation>Précision des champs d&apos;entrée</translation>
@ -6683,6 +6695,10 @@ en raison de leurs types incompatibles:
<source>ADDITIONAL_INFO</source>
<translation>Infos détaillées</translation>
</message>
<message>
<source>CTRL_INFO</source>
<translation type="unfinished">Quality Info</translation>
</message>
<message>
<source>NODE_MODE</source>
<translation>Nœud</translation>
@ -7049,6 +7065,80 @@ en raison de leurs types incompatibles:
<translation>Point</translation>
</message>
</context>
<context>
<name>SMESHGUI_CtrlInfo</name>
<message>
<source>CTRL_INFO</source>
<translation type="unfinished">Quality information</translation>
</message>
<message>
<source>NAME_LAB</source>
<translation type="unfinished">Name:</translation>
</message>
<message>
<source>VALUE</source>
<translation type="unfinished">Value</translation>
</message>
<message>
<source>BUT_COMPUTE</source>
<translation type="unfinished">Compute</translation>
</message>
<message>
<source>NODES_INFO</source>
<translation type="unfinished">Nodes Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_FREE_NODES</source>
<translation type="unfinished">Number of the free nodes</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_NODES</source>
<translation type="unfinished">Number of the double nodes</translation>
</message>
<message>
<source>EDGES_INFO</source>
<translation type="unfinished">Edges Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_EDGES</source>
<translation type="unfinished">Number of the double edges</translation>
</message>
<message>
<source>FACES_INFO</source>
<translation type="unfinished">Faces Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_FACES</source>
<translation type="unfinished">Number of the double faces</translation>
</message>
<message>
<source>ASPECT_RATIO_HISTOGRAM</source>
<translation type="unfinished">Aspect Ratio histogram</translation>
</message>
<message>
<source>VOLUMES_INFO</source>
<translation type="unfinished">Volumes Information:</translation>
</message>
<message>
<source>NUMBER_OF_THE_DOUBLE_VOLUMES</source>
<translation type="unfinished">Number of the double volumes</translation>
</message>
<message>
<source>NUMBER_OF_THE_OVER_CONSTRAINED</source>
<translation type="unfinished">Number of the over-constrained</translation>
</message>
<message>
<source>ASPECT_RATIO_3D_HISTOGRAM</source>
<translation type="unfinished">Aspect Ratio 3D histogram</translation>
</message>
</context>
<context>
<name>SMESHGUI_CtrlInfoDlg</name>
<message>
<source>CTRL_INFO</source>
<translation type="unfinished">Quality Info</translation>
</message>
</context>
<context>
<name>SMESHGUI_MinDistance</name>
<message>