22853: EDF 9924 GEOM: Dimension histogram

This commit is contained in:
akl 2015-04-23 12:42:06 +04:00 committed by vsr
parent 1442137f3f
commit 59b5446863
28 changed files with 1199 additions and 17 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

View File

@ -0,0 +1,28 @@
/*!
\page shape_statistics_operation_page Shape Statistics
This operation allows plotting a distribution histogram for the numerical parameters and creating the corresponding geometrical groups of the given shape.
To call <b>Shape Statistics</b> dialog box, in the <b>Main Menu</b> select <b>Inspection - > Shape Statistics</b>.
\image html shape_statistics.png
In this dialog:
- "Selected objects" standard selection box allows selecting one or more geometrical objects.
- "Type" combo-box with the following items: "Edges length", "Faces area", "Solids volume".
\note "Type" combo-box includes only parameters applied to the currently selected shape (e.g. "Solids volume" will not be available for face or shell being selected); multiple selection is processed correspondingly (i.e. only types applicable for all selected shapes will be available).
- "Number of intervals" spin box is used to specify number of distribution histogram ranges.
- "Scalar range" checkable group box that, when switched ON, allows specifying custom values range used for plotting and creating groups.
\note By default, "Scalar range" controls is empty; pressing "Compute" button allows automatic computing initial range of the chosen parameter. This is needed as computation of the parameters range can be time-consuming for large or complex models. In case of multiple selection, scalar range is computed as common from all selected shapes.
- "Plot" button opens or uses an opened Plot2d viewer and plots the distribution histogram for the selected shape(s).
- "Create groups" button allows creating a groups according to the currently specified parameters. The groups names will include numerical values of the range, e.g. "Edges_length_0-20", "Edges_length_20-40", etc. Empty groups are not created.
- Close dialog box, by pressing <b>Close</b> button.
*/

View File

@ -19,6 +19,7 @@
<li>\subpage managing_dimensions_page "Dimensions"</li>
<li>\subpage whatis_page "WhatIs"</li>
<li>\subpage inspect_object_operation_page "Inspect Object"</li>
<li>\subpage shape_statistics_operation_page "Shape Statistics"</li>
</ul>
\n To check their integrity:

View File

@ -24,7 +24,7 @@ This functionality is available in OCC viewer only.
To create a group of sub-shapes of a geometrical object in the main
menu select <b>New entity > Group > Create</b>
\n The following menu will appear:
\n The following dialog box will appear:
\image html geomcreategroup.png
@ -101,6 +101,11 @@ In order to filter out some entities:
The entities which satisfy entered filtering parameters will be automatically highlighted
in the 3D viewer.
\b Plot button into "Filter" group box provides an access
to the \ref shape_statistics_operation_page "Shape Statistics" functionality with simplified look-n-feel:
\image html shape_statistics_simple.png
\n <b>TUI Command:</b> <em>geompy.CreateGroup(MainShape,
ShapeType),</em> where MainShape is a shape for which the group is
created, ShapeType is a type of shapes in the created group.

View File

@ -43,8 +43,8 @@ IF(SALOME_BUILD_GUI)
SET(SUBDIRS_GUI
OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI
GEOMBase DependencyTree GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI
CurveCreator EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI
RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI
CurveCreator MeasureGUI EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI
RepairGUI GroupGUI BlocksGUI AdvancedGUI
GEOM_SWIG_WITHIHM
)
ENDIF()

View File

@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES(
${PROJECT_SOURCE_DIR}/src/GEOMImpl
${PROJECT_SOURCE_DIR}/src/GEOMGUI
${PROJECT_SOURCE_DIR}/src/GEOMBase
${PROJECT_SOURCE_DIR}/src/MeasureGUI
${PROJECT_SOURCE_DIR}/src/SKETCHER
${PROJECT_SOURCE_DIR}/src/CurveCreator
${PROJECT_SOURCE_DIR}/src/ShapeRecognition
@ -67,6 +68,7 @@ SET(_link_LIBRARIES
DlgRef
GEOMSketcher
CurveCreator
MeasureGUI
)
# optional sources

View File

@ -30,6 +30,7 @@
#include <GeometryGUI.h>
#include <GEOMBase.h>
#include <GEOMUtils.hxx>
#include <MeasureGUI_ShapeStatisticsDlg.h>
#include <OCCViewer_ViewModel.h>
#include <SVTK_ViewModel.h>
@ -165,6 +166,7 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge
myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp);
myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp);
QGridLayout* filterLayout = new QGridLayout(myFilterGrp);
filterLayout->addWidget(myLessFilterCheck, 0, 0);
@ -174,6 +176,7 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge
filterLayout->addWidget(myGreaterFilterCombo, 1, 1);
filterLayout->addWidget(myGreaterFilterSpin, 1, 2);
filterLayout->addWidget(myApplyFilterButton, 0, 3);
filterLayout->addWidget(myPlotDistributionButton, 1, 3);
QVBoxLayout* layout = new QVBoxLayout(centralWidget());
layout->setMargin(0); layout->setSpacing(6);
@ -250,6 +253,7 @@ void EntityGUI_SubShapeDlg::Init()
connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter()));
connect(myPlotDistributionButton, SIGNAL(clicked()), this, SLOT(ClickOnPlot()));
connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
@ -491,6 +495,11 @@ void EntityGUI_SubShapeDlg::SubShapeToggled()
GroupPoints->CheckButton1->isChecked() &&
shapeType() < GEOM::VERTEX);
myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() &&
( shapeType() == TopAbs_EDGE ||
shapeType() == TopAbs_FACE ||
shapeType() == TopAbs_SOLID ) );
activateSelection();
}
@ -936,6 +945,18 @@ void EntityGUI_SubShapeDlg::ClickOnOkFilter()
updateButtonState();
}
//=================================================================================
// function : ClickOnPlot()
// purpose : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution.
//=================================================================================
void EntityGUI_SubShapeDlg::ClickOnPlot()
{
QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, myShape, (TopAbs_ShapeEnum)shapeType() );
if ( dlg ) {
dlg->show();
}
}
//=================================================================================
// function : MeasureToggled()
// purpose :

View File

@ -73,6 +73,7 @@ private slots:
void showOnlySelected();
void ClickOnOkFilter();
void ClickOnPlot();
void MeasureToggled();
private:
@ -102,6 +103,7 @@ private:
SalomeApp_DoubleSpinBox* myLessFilterSpin;
SalomeApp_DoubleSpinBox* myGreaterFilterSpin;
QPushButton* myApplyFilterButton;
QPushButton* myPlotDistributionButton;
QGroupBox* myFilterGrp;
};

View File

@ -859,7 +859,7 @@ QString GEOMBase::GetEntry( GEOM::GEOM_Object_ptr object )
// Function : PublishSubObject
// Purpose : Publish sub-shape under the main object
//================================================================
void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object )
void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object, const QString& name )
{
SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
if ( study && !CORBA::is_nil( object ) ) {
@ -868,9 +868,9 @@ void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object )
GEOM::GEOM_Object_var father = object->GetMainShape();
QString fatherEntry = GetEntry( father );
if ( entry.isEmpty() && !CORBA::is_nil( father ) && !fatherEntry.isEmpty() ) {
QString name = GetName( object );
QString aName = !name.isEmpty() ? name : GetName( object );
GeometryGUI::GetGeomGen()->AddInStudy( GeometryGUI::ClientStudyToStudy( studyDS ),
object, name.toLatin1().data(), father.in() );
object, aName.toLatin1().data(), father.in() );
}
}
}

View File

@ -133,7 +133,7 @@ public :
static QString GetEntry( GEOM::GEOM_Object_ptr object );
/* Publish sub-shape under the main object */
static void PublishSubObject( GEOM::GEOM_Object_ptr object );
static void PublishSubObject( GEOM::GEOM_Object_ptr object, const QString& name = QString() );
static void Synchronize( QList<GEOM::GeomObjPtr>& left, QList<GEOM::GeomObjPtr>& right );
};

View File

@ -431,6 +431,10 @@ Please, select face, shell or solid and try again</translation>
<source>GEOM_FAST_CHECK_INTERSECTIONS</source>
<translation>Fast intersection</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS</source>
<translation>Shape Statistics</translation>
</message>
<message>
<source>GEOM_CIRCLE</source>
<translation>Circle</translation>
@ -2556,6 +2560,10 @@ Please, select face, shell or solid and try again</translation>
<source>MEN_FAST_CHECK_INTERSECTIONS</source>
<translation>Fast intersection</translation>
</message>
<message>
<source>MEN_SHAPE_STATISTICS</source>
<translation>Shape Statistics</translation>
</message>
<message>
<source>MEN_CHECK_FREE_BNDS</source>
<translation>Check Free Boundaries</translation>
@ -2838,7 +2846,7 @@ Please, select face, shell or solid and try again</translation>
</message>
<message>
<source>MEN_MEASURES</source>
<translation>Measures</translation>
<translation>Inspection</translation>
</message>
<message>
<source>MEN_MIN_DIST</source>
@ -3591,6 +3599,10 @@ Please, select face, shell or solid and try again</translation>
<message>
<source>STB_FAST_CHECK_INTERSECTIONS</source>
<translation>Fast intersection</translation>
</message>
<message>
<source>STB_SHAPE_STATISTICS</source>
<translation>Shape Statistics</translation>
</message>
<message>
<source>STB_CHECK_FREE_BNDS</source>
@ -4224,6 +4236,10 @@ Please, select face, shell or solid and try again</translation>
<source>TOP_FAST_CHECK_INTERSECTIONS</source>
<translation>Fast intersection</translation>
</message>
<message>
<source>TOP_SHAPE_STATISTICS</source>
<translation>Shape Statistics</translation>
</message>
<message>
<source>TOP_CHECK_FREE_BNDS</source>
<translation>Check free boundaries</translation>
@ -5384,6 +5400,10 @@ shells and solids on the other hand.</translation>
<source>GEOM_HEALING_STATS_COL_2</source>
<translation>Modification</translation>
</message>
<message>
<source>GEOM_PLOT_DISTRIBUTION</source>
<translation>Plot</translation>
</message>
</context>
<context>
<name>GeometryGUI</name>
@ -5433,7 +5453,7 @@ shells and solids on the other hand.</translation>
</message>
<message>
<source>TOOL_MEASURES</source>
<translation>Measures</translation>
<translation>Inspection</translation>
</message>
<message>
<source>TOOL_IMPORTEXPORT</source>
@ -7335,6 +7355,69 @@ Do you want to create new material?</translation>
<translation>Objects And Results</translation>
</message>
</context>
<context>
<name>MeasureGUI_ShapeStatisticsDlg</name>
<message>
<source>GEOM_SHAPE_STATISTICS_TYPE</source>
<translation>Type</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_LENGTH</source>
<translation>Edges length</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_AREA</source>
<translation>Faces area</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_VOLUME</source>
<translation>Solids volume</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_NB_INTERVALS</source>
<translation>Number of intervals</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_SCALAR_RANGE</source>
<translation>Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_COMPUTE</source>
<translation>Compute</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN</source>
<translation>Min</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MAX</source>
<translation>Max</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_CREATE_GROUPS</source>
<translation>Create Groups</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT</source>
<translation>Number of entities</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN_ERROR</source>
<translation>Set minimal range value or switch-off Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MAX_ERROR</source>
<translation>Set maximal range value or switch-off Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR</source>
<translation>Minimal range value can not be more than maximal</translation>
</message>
<message>
<source>GEOM_MSG_GROUPS_CREATED</source>
<translation>%1 groups created</translation>
</message>
</context>
<context>
<name>TransformationGUI_ExtensionDlg</name>
<message>

View File

@ -431,6 +431,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
<source>GEOM_FAST_CHECK_INTERSECTIONS</source>
<translation>Intersection rapide</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>GEOM_CIRCLE</source>
<translation>Cercle</translation>
@ -2512,6 +2516,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
<source>MEN_FAST_CHECK_INTERSECTIONS</source>
<translation>Intersection rapide</translation>
</message>
<message>
<source>MEN_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>MEN_CHECK_FREE_BNDS</source>
<translation>Contrôler les contours libres</translation>
@ -2794,7 +2802,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
</message>
<message>
<source>MEN_MEASURES</source>
<translation>Mesures</translation>
<translation type="unfinished">Inspection</translation>
</message>
<message>
<source>MEN_MIN_DIST</source>
@ -3540,6 +3548,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
<source>STB_FAST_CHECK_INTERSECTIONS</source>
<translation>Intersection rapide</translation>
</message>
<message>
<source>STB_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>STB_CHECK_FREE_BNDS</source>
<translation>Vérifier les contours libres</translation>
@ -4164,6 +4176,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
<source>TOP_FAST_CHECK_INTERSECTIONS</source>
<translation>Intersection rapide</translation>
</message>
<message>
<source>TOP_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>TOP_CHECK_FREE_BNDS</source>
<translation>Valider les contours libres</translation>
@ -5316,6 +5332,10 @@ le paramètre &apos;%1&apos; aux préférences du module Géométrie.</translati
<source>GEOM_HEALING_STATS_COL_2</source>
<translation>Modification</translation>
</message>
<message>
<source>GEOM_PLOT_DISTRIBUTION</source>
<translation type="unfinished">Plot</translation>
</message>
</context>
<context>
<name>GeometryGUI</name>
@ -5365,7 +5385,7 @@ le paramètre &apos;%1&apos; aux préférences du module Géométrie.</translati
</message>
<message>
<source>TOOL_MEASURES</source>
<translation>Informations</translation>
<translation type="unfinished">Inspection</translation>
</message>
<message>
<source>TOOL_IMPORTEXPORT</source>
@ -7268,6 +7288,69 @@ Voulez-vous en créer un nouveau ?</translation>
<translation>Objets et résultats</translation>
</message>
</context>
<context>
<name>MeasureGUI_ShapeStatisticsDlg</name>
<message>
<source>GEOM_SHAPE_STATISTICS_TYPE</source>
<translation type="unfinished">Type</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_LENGTH</source>
<translation type="unfinished">Edges length</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_AREA</source>
<translation type="unfinished">Faces area</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_VOLUME</source>
<translation type="unfinished">Solids volume</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_NB_INTERVALS</source>
<translation type="unfinished">Number of intervals</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_SCALAR_RANGE</source>
<translation type="unfinished">Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_COMPUTE</source>
<translation type="unfinished">Compute</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN</source>
<translation type="unfinished">Min</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MAX</source>
<translation type="unfinished">Max</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_CREATE_GROUPS</source>
<translation type="unfinished">Create Groups</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT</source>
<translation type="unfinished">Number of entities</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN_ERROR</source>
<translation type="unfinished">Set minimal range value or switch-off Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MAX_ERROR</source>
<translation type="unfinished">Set maximal range value or switch-off Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR</source>
<translation type="unfinished">Minimal range value can not be more than maximal</translation>
</message>
<message>
<source>GEOM_MSG_GROUPS_CREATED</source>
<translation type="unfinished">%1 groups created</translation>
</message>
</context>
<context>
<name>TransformationGUI_ExtensionDlg</name>
<message>

View File

@ -415,6 +415,10 @@
<source>GEOM_FAST_CHECK_INTERSECTIONS</source>
<translation type="unfinished">Fast intersection</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>GEOM_CHECK_SELF_INTERSECTIONS_FAILED</source>
<translation></translation>
@ -2467,6 +2471,10 @@
<source>MEN_FAST_CHECK_INTERSECTIONS</source>
<translation type="unfinished">Fast intersection</translation>
</message>
<message>
<source>MEN_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>MEN_CHECK_FREE_BNDS</source>
<translation></translation>
@ -2749,7 +2757,7 @@
</message>
<message>
<source>MEN_MEASURES</source>
<translation></translation>
<translation type="unfinished">Inspection</translation>
</message>
<message>
<source>MEN_MIN_DIST</source>
@ -3483,6 +3491,10 @@
<source>STB_FAST_CHECK_INTERSECTIONS</source>
<translation type="unfinished">Fast intersection</translation>
</message>
<message>
<source>STB_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>STB_CHECK_FREE_BNDS</source>
<translation></translation>
@ -4103,6 +4115,10 @@
<source>TOP_FAST_CHECK_INTERSECTIONS</source>
<translation type="unfinished">Fast intersection</translation>
</message>
<message>
<source>TOP_SHAPE_STATISTICS</source>
<translation type="unfinished">Shape Statistics</translation>
</message>
<message>
<source>TOP_CHECK_FREE_BNDS</source>
<translation></translation>
@ -5211,6 +5227,10 @@
<source>GEOM_NO_SHAPES_SELECTED</source>
<translation type="unfinished">There are no shapes that meet filtering parameters</translation>
</message>
<message>
<source>GEOM_PLOT_DISTRIBUTION</source>
<translation type="unfinished">Plot</translation>
</message>
</context>
<context>
<name>GeometryGUI</name>
@ -5260,7 +5280,7 @@
</message>
<message>
<source>TOOL_MEASURES</source>
<translation type="unfinished">Measures</translation>
<translation type="unfinished">Inspection</translation>
</message>
<message>
<source>TOOL_IMPORTEXPORT</source>
@ -7153,6 +7173,69 @@
<translation type="unfinished">Objects And Results</translation>
</message>
</context>
<context>
<name>MeasureGUI_ShapeStatisticsDlg</name>
<message>
<source>GEOM_SHAPE_STATISTICS_TYPE</source>
<translation type="unfinished">Type</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_LENGTH</source>
<translation type="unfinished">Edges length</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_AREA</source>
<translation type="unfinished">Faces area</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_VOLUME</source>
<translation type="unfinished">Solids volume</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_NB_INTERVALS</source>
<translation type="unfinished">Number of intervals</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_SCALAR_RANGE</source>
<translation type="unfinished">Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_COMPUTE</source>
<translation type="unfinished">Compute</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN</source>
<translation type="unfinished">Min</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MAX</source>
<translation type="unfinished">Max</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_CREATE_GROUPS</source>
<translation type="unfinished">Create Groups</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT</source>
<translation type="unfinished">Number of entities</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN_ERROR</source>
<translation type="unfinished">Set minimal range value or switch-off Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MAX_ERROR</source>
<translation type="unfinished">Set maximal range value or switch-off Scalar range</translation>
</message>
<message>
<source>GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR</source>
<translation type="unfinished">Minimal range value can not be more than maximal</translation>
</message>
<message>
<source>GEOM_MSG_GROUPS_CREATED</source>
<translation type="unfinished">%1 groups created</translation>
</message>
</context>
<context>
<name>TransformationGUI_ExtensionDlg</name>
<message>

View File

@ -644,6 +644,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam )
case GEOMOp::OpCheckSelfInters: // MENU MEASURE - CHECK SELF INTERSECTIONS
case GEOMOp::OpFastCheckInters: // MENU MEASURE - FAST CHECK INTERSECTIONS
case GEOMOp::OpManageDimensions: // MENU MEASURE - MANAGE DIMENSIONS
case GEOMOp::OpShapeStatistics: // MENU MEASURE - SHAPE STATISTICS
case GEOMOp::OpShowAllDimensions: // POPUP MENU - SHOW ALL DIMENSIONS
case GEOMOp::OpHideAllDimensions: // POPUP MENU - HIDE ALL DIMENSIONS
libName = "MeasureGUI";
@ -1025,6 +1026,7 @@ void GeometryGUI::initialize( CAM_Application* app )
createGeomAction( GEOMOp::OpGetNonBlocks, "GET_NON_BLOCKS" );
createGeomAction( GEOMOp::OpCheckSelfInters, "CHECK_SELF_INTERSECTIONS" );
createGeomAction( GEOMOp::OpFastCheckInters, "FAST_CHECK_INTERSECTIONS" );
createGeomAction( GEOMOp::OpShapeStatistics, "SHAPE_STATISTICS" );
#ifdef _DEBUG_ // PAL16821
createGeomAction( GEOMOp::OpCheckGeom, "CHECK_GEOMETRY" );
@ -1288,6 +1290,7 @@ void GeometryGUI::initialize( CAM_Application* app )
createMenu( GEOMOp::OpCheckSelfInters, measurId, -1 );
createMenu( GEOMOp::OpFastCheckInters, measurId, -1 );
createMenu( GEOMOp::OpInspectObj, measurId, -1 );
createMenu( GEOMOp::OpShapeStatistics, measurId, -1 );
int toolsId = createMenu( tr( "MEN_TOOLS" ), -1, -1, 50 );
#if defined(_DEBUG_) || defined(_DEBUG) // PAL16821

View File

@ -200,6 +200,7 @@ namespace GEOMOp {
OpHideAllDimensions = 5016, // POPUP MENU - HIDE ALL DIMENSIONS
OpFastCheckInters = 5017, // MENU MEASURES - FAST CHECK INTERSECTIONS
OpInspectObj = 5018, // MENU MEASURES - INSPECT OBJECT
OpShapeStatistics = 5019, // MENU MEASURES - SHAPE STATISTICS
// GroupGUI --------------------//--------------------------------
OpGroupCreate = 6000, // MENU GROUP - CREATE
OpGroupEdit = 6001, // MENU GROUP - EDIT

View File

@ -53,6 +53,7 @@ SET(GEOMUtils_HEADERS
GEOMUtils.hxx
GEOMUtils_Hatcher.hxx
GEOMUtils_HTrsfCurve2d.hxx
GEOMUtils_ShapeStatistics.hxx
GEOMUtils_Trsf2d.hxx
GEOMUtils_TrsfCurve2d.hxx
GEOMUtils_XmlHandler.hxx
@ -63,6 +64,7 @@ SET(GEOMUtils_SOURCES
GEOMUtils.cxx
GEOMUtils_Hatcher.cxx
GEOMUtils_HTrsfCurve2d.cxx
GEOMUtils_ShapeStatistics.cxx
GEOMUtils_Trsf2d.cxx
GEOMUtils_TrsfCurve2d.cxx
GEOMUtils_XmlHandler.cxx

View File

@ -0,0 +1,145 @@
// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
// 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
//
// File : GEOMUtils_ShapeStatisticsDlg.cxx
// Author : Alexander KOVALEV, OPEN CASCADE S.A.S.
#include "GEOMUtils_ShapeStatistics.hxx"
#include <BRepGProp.hxx>
#include <GProp_GProps.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
namespace GEOMUtils
{
//=================================================================================
// function : ComputeMeasures()
// purpose : gets measures of the given type for list of shapes in the range
//=================================================================================
std::map<int,double> ComputeMeasures( std::list<TopoDS_Shape> shapes,
TopAbs_ShapeEnum entity,
Range &range)
{
bool hasRange = (range.min != -1.0); // -1.0 means that range must not be used
if ( !hasRange )
range.min = 1e+32, range.max = 0.0;
// list of measures of entities
std::map<int, double> measures;
std::list<TopoDS_Shape>::const_iterator it;
for ( it = shapes.begin(); it != shapes.end(); ++it ) {
double aMeasure;
TopTools_IndexedMapOfShape aSubShapesMap;
TopExp::MapShapes(*it, aSubShapesMap); // map of all global indices
TopTools_IndexedMapOfShape aMx;
TopExp::MapShapes( *it, entity, aMx ); // map of current type sub-shape indices
int aNbS = aMx.Extent();
int index = -1;
for ( int i = 1; i <= aNbS; ++i ) {
aMeasure = 0.0;
const TopoDS_Shape& aSubShape = aMx( i );
//Get the measure: length, area or volume
GProp_GProps LProps, SProps, VProps;
if ( entity == TopAbs_EDGE ) {
BRepGProp::LinearProperties( aSubShape, LProps );
aMeasure = LProps.Mass();
} else if ( entity == TopAbs_FACE ) {
BRepGProp::SurfaceProperties( aSubShape, SProps );
aMeasure = SProps.Mass();
} else if ( entity == TopAbs_SOLID ) {
BRepGProp::VolumeProperties( aSubShape, VProps );
aMeasure = VProps.Mass();
}
// Don't pass sub-shapes with out of range measure, if range is used
if ( hasRange ) {
if ( aMeasure < range.min || aMeasure > range.max )
continue;
} else {
// get range min and max
if ( aMeasure < range.min ) range.min = aMeasure;
if ( aMeasure > range.max ) range.max = aMeasure;
}
// get global index of sub-shape
index = aSubShapesMap.FindIndex( aSubShape );
// keep measures to distribute it
measures[index] = aMeasure;
}
}
return measures;
}
//=================================================================================
// function : ComputeDistribution()
// purpose : gets distribution data for single shape
//=================================================================================
Distribution ComputeDistribution( TopoDS_Shape shape,
TopAbs_ShapeEnum entity,
int intervals,
Range range)
{
std::list<TopoDS_Shape> aShapes;
aShapes.push_back( shape );
return ComputeDistribution( aShapes, entity, intervals, range );
}
//=================================================================================
// function : ComputeDistribution()
// purpose : gets distribution data for list of shapes
//=================================================================================
Distribution ComputeDistribution( std::list<TopoDS_Shape> shapes,
TopAbs_ShapeEnum entity,
int nbIntervals,
Range range)
{
// get list of measures and compute range (if it was not specified)
std::map<int,double> measures = ComputeMeasures( shapes, entity, range );
// compute a step
double aStep = (range.max - range.min) / nbIntervals;
// compute distribution in intervals
Distribution aDistr;
std::map<int,double>::iterator dit;
for ( int i = 0; i < nbIntervals; i++ ) {
Range localRange; // range of current interval
localRange.min = range.min + ( i * aStep );
localRange.max = range.min + ( (i+1) * aStep );
localRange.count = 0;
std::vector<int> indicesToErase;
for ( dit = measures.begin(); dit != measures.end(); dit++ ) {
if ( ( dit->second >= localRange.min && dit->second < localRange.max ) ||
( i == nbIntervals-1 && dit->second == localRange.max ) ) {
localRange.count++;
localRange.indices.push_back( dit->first );
// measure is in interval, so remove it from map of search
indicesToErase.push_back( dit->first );
}
}
aDistr.push_back( localRange );
for( int j=0; j < indicesToErase.size(); j++ )
measures.erase( indicesToErase[j] );
}
return aDistr;
}
} //namespace GEOMUtils

View File

@ -0,0 +1,61 @@
// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
// 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
//
// File : GEOMUtils_ShapeStatisticsDlg.hxx
// Author : Alexander KOVALEV, OPEN CASCADE S.A.S.
#ifndef _GEOMUtils_ShapeStatistics_HXX_
#define _GEOMUtils_ShapeStatistics_HXX_
#include <list>
#include <map>
#include <vector>
#include <TopoDS_Shape.hxx>
namespace GEOMUtils
{
// struct to store range data
typedef struct { double min; double max; long count; std::list<long> indices; } Range;
// distribution is a set of ranges
typedef std::vector<Range> Distribution;
// function to get measures of entities and compute range for list of shapes
Standard_EXPORT std::map<int,double> ComputeMeasures(
std::list<TopoDS_Shape> shapes,
TopAbs_ShapeEnum entity,
Range &range );
// function to get distribution data for single shape
Standard_EXPORT Distribution ComputeDistribution(
TopoDS_Shape shape,
TopAbs_ShapeEnum entity,
int intervals,
Range range );
// function to get distribution data for list of shapes
Standard_EXPORT Distribution ComputeDistribution(
std::list<TopoDS_Shape> shapes,
TopAbs_ShapeEnum entity,
int intervals,
Range range );
}
#endif // _GEOMUtils_ShapeStatistics_HXX_

View File

@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES(
${PROJECT_SOURCE_DIR}/src/GEOMImpl
${PROJECT_SOURCE_DIR}/src/GEOMGUI
${PROJECT_SOURCE_DIR}/src/GEOMBase
${PROJECT_SOURCE_DIR}/src/MeasureGUI
${PROJECT_SOURCE_DIR}/src/DlgRef
${PROJECT_BINARY_DIR}/src/DlgRef
${CMAKE_CURRENT_SOURCE_DIR}
@ -56,6 +57,7 @@ ADD_DEFINITIONS(
SET(_link_LIBRARIES
GEOMBase
GEOMUtils
MeasureGUI
)
# --- resources ---

View File

@ -31,6 +31,7 @@
#include <GeometryGUI.h>
#include <GEOM_Displayer.h>
#include <GEOMUtils.hxx>
#include <MeasureGUI_ShapeStatisticsDlg.h>
#include <SalomeApp_Application.h>
#include <SalomeApp_Study.h>
@ -200,6 +201,7 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW
myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp);
myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp);
QGridLayout* filterLayout = new QGridLayout(myFilterGrp);
filterLayout->addWidget(myLessFilterCheck, 0, 0);
@ -209,6 +211,7 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW
filterLayout->addWidget(myGreaterFilterCombo, 1, 1);
filterLayout->addWidget(myGreaterFilterSpin, 1, 2);
filterLayout->addWidget(myApplyFilterButton, 0, 3);
filterLayout->addWidget(myPlotDistributionButton, 1, 3);
QVBoxLayout* layout = new QVBoxLayout(centralWidget());
layout->setMargin(0); layout->setSpacing(6);
@ -326,6 +329,7 @@ void GroupGUI_GroupDlg::Init()
connect(myIdList, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter()));
connect(myPlotDistributionButton, SIGNAL(clicked()), this, SLOT(ClickOnPlot()));
connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
@ -1135,6 +1139,16 @@ void GroupGUI_GroupDlg::updateState (bool isAdd)
subSelectionWay() == ALL_SUBSHAPES &&
myIsShapeType &&
getShapeType() != TopAbs_VERTEX);
// manage of 'Plot' button access
GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
GEOM::ListOfLong_var aSubShapes = aShOp->SubShapeAllIDs( myMainObj, getShapeType(), false );
bool hasCurrentEntities = aSubShapes->length() > 0;
myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() &&
myIsShapeType &&
( getShapeType() == TopAbs_EDGE ||
getShapeType() == TopAbs_FACE ||
getShapeType() == TopAbs_SOLID ) &&
hasCurrentEntities );
if (subSelectionWay() == ALL_SUBSHAPES)
setInPlaceObj(GEOM::GEOM_Object::_nil());
}
@ -1423,6 +1437,19 @@ void GroupGUI_GroupDlg::ClickOnOkFilter()
updateState(true);
}
//=================================================================================
// function : ClickOnPlot()
// purpose : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution.
//=================================================================================
void GroupGUI_GroupDlg::ClickOnPlot()
{
TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, aMainShape, getShapeType() );
if ( dlg ) {
dlg->show();
}
}
void GroupGUI_GroupDlg::MeasureToggled()
{
myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked());

View File

@ -83,6 +83,7 @@ private slots:
void showOnlySelected();
void selectionChanged();
void ClickOnOkFilter();
void ClickOnPlot();
void MeasureToggled();
private:
@ -133,6 +134,7 @@ private:
SalomeApp_DoubleSpinBox* myLessFilterSpin;
SalomeApp_DoubleSpinBox* myGreaterFilterSpin;
QPushButton* myApplyFilterButton;
QPushButton* myPlotDistributionButton;
QGroupBox* myFilterGrp;
};

View File

@ -129,6 +129,7 @@ SET(_moc_HEADERS
MeasureGUI_ManageDimensionsDlg.h
MeasureGUI_CreateDimensionDlg.h
MeasureGUI_DimensionInteractor.h
MeasureGUI_ShapeStatisticsDlg.h
)
# header files / uic wrappings
@ -163,6 +164,7 @@ SET(MeasureGUI_SOURCES
MeasureGUI_DimensionCreateTool.cxx
MeasureGUI_DimensionInteractor.cxx
MeasureGUI_DimensionFilter.cxx
MeasureGUI_ShapeStatisticsDlg.cxx
${_moc_SOURCES}
${_uic_files}
)

View File

@ -53,6 +53,7 @@
#include "MeasureGUI_FastCheckIntersectionsDlg.h" // Method FAST CHECK INTERSCTIONS
#include "MeasureGUI_PointDlg.h" // Method POINTCOORDINATES
#include "MeasureGUI_ManageDimensionsDlg.h" // Method MANAGEDIMENSIONS
#include "MeasureGUI_ShapeStatisticsDlg.h" // Method SHAPE STATISTICS
#include <QApplication>
@ -129,6 +130,9 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
case GEOMOp::OpFastCheckInters:
dlg = new MeasureGUI_FastCheckIntersectionsDlg( getGeometryGUI(), parent );
break; // FAST CHECK INTERSCTIONS
case GEOMOp::OpShapeStatistics:
dlg = new MeasureGUI_ShapeStatisticsDlg( parent );
break; // FAST CHECK INTERSCTIONS
case GEOMOp::OpPointCoordinates:
dlg = new MeasureGUI_PointDlg( getGeometryGUI(), parent );
break; // POINT COORDINATES

View File

@ -0,0 +1,533 @@
// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
// 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
//
// File : MeasureGUI_ShapeStatisticsDlg.cxx
// Author : Alexander KOVALEV, OPEN CASCADE S.A.S.
// internal includes
#include "MeasureGUI_ShapeStatisticsDlg.h"
// GEOM includes
#include <GEOMBase.h>
#include <GEOMUtils_ShapeStatistics.hxx>
#include <GeometryGUI.h>
#include <DlgRef.h>
// GUI includes
#include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_ViewManager.h>
#include <SUIT_ViewWindow.h>
#include <LightApp_SelectionMgr.h>
#include <SalomeApp_Application.h>
#include <SalomeApp_Study.h>
#include <Plot2d_Histogram.h>
#include <Plot2d_ViewFrame.h>
#include <Plot2d_ViewModel.h>
#include <Plot2d_ViewWindow.h>
// Qt includes
#include <QIcon>
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
// Qtx includes
#include <QtxValidator.h>
// OCC includes
#include <TopoDS_Shape.hxx>
#include <GEOMImpl_Types.hxx>
//===========================================================================
// class : MeasureGUI_ShapeStatisticsDlg()
//===========================================================================
MeasureGUI_ShapeStatisticsDlg::MeasureGUI_ShapeStatisticsDlg( QWidget* parent, TopoDS_Shape aShape, TopAbs_ShapeEnum aSubShapeType )
: GEOMBase_Helper( SUIT_Session::session()->activeApplication()->desktop() ),
QDialog( parent ),
myHistogram ( 0 )
{
myShapes.push_back( aShape );
QIcon iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
setWindowTitle( tr( "GEOM_SHAPE_STATISTICS" ) );
setAttribute( Qt::WA_DeleteOnClose );
myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
QVBoxLayout* topLayout = new QVBoxLayout( this );
QGridLayout* settingsLayout = new QGridLayout();
/********************** Selected Objects **********************/
QLabel* objsLabel = new QLabel( tr( "GEOM_SELECTED_OBJECTS" ), this );
QPushButton* selBtn = new QPushButton( this );
selBtn->setIcon( iconSelect );
myEditMainShape = new QLineEdit( this );
myEditMainShape->setReadOnly(true);
settingsLayout->addWidget( objsLabel, 0, 0 );
settingsLayout->addWidget( selBtn, 0, 1 );
settingsLayout->addWidget( myEditMainShape, 0, 2 );
if ( !aShape.IsNull() ) {
objsLabel->hide();
selBtn->hide();
myEditMainShape->hide();
}
/********************** Type **********************/
QLabel* typeLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_TYPE" ), this );
myCBTypes = new QtxComboBox( this );
myCBTypes->setCleared( true );
if ( aSubShapeType != TopAbs_SHAPE ) {
fillTypes( aSubShapeType == TopAbs_EDGE,
aSubShapeType == TopAbs_FACE,
aSubShapeType == TopAbs_SOLID );
myCBTypes->setEnabled( false );
}
settingsLayout->addWidget( typeLabel, 1, 0 );
settingsLayout->addWidget( myCBTypes, 1, 2 );
/********************** Number of intervals **********************/
QLabel* nbIntervalsLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_NB_INTERVALS" ), this );
myNbIntervals = new QtxIntSpinBox( 1, 1000, 1, this );
myNbIntervals->setValue( 10 );
settingsLayout->addWidget( nbIntervalsLabel, 2, 0 );
settingsLayout->addWidget( myNbIntervals, 2, 2 );
/********************** Scalar Range **********************/
myScalarRangeBox = new QGroupBox( tr( "GEOM_SHAPE_STATISTICS_SCALAR_RANGE" ), this );
myScalarRangeBox->setCheckable( true );
myScalarRangeBox->setChecked( false );
QLabel* minLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_MIN" ), this );
myMin = new QLineEdit( this );
QtxDoubleValidator* aValid = new QtxDoubleValidator( this );
aValid->setBottom( 0.0 );
myMin->setValidator( aValid );
QLabel* maxLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_MAX" ), this );
myMax = new QLineEdit( this );
myMax->setValidator( aValid );
QPushButton* buttonCompute = new QPushButton( tr( "GEOM_SHAPE_STATISTICS_COMPUTE" ), this );
connect( buttonCompute, SIGNAL( clicked() ), this, SLOT( clickOnCompute() ) );
QGridLayout* scalarRangeLayout = new QGridLayout();
scalarRangeLayout->setMargin( 11 ); settingsLayout->setSpacing( 6 );
scalarRangeLayout->addWidget( minLabel, 0, 0 );
scalarRangeLayout->addWidget( myMin, 0, 1 );
scalarRangeLayout->addWidget( maxLabel, 1, 0 );
scalarRangeLayout->addWidget( myMax, 1, 1 );
scalarRangeLayout->addWidget( buttonCompute, 0, 2, 2, 1 );
myScalarRangeBox->setLayout( scalarRangeLayout );
/********************** Buttons **********************/
myButtonPlot = new QPushButton( tr( "GEOM_PLOT_DISTRIBUTION" ), this );
myButtonPlot->setDefault( true );
myButtonCreateGr = new QPushButton( tr( "GEOM_SHAPE_STATISTICS_CREATE_GROUPS" ), this );
QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ), this );
QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ), this );
QHBoxLayout* buttonsLayout = new QHBoxLayout();
buttonsLayout->addWidget( myButtonPlot );
buttonsLayout->addWidget( myButtonCreateGr );
buttonsLayout->addWidget( buttonClose );
buttonsLayout->addWidget( buttonHelp );
if ( !aShape.IsNull() ) {
myButtonCreateGr->hide();
}
/********************** Layouting **********************/
topLayout->addLayout( settingsLayout );
topLayout->addWidget( myScalarRangeBox );
topLayout->addLayout( buttonsLayout );
// Signals and slots connections
connect( selBtn, SIGNAL( clicked() ), this, SLOT( onEditMainShape() ) );
connect( myButtonPlot, SIGNAL( clicked() ), this, SLOT( clickOnPlot() ) );
connect( myButtonCreateGr, SIGNAL( clicked() ), this, SLOT( clickOnCreateGroups() ) );
connect( buttonClose, SIGNAL( clicked() ), this, SLOT( reject() ) );
connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) );
connect(myApp->selectionMgr(),
SIGNAL(currentSelectionChanged()), this, SLOT(onEditMainShape()));
if ( aShape.IsNull() )
onEditMainShape();
}
//===========================================================================
// function : ~MeasureGUI_ShapeStatisticsDlg()
// purpose : Destroys the object and frees any allocated resources
//===========================================================================
MeasureGUI_ShapeStatisticsDlg::~MeasureGUI_ShapeStatisticsDlg()
{
}
//=================================================================================
// function : createOperation
// purpose :
//=================================================================================
GEOM::GEOM_IOperations_ptr MeasureGUI_ShapeStatisticsDlg::createOperation()
{
return getGeomEngine()->GetIGroupOperations(getStudyId());
}
#define RETURN_WITH_MSG(a, b) \
if (!(a)) { \
theMessage += (b); \
return false; \
}
//================================================================
// Function : getFather
// Purpose : Get father object for object to be added in study
// (called with addInStudy method)
//================================================================
GEOM::GEOM_Object_ptr MeasureGUI_ShapeStatisticsDlg::getFather(GEOM::GEOM_Object_ptr theObj)
{
GEOM::GEOM_Object_var aFatherObj;
if (theObj->GetType() == GEOM_GROUP) {
GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
aFatherObj = anOper->GetMainShape(theObj);
}
return aFatherObj._retn();
}
//=================================================================================
// function : getSourceObjects
// purpose : virtual method to get source objects
//=================================================================================
QList<GEOM::GeomObjPtr> MeasureGUI_ShapeStatisticsDlg::getSourceObjects()
{
QList<GEOM::GeomObjPtr> res;
res << myMainObj;
return res;
}
//=================================================================================
// function : onEditMainShape()
// purpose : called when selection button was clicked
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::onEditMainShape()
{
// restore initial parameters for dialog box
myEditMainShape->setText("");
myEditMainShape->setFocus();
//get shapes from selection
QList<GEOM::GeomObjPtr> selShapes = getSelected( TopAbs_SHAPE, -1 );
myButtonPlot->setEnabled( !selShapes.isEmpty() );
myButtonCreateGr->setEnabled( selShapes.count() == 1 );
if ( !selShapes.isEmpty() ) {
if ( selShapes.count() == 1 )
myMainObj = selShapes[0];
QString aName = selShapes.count() > 1 ? QString( "%1_objects").arg( selShapes.count() ) : GEOMBase::GetName( myMainObj.get() );
myEditMainShape->setText( aName );
}
updateTypes( selShapes );
}
//=================================================================================
// function : currentType()
// purpose : returns currently selected type of shapes in 'Type' combobox
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::fillTypes( bool hasEdges, bool hasFaces, bool hasSolids )
{
if ( hasEdges )
myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_LENGTH"), (int)TopAbs_EDGE );
if ( hasFaces )
myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_AREA"), (int)TopAbs_FACE );
if ( hasSolids )
myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_VOLUME"), (int)TopAbs_SOLID );
myCBTypes->setEnabled( myCBTypes->count() > 0 );
}
//=================================================================================
// function : updateTypes()
// purpose : update 'Type' combobox with available types
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::updateTypes( QList<GEOM::GeomObjPtr> theShapes )
{
myCBTypes->clear();
myCBTypes->setEnabled( false );
int hasEdges = -1, hasFaces = -1, hasSolids = -1;
myShapes.clear();
// get types of the shapes and its sub-shapes
foreach( GEOM::GeomObjPtr aShapePtr, theShapes ) {
if ( !aShapePtr )
return;
TopoDS_Shape aShape;
if ( !GEOMBase::GetShape( aShapePtr.get(), aShape ) || aShape.IsNull() )
return;
myShapes.push_back( aShape );
GEOM::ListOfLong_var aSubShapes;
GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
if ( hasEdges != 0 )
hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_EDGE ) > 0;
if ( hasFaces != 0 )
hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_FACE ) > 0;
if ( hasSolids != 0 )
hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_SOLID ) > 0;
}
fillTypes( hasEdges, hasFaces, hasSolids );
}
//=================================================================================
// function : currentType()
// purpose : returns currently selected type of shapes in 'Type' combobox
//=================================================================================
TopAbs_ShapeEnum MeasureGUI_ShapeStatisticsDlg::currentType()
{
return (TopAbs_ShapeEnum)( myCBTypes->itemData( myCBTypes->currentIndex() ).toInt() );
}
//=================================================================================
// function : clickOnPlot()
// purpose : called when Plot button was clicked
//=================================================================================
bool MeasureGUI_ShapeStatisticsDlg::isValid(QString& theMessage)
{
if ( myScalarRangeBox->isChecked() ) {
RETURN_WITH_MSG( !myMin->text().isEmpty(), tr("GEOM_SHAPE_STATISTICS_MIN_ERROR") )
RETURN_WITH_MSG( !myMax->text().isEmpty(), tr("GEOM_SHAPE_STATISTICS_MAX_ERROR") )
RETURN_WITH_MSG( myMin->text().toDouble() <= myMax->text().toDouble(), tr("GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR") )
}
return true;
}
//=================================================================================
// function : clickOnPlot()
// purpose : called when Plot button was clicked
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::clickOnPlot()
{
GEOMUtils::Range aRange;
if ( myScalarRangeBox->isChecked() ) {
QString msg;
if ( !isValid( msg ) ) {
showError( msg );
return;
}
aRange.min = myMin->text().toDouble();
aRange.max = myMax->text().toDouble();
} else {
aRange.min = -1.0; // flag that range is empty
aRange.max = -1.0; // flag that range is empty
}
GEOMUtils::Distribution aShapesDistr =
GEOMUtils::ComputeDistribution( myShapes, currentType(), myNbIntervals->value(), aRange );
QList<double> xVals, yVals;
double width = -1, min = -1;
double xmin = 1e+32, xmax = 0.0, ymax = 0.0;
int i=0;
GEOMUtils::Distribution::const_iterator it;
for (it = aShapesDistr.begin(); it != aShapesDistr.end(); it++) {
GEOMUtils::Range ran = *it;
if ( width < 0 ) width = ran.max - ran.min; // bar width
if ( min < 0 ) min = ran.min; // global min
xVals << width / 2. + i*width + min; // get a middle of bar
yVals << ran.count;
// get global boundary max values
if ( ran.min < xmin ) xmin = ran.min;
if ( ran.max > xmax ) xmax = ran.max;
if ( ran.count > ymax ) ymax = ran.count;
i++;
}
// plot the computed distribution
SUIT_ViewManager* aViewManager = myApp->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary
if( !aViewManager )
return;
Plot2d_ViewWindow* aViewWnd = dynamic_cast<Plot2d_ViewWindow*>(aViewManager->getActiveView());
if( !aViewWnd )
return;
Plot2d_ViewFrame* aPlot = aViewWnd->getViewFrame();
if ( !aPlot )
return;
aPlot->EraseAll();
// create or reuse histogram
if( !myHistogram )
myHistogram = new Plot2d_Histogram();
else
myHistogram->clearAllPoints();
// set histogram parameters
myHistogram->setData( xVals, yVals );
if ( width != 0.0 )
myHistogram->setWidth( width );
myHistogram->setAutoAssign(true);
myHistogram->setName( myEditMainShape->text() );
myHistogram->setHorTitle( myCBTypes->currentText() );
myHistogram->setVerTitle( tr("GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT") );
myHistogram->setColor( QColor(0, 85, 0) );
// display histogram
aPlot->displayObject( myHistogram, true );
if ( width == 0.0 ) // only one X value
aPlot->fitAll();
else
aPlot->fitData( 0, xmin, xmax, 0.0, ymax );
}
//=================================================================================
// function : clickOnCompute()
// purpose : called when Compute button was clicked
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::clickOnCompute()
{
GEOMUtils::Range aRange;
aRange.min = -1.0; // flag that range is empty
aRange.max = -1.0; // flag that range is empty
std::map<int,double> measures = GEOMUtils::ComputeMeasures( myShapes, currentType(), aRange );
if ( measures.size() != 0 ) {
SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 );
myMin->setText( DlgRef::PrintDoubleValue( aRange.min, aPrecision ) );
myMax->setText( DlgRef::PrintDoubleValue( aRange.max, aPrecision ) );
}
}
//=================================================================================
// function : clickOnCreateGroups()
// purpose : called when Create Groups button was clicked
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::clickOnCreateGroups()
{
onAccept(false, false, false);
}
//=================================================================================
// function : execute(ObjectList& objects)
// purpose :
//=================================================================================
bool MeasureGUI_ShapeStatisticsDlg::execute(ObjectList& objects)
{
if ( myMainObj.isNull() )
return false;
GEOM::GroupOpPtr anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
GEOMUtils::Range aRange;
if ( myScalarRangeBox->isChecked() ) {
QString msg;
if ( !isValid( msg ) ) {
showError( msg );
return false;
}
aRange.min = myMin->text().toDouble();
aRange.max = myMax->text().toDouble();
} else {
aRange.min = -1.0; // flag that range is empty
aRange.max = -1.0; // flag that range is empty
}
SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 );
QString aTypePrefix = myCBTypes->currentText().replace(' ', '_');
QString objIOR, aMin, aMax, aGroupName;
SalomeApp_Study* study = getStudy();
GEOMUtils::Distribution aShapesDistr =
GEOMUtils::ComputeDistribution( myShapes, currentType(), myNbIntervals->value(), aRange );
int nbGroups = 0;
GEOMUtils::Distribution::const_iterator it;
for (it = aShapesDistr.begin(); it != aShapesDistr.end(); it++) {
std::list<long> idList = (*it).indices;
int nn = idList.size();
if ( nn > 0 ) {
GEOM::ListOfLong_var aNewList = new GEOM::ListOfLong;
aNewList->length(nn);
int ii = 0;
std::list<long>::const_iterator id_it;
for ( id_it = idList.begin(); id_it != idList.end(); id_it++ ) {
aNewList[ii++] = *id_it;
}
// Create an empty group
GEOM::GEOM_Object_var aGroup;
aGroup = anOper->CreateGroup( myMainObj.get(), currentType() );
if (CORBA::is_nil(aGroup) || !anOper->IsDone())
return false;
// Add sub-shapes into group
anOper->UnionIDs(aGroup, aNewList);
if (!anOper->IsDone())
return false;
// publish group
aMin = DlgRef::PrintDoubleValue( (*it).min, aPrecision );
aMax = DlgRef::PrintDoubleValue( (*it).max, aPrecision );
aGroupName = aTypePrefix + "_" + aMin + "_" + aMax;
GEOMBase::PublishSubObject( aGroup, aGroupName );
// this is needed just to avoid error message
objects.push_back(aGroup._retn());
nbGroups++;
}
}
SUIT_MessageBox::information( this, tr( "INF_INFO" ), tr( "GEOM_MSG_GROUPS_CREATED" ).arg( nbGroups ) );
return true;
}
//=================================================================================
// function : clickOnHelp()
// purpose : called when Help button was clicked
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::clickOnHelp()
{
GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( myApp->module( "Geometry" ) );
myApp->onHelpContextModule( aGeomGUI ? myApp->moduleName( aGeomGUI->moduleName() ) : QString(""), "shape_statistics_operation_page.html" );
}

View File

@ -0,0 +1,92 @@
// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
// 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
//
// GEOM GEOMGUI : GUI for Geometry component
// File : MeasureGUI_ShapeStatisticsDlg.h
// Author : Alexander KOVALEV, Open CASCADE (alexander.kovalev@opencascade.com)
//
#ifndef MEASUREGUI_SHAPESTATISTICSDLG_H
#define MEASUREGUI_SHAPESTATISTICSDLG_H
// GEOM includes
#include <GEOMBase_Helper.h>
#include "GEOM_GenericObjPtr.h"
// Qt includes
#include <QDialog>
#include <QLineEdit>
#include <QPointer>
#include <QGroupBox>
// Qtx includes
#include <QtxIntSpinBox.h>
#include <QtxComboBox.h>
class Plot2d_Histogram;
//==========================================================================
// class : MeasureGUI_ShapeStatisticsDlg
// purpose :
//==========================================================================
class MeasureGUI_ShapeStatisticsDlg : public QDialog, public GEOMBase_Helper
{
Q_OBJECT
public:
MeasureGUI_ShapeStatisticsDlg( QWidget*, TopoDS_Shape aShape = TopoDS_Shape(), TopAbs_ShapeEnum aSubShapeType = TopAbs_SHAPE );
~MeasureGUI_ShapeStatisticsDlg();
protected:
// redefined from GEOMBase_Helper
virtual GEOM::GEOM_IOperations_ptr createOperation();
virtual bool isValid (QString&);
virtual bool execute (ObjectList&);
virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr);
virtual QList<GEOM::GeomObjPtr> getSourceObjects();
private slots:
void onEditMainShape();
void clickOnCompute();
void clickOnPlot();
void clickOnCreateGroups();
void clickOnHelp();
private:
void fillTypes( bool, bool, bool );
void updateTypes( QList<GEOM::GeomObjPtr> theShapes );
TopAbs_ShapeEnum currentType();
private:
SalomeApp_Application* myApp;
QLineEdit* myEditMainShape;
QtxComboBox* myCBTypes;
std::list<TopoDS_Shape> myShapes;
GEOM::GeomObjPtr myMainObj;
QtxIntSpinBox* myNbIntervals;
QGroupBox* myScalarRangeBox;
QLineEdit* myMin;
QLineEdit* myMax;
QPushButton* myButtonPlot;
QPushButton* myButtonCreateGr;
Plot2d_Histogram* myHistogram;
};
#endif // MEASUREGUI_SHAPESTATISTICSDLG_H