Salome HOME
22853: EDF 9924 GEOM: Dimension histogram
authorakl <alexander.kovalev@opencascade.com>
Thu, 23 Apr 2015 08:42:06 +0000 (12:42 +0400)
committervsr <vsr@opencascade.com>
Fri, 24 Apr 2015 15:52:02 +0000 (18:52 +0300)
28 files changed:
doc/salome/gui/GEOM/images/editgroup.png
doc/salome/gui/GEOM/images/geomcreategroup.png
doc/salome/gui/GEOM/images/shape_statistics.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/shape_statistics_simple.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/shape_statistics_operation.doc [new file with mode: 0644]
doc/salome/gui/GEOM/input/using_measurement_tools.doc
doc/salome/gui/GEOM/input/working_with_groups.doc
src/CMakeLists.txt
src/EntityGUI/CMakeLists.txt
src/EntityGUI/EntityGUI_SubShapeDlg.cxx
src/EntityGUI/EntityGUI_SubShapeDlg.h
src/GEOMBase/GEOMBase.cxx
src/GEOMBase/GEOMBase.h
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMGUI/GEOM_msg_ja.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI_Operations.h
src/GEOMUtils/CMakeLists.txt
src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx [new file with mode: 0644]
src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx [new file with mode: 0644]
src/GroupGUI/CMakeLists.txt
src/GroupGUI/GroupGUI_GroupDlg.cxx
src/GroupGUI/GroupGUI_GroupDlg.h
src/MeasureGUI/CMakeLists.txt
src/MeasureGUI/MeasureGUI.cxx
src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx [new file with mode: 0644]
src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h [new file with mode: 0644]

index c7f55074e27ea482a3fe678945ae82c6b0ea61e4..4501fa61ff4701073ab349387730f3f9ec365f1d 100755 (executable)
Binary files a/doc/salome/gui/GEOM/images/editgroup.png and b/doc/salome/gui/GEOM/images/editgroup.png differ
index 0f67a625c1f772ed7a469793c067a109ff01e0e1..c982f0bc93886bc8de8acdf5d47824c77bc3c99b 100755 (executable)
Binary files a/doc/salome/gui/GEOM/images/geomcreategroup.png and b/doc/salome/gui/GEOM/images/geomcreategroup.png differ
diff --git a/doc/salome/gui/GEOM/images/shape_statistics.png b/doc/salome/gui/GEOM/images/shape_statistics.png
new file mode 100644 (file)
index 0000000..2aaaa9a
Binary files /dev/null and b/doc/salome/gui/GEOM/images/shape_statistics.png differ
diff --git a/doc/salome/gui/GEOM/images/shape_statistics_simple.png b/doc/salome/gui/GEOM/images/shape_statistics_simple.png
new file mode 100644 (file)
index 0000000..bc2c076
Binary files /dev/null and b/doc/salome/gui/GEOM/images/shape_statistics_simple.png differ
diff --git a/doc/salome/gui/GEOM/input/shape_statistics_operation.doc b/doc/salome/gui/GEOM/input/shape_statistics_operation.doc
new file mode 100644 (file)
index 0000000..207db3b
--- /dev/null
@@ -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.
+
+*/
index 77a5ee4b3aecbb40dde9c228ddda5b5e167e485d..515a94ce4a7808c7942730e944c6d6ec2b716803 100644 (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:
index 36a0d49a30b84f48fb5abc434f6493376a53eba7..df36fd6a2c5801ddd05c5f946b457c827a1a61bf 100644 (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.
index d271e268eaef9f2b1eaabd65f07b1f6834b51a1a..6f830743b957ffe5951b5607bc6a753fbbd872aa 100755 (executable)
@@ -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()
index ecfc09a2d4f7fbd29dba91dae9789e5c93ab9d50..0bb93f921c92435cfd152cf93f47709b534d103f 100755 (executable)
@@ -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
index 9db5fbab0723d932e37a3e99b5a037fddaf78724..598d05de696a15242499b921f372e42b8046f7ea 100644 (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  :
index e3618ac41e97b5d5d6b210384930b1cea21c9c06..c2f14e66e0a8d1326c3caa20321d3cbfc803188d 100644 (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;
 };
 
index e10909ddca19a73d142a7305a86791d3eeadbd55..0cfe8f6aed6d58ba05089445c9f6225452d4e0a2 100644 (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() );
     }
   }
 }
index 242e5fdcdfb664331744e3bd6c867436173d16f5..69e21e778a533a3639928a0cd24c86cfcc7255d3 100644 (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 );
 };
index c1e7addb1a81172f90750fb6e6f0dee423a93ca4..c67b290feba7362eab118cbb672ec97516e3bdab 100644 (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>
index 69786b158fc606e8df4b23ca0712f413462566a1..0ab7e34fc6dc1e8b2abcb8073cf1d230dd29b27c 100644 (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>
@@ -3539,7 +3547,11 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
     <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>
@@ -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>
index 6b5668ec800ad0d5dc670430ddb3184da6e6228b..75807fcc71114f00d3a01419d14e22bd597b0ea7 100644 (file)
         <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>
index 790e65a7d8cab6f9dbc42f8202ee8a9a79d9a2df..25832ed53cda0cb3bb6b5bcfcf6ac99176873049 100644 (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
index 915f5d1f18bc026eb1e0d0bf7bda802b641ed792..865ac91d9a171aa5a93fb7cc0e08ecdc30db11b1 100644 (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
index 039990ab77c4edf7b699ebf53f3a1ee0c148acee..a2bbfd9d00d295b8c7514cf029876560656a52f5 100755 (executable)
@@ -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
diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx
new file mode 100644 (file)
index 0000000..81ae5ae
--- /dev/null
@@ -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
diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx
new file mode 100644 (file)
index 0000000..703050e
--- /dev/null
@@ -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_
index acf593702c81fbebe5b6adecd7cfee965a6d5ab8..73e18271bbad8586b320fa1d3d9df1ec762b64f8 100755 (executable)
@@ -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 ---
index 82a51075e3484b6ed45718cc04a44b75fca4acf2..a13977ef6c54257a6ed266efc28148197297a284 100644 (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());
index ad8f4e1598b804debb903745d9184ebf7f1cdf5d..231ea033a1264c08b301a4026562a37be0dcf431 100644 (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;
 };
 
index c7ab327c1b6a1106bb32adfa9ae8b73f46cc047c..31e2375ac37d2966fd994cc29f866057d0fb322b 100755 (executable)
@@ -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}
   )
index 37c8ed4b22d5b03ed74dec05fd373ec70be0c2af..1ab692d327486ec5eecd1a5e77f45a46714649b4 100644 (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
diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx
new file mode 100644 (file)
index 0000000..9387cf4
--- /dev/null
@@ -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" );
+}
diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h
new file mode 100644 (file)
index 0000000..8013132
--- /dev/null
@@ -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