--- /dev/null
+/*!
+
+\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.
+
+*/
<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:
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
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.
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()
${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
DlgRef
GEOMSketcher
CurveCreator
+ MeasureGUI
)
# optional sources
#include <GeometryGUI.h>
#include <GEOMBase.h>
#include <GEOMUtils.hxx>
+#include <MeasureGUI_ShapeStatisticsDlg.h>
#include <OCCViewer_ViewModel.h>
#include <SVTK_ViewModel.h>
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);
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);
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()));
GroupPoints->CheckButton1->isChecked() &&
shapeType() < GEOM::VERTEX);
+ myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() &&
+ ( shapeType() == TopAbs_EDGE ||
+ shapeType() == TopAbs_FACE ||
+ shapeType() == TopAbs_SOLID ) );
+
activateSelection();
}
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 :
void showOnlySelected();
void ClickOnOkFilter();
+ void ClickOnPlot();
void MeasureToggled();
private:
SalomeApp_DoubleSpinBox* myLessFilterSpin;
SalomeApp_DoubleSpinBox* myGreaterFilterSpin;
QPushButton* myApplyFilterButton;
+ QPushButton* myPlotDistributionButton;
QGroupBox* myFilterGrp;
};
// 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 ) ) {
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() );
}
}
}
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 );
};
<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>
<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>
</message>
<message>
<source>MEN_MEASURES</source>
- <translation>Measures</translation>
+ <translation>Inspection</translation>
</message>
<message>
<source>MEN_MIN_DIST</source>
<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>
<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>
<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>
</message>
<message>
<source>TOOL_MEASURES</source>
- <translation>Measures</translation>
+ <translation>Inspection</translation>
</message>
<message>
<source>TOOL_IMPORTEXPORT</source>
<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>
<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>
<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>
</message>
<message>
<source>MEN_MEASURES</source>
- <translation>Mesures</translation>
+ <translation type="unfinished">Inspection</translation>
</message>
<message>
<source>MEN_MIN_DIST</source>
<message>
<source>STB_FAST_CHECK_INTERSECTIONS</source>
<translation>Intersection rapide</translation>
- </message>
+ </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>
<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>
<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>
</message>
<message>
<source>TOOL_MEASURES</source>
- <translation>Informations</translation>
+ <translation type="unfinished">Inspection</translation>
</message>
<message>
<source>TOOL_IMPORTEXPORT</source>
<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>
<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>
<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>
</message>
<message>
<source>MEN_MEASURES</source>
- <translation>計測</translation>
+ <translation type="unfinished">Inspection</translation>
</message>
<message>
<source>MEN_MIN_DIST</source>
<message>
<source>STB_FAST_CHECK_INTERSECTIONS</source>
<translation type="unfinished">Fast intersection</translation>
- </message>
+ </message>
+ <message>
+ <source>STB_SHAPE_STATISTICS</source>
+ <translation type="unfinished">Shape Statistics</translation>
+ </message>
<message>
<source>STB_CHECK_FREE_BNDS</source>
<translation>自由境界をチェック</translation>
<translation>自己交差の確認</translation>
</message>
<message>
- <source>TOP_FAST_CHECK_INTERSECTIONS</source>
- <translation type="unfinished">Fast intersection</translation>
+ <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>
<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>
</message>
<message>
<source>TOOL_MEASURES</source>
- <translation type="unfinished">Measures</translation>
+ <translation type="unfinished">Inspection</translation>
</message>
<message>
<source>TOOL_IMPORTEXPORT</source>
<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>
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";
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" );
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
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
GEOMUtils.hxx
GEOMUtils_Hatcher.hxx
GEOMUtils_HTrsfCurve2d.hxx
+ GEOMUtils_ShapeStatistics.hxx
GEOMUtils_Trsf2d.hxx
GEOMUtils_TrsfCurve2d.hxx
GEOMUtils_XmlHandler.hxx
GEOMUtils.cxx
GEOMUtils_Hatcher.cxx
GEOMUtils_HTrsfCurve2d.cxx
+ GEOMUtils_ShapeStatistics.cxx
GEOMUtils_Trsf2d.cxx
GEOMUtils_TrsfCurve2d.cxx
GEOMUtils_XmlHandler.cxx
--- /dev/null
+// 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
--- /dev/null
+// 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_
${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}
SET(_link_LIBRARIES
GEOMBase
GEOMUtils
+ MeasureGUI
)
# --- resources ---
#include <GeometryGUI.h>
#include <GEOM_Displayer.h>
#include <GEOMUtils.hxx>
+#include <MeasureGUI_ShapeStatisticsDlg.h>
#include <SalomeApp_Application.h>
#include <SalomeApp_Study.h>
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);
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);
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()));
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());
}
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());
void showOnlySelected();
void selectionChanged();
void ClickOnOkFilter();
+ void ClickOnPlot();
void MeasureToggled();
private:
SalomeApp_DoubleSpinBox* myLessFilterSpin;
SalomeApp_DoubleSpinBox* myGreaterFilterSpin;
QPushButton* myApplyFilterButton;
+ QPushButton* myPlotDistributionButton;
QGroupBox* myFilterGrp;
};
MeasureGUI_ManageDimensionsDlg.h
MeasureGUI_CreateDimensionDlg.h
MeasureGUI_DimensionInteractor.h
+ MeasureGUI_ShapeStatisticsDlg.h
)
# header files / uic wrappings
MeasureGUI_DimensionCreateTool.cxx
MeasureGUI_DimensionInteractor.cxx
MeasureGUI_DimensionFilter.cxx
+ MeasureGUI_ShapeStatisticsDlg.cxx
${_moc_SOURCES}
${_uic_files}
)
#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>
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
--- /dev/null
+// 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" );
+}
--- /dev/null
+// 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