]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
22853: EDF 9924 GEOM: Dimension histogram
authorakl <alexander.kovalev@opencascade.com>
Thu, 23 Apr 2015 08:42:06 +0000 (12:42 +0400)
committerakl <alexander.kovalev@opencascade.com>
Thu, 23 Apr 2015 08:42:06 +0000 (12:42 +0400)
19 files changed:
src/CMakeLists.txt
src/EntityGUI/CMakeLists.txt
src/EntityGUI/EntityGUI_SubShapeDlg.cxx
src/EntityGUI/EntityGUI_SubShapeDlg.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 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 c1e7addb1a81172f90750fb6e6f0dee423a93ca4..64727e1af309090c306b03785ff99877bffbec73 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,65 @@ 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>
+</context>
 <context>
     <name>TransformationGUI_ExtensionDlg</name>
     <message>
index 69786b158fc606e8df4b23ca0712f413462566a1..a895bf9605c280b4ad03f31add34263b74d5c1bd 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,65 @@ 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>
+</context>
 <context>
     <name>TransformationGUI_ExtensionDlg</name>
     <message>
index 6b5668ec800ad0d5dc670430ddb3184da6e6228b..c3e895e1e50f66f1142c4a68f7a3266abc45708a 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>
+</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..3343e2c
--- /dev/null
@@ -0,0 +1,154 @@
+// 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 aMx;
+    TopExp::MapShapes( *it, entity, aMx );
+    int aNbS = aMx.Extent();
+    int index = -1;
+    for ( int i = 1; i <= aNbS; ++i ) {
+      aMeasure = 0.0;
+      const TopoDS_Shape& aSubShape = aMx( i );
+      index = aMx.FindIndex( aSubShape );
+      //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;
+      }
+      // 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;
+}
+
+//=================================================================================
+// function : FilterSubShapes()
+// purpose  : gets list of sub-shapes IDs according to the specified range data (needed for groups creation function)
+//=================================================================================
+std::list<long> FilterSubShapes( TopoDS_Shape shape, 
+                                TopAbs_ShapeEnum entity, 
+                                Range range)
+{
+  std::list<long> idList;
+  return idList;
+}
+
+} //namespace GEOMUtils
diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx
new file mode 100644 (file)
index 0000000..73c29ed
--- /dev/null
@@ -0,0 +1,67 @@
+// 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 );
+
+  // function to get list of sub-shapes IDs according to the specified range data (needed for groups creation function).
+  Standard_EXPORT std::list<long> FilterSubShapes(
+    TopoDS_Shape shape, 
+    TopAbs_ShapeEnum entity, 
+    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..febb7fa
--- /dev/null
@@ -0,0 +1,486 @@
+// 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 <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>
+
+//===========================================================================
+// 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 );
+  myMainObj = GEOM::GEOM_Object::_nil();
+
+  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() );
+  //myViewWindow = myApp->desktop()->activeWindow();
+
+  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 );
+  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 : 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].get();
+    QString aName = selShapes.count() > 1 ? QString( "%1_objects").arg( selShapes.count() ) : GEOMBase::GetName( myMainObj );
+    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"), 0 );
+  if ( hasFaces )
+    myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_AREA"), 1 );
+  if ( hasSolids )
+    myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_VOLUME"), 2 );
+
+  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 ) {
+      hasEdges, hasFaces, hasSolids = 0;
+      return;
+    }
+    TopoDS_Shape aShape;
+    if ( !GEOMBase::GetShape( aShapePtr.get(), aShape ) || aShape.IsNull() ) {
+      hasEdges, hasFaces, hasSolids = 0;
+      return;
+  }
+
+    myShapes.push_back( aShape );
+
+    GEOM::ListOfLong_var aSubShapes;
+    GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
+    if ( hasEdges != 0 ) {
+      aSubShapes = aShOp->SubShapeAllIDs( aShapePtr.get(), TopAbs_EDGE, false );
+      hasEdges = aSubShapes->length() > 0;
+    }
+    if ( hasFaces != 0 ) {
+      aSubShapes = aShOp->SubShapeAllIDs( aShapePtr.get(), TopAbs_FACE, false );
+      hasFaces = aSubShapes->length() > 0;
+    }
+    if ( hasSolids != 0 ) {
+      aSubShapes = aShOp->SubShapeAllIDs( aShapePtr.get(), TopAbs_SOLID, false );
+      hasSolids = aSubShapes->length() > 0;
+    }
+  }
+  fillTypes( hasEdges, hasFaces, hasSolids );
+}
+
+//=================================================================================
+// function : currentType()
+// purpose  : returns currently selected type of shapes in 'Type' combobox
+//=================================================================================
+TopAbs_ShapeEnum MeasureGUI_ShapeStatisticsDlg::currentType()
+{
+  switch ( myCBTypes->itemData( myCBTypes->currentIndex() ).toInt() ) {
+  case 0:
+    return TopAbs_EDGE;
+  case 1:
+    return TopAbs_FACE;
+  case 2:
+    return TopAbs_SOLID;
+  }
+}
+
+//=================================================================================
+// function : clickOnPlot()
+// purpose  : called when Plot button was clicked
+//=================================================================================
+bool MeasureGUI_ShapeStatisticsDlg::checkInput()
+{
+  if ( myMin->text().isEmpty() ) {
+    showError( tr("GEOM_SHAPE_STATISTICS_MIN_ERROR") );
+    return false;
+  }
+  if ( myMax->text().isEmpty() ) {
+    showError( tr("GEOM_SHAPE_STATISTICS_MAX_ERROR" ) );
+    return false;
+  }
+  if (myMin->text().toDouble() > myMax->text().toDouble()) {
+    showError( tr("GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR" ) );
+    return false;
+  }
+  return true;
+}
+//=================================================================================
+// function : clickOnPlot()
+// purpose  : called when Plot button was clicked
+//=================================================================================
+void MeasureGUI_ShapeStatisticsDlg::clickOnPlot()
+{
+  GEOMUtils::Range aRange;
+  if ( myScalarRangeBox->isChecked() ) {
+    if ( !checkInput() )
+      return;
+    aRange.min = myMin->text().toDouble();
+    aRange.max = myMax->text().toDouble();
+  } else {
+    aRange.min = -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_Viewer* aView = dynamic_cast<Plot2d_Viewer*>(aViewManager->getViewModel());
+  if ( !aView )
+    return;
+  Plot2d_ViewWindow* aViewWnd = dynamic_cast<Plot2d_ViewWindow*>(aViewManager->getActiveView());
+  if( !aViewWnd )
+    return;
+  aViewWnd->setFocus();
+  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
+  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()
+{
+  GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
+
+  GEOMUtils::Range aRange;
+  if ( myScalarRangeBox->isChecked() ) {
+    if ( !checkInput() )
+      return;
+    aRange.min = myMin->text().toDouble();
+    aRange.max = myMax->text().toDouble();
+  } else {
+    aRange.min = -1.0; // flag that range is empty
+  }
+
+  GEOMUtils::Distribution aShapesDistr = 
+    GEOMUtils::ComputeDistribution( myShapes, currentType(), myNbIntervals->value(), aRange );
+
+  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;
+       ii++;
+      }
+
+      if (CORBA::is_nil(myMainObj))
+       return;
+
+      GEOM::GEOM_Object_var aGroup;
+      aGroup = anOper->CreateGroup( myMainObj, currentType() );
+
+      if (CORBA::is_nil(aGroup) || !anOper->IsDone())
+       return;
+
+      GEOM::ListOfLong_var aCurrList = anOper->GetObjects(aGroup);
+      if (!anOper->IsDone())
+       return;
+
+      if (aCurrList->length() > 0)
+       {
+         anOper->DifferenceIDs(aGroup, aCurrList);
+         if (!anOper->IsDone())
+           return;
+       }
+
+      anOper->UnionIDs(aGroup, aNewList);
+      if (!anOper->IsDone())
+       return;
+    }
+  }
+}
+
+//=================================================================================
+// 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(""), "create_sketcher_page.html" );
+}
diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h
new file mode 100644 (file)
index 0000000..64c39f3
--- /dev/null
@@ -0,0 +1,86 @@
+// 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();
+  
+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();
+  bool                    checkInput();
+
+private:
+  SalomeApp_Application*     myApp;
+  QPointer<SUIT_ViewWindow>  myViewWindow;
+  QLineEdit*                 myEditMainShape;
+  QtxComboBox*               myCBTypes;
+  std::list<TopoDS_Shape>    myShapes;
+  GEOM::GEOM_Object_var      myMainObj;
+  QtxIntSpinBox*             myNbIntervals;
+  QGroupBox*                 myScalarRangeBox;
+  QLineEdit*                 myMin;
+  QLineEdit*                 myMax;
+  QPushButton*               myButtonPlot;
+  QPushButton*               myButtonCreateGr;
+  Plot2d_Histogram*          myHistogram;
+
+};
+
+#endif // MEASUREGUI_SHAPESTATISTICSDLG_H