diff --git a/doc/salome/gui/GEOM/images/editgroup.png b/doc/salome/gui/GEOM/images/editgroup.png
index c7f55074e..4501fa61f 100755
Binary files a/doc/salome/gui/GEOM/images/editgroup.png and b/doc/salome/gui/GEOM/images/editgroup.png differ
diff --git a/doc/salome/gui/GEOM/images/geomcreategroup.png b/doc/salome/gui/GEOM/images/geomcreategroup.png
index 0f67a625c..c982f0bc9 100755
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
index 000000000..2aaaa9ad3
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
index 000000000..bc2c0767b
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
index 000000000..207db3b75
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/shape_statistics_operation.doc
@@ -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 Shape Statistics dialog box, in the Main Menu select Inspection - > Shape Statistics.
+
+\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 Close button.
+
+*/
diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
index 77a5ee4b3..515a94ce4 100644
--- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc
+++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
@@ -19,6 +19,7 @@
\subpage managing_dimensions_page "Dimensions"
\subpage whatis_page "WhatIs"
\subpage inspect_object_operation_page "Inspect Object"
+\subpage shape_statistics_operation_page "Shape Statistics"
\n To check their integrity:
diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc
index 36a0d49a3..df36fd6a2 100644
--- a/doc/salome/gui/GEOM/input/working_with_groups.doc
+++ b/doc/salome/gui/GEOM/input/working_with_groups.doc
@@ -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 New entity > Group > Create
-\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 TUI Command: geompy.CreateGroup(MainShape,
ShapeType), where MainShape is a shape for which the group is
created, ShapeType is a type of shapes in the created group.
diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx
index 3343e2c2c..81ae5aeba 100644
--- a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx
+++ b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx
@@ -47,14 +47,15 @@ namespace GEOMUtils
std::list::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 );
+ 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 );
- index = aMx.FindIndex( aSubShape );
//Get the measure: length, area or volume
GProp_GProps LProps, SProps, VProps;
if ( entity == TopAbs_EDGE ) {
@@ -76,6 +77,8 @@ namespace GEOMUtils
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;
}
@@ -139,16 +142,4 @@ Distribution ComputeDistribution( std::list shapes,
return aDistr;
}
-//=================================================================================
-// function : FilterSubShapes()
-// purpose : gets list of sub-shapes IDs according to the specified range data (needed for groups creation function)
-//=================================================================================
-std::list FilterSubShapes( TopoDS_Shape shape,
- TopAbs_ShapeEnum entity,
- Range range)
-{
- std::list idList;
- return idList;
-}
-
} //namespace GEOMUtils
diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx
index 73c29ed61..703050e51 100644
--- a/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx
+++ b/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx
@@ -56,12 +56,6 @@ namespace GEOMUtils
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 FilterSubShapes(
- TopoDS_Shape shape,
- TopAbs_ShapeEnum entity,
- Range range );
-
}
#endif // _GEOMUtils_ShapeStatistics_HXX_
diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx
index febb7fab8..61a059399 100644
--- a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx
+++ b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx
@@ -40,6 +40,7 @@
#include
#include
+#include
#include
#include
@@ -58,6 +59,8 @@
// OCC includes
#include
+#include
+
//===========================================================================
// class : MeasureGUI_ShapeStatisticsDlg()
//===========================================================================
@@ -67,7 +70,6 @@ MeasureGUI_ShapeStatisticsDlg::MeasureGUI_ShapeStatisticsDlg( QWidget* parent, T
myHistogram ( 0 )
{
myShapes.push_back( aShape );
- myMainObj = GEOM::GEOM_Object::_nil();
QIcon iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
@@ -75,7 +77,6 @@ MeasureGUI_ShapeStatisticsDlg::MeasureGUI_ShapeStatisticsDlg( QWidget* parent, T
setAttribute( Qt::WA_DeleteOnClose );
myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
- //myViewWindow = myApp->desktop()->activeWindow();
QVBoxLayout* topLayout = new QVBoxLayout( this );
@@ -154,6 +155,7 @@ MeasureGUI_ShapeStatisticsDlg::MeasureGUI_ShapeStatisticsDlg( QWidget* parent, T
/********************** 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 );
@@ -198,6 +200,48 @@ 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 MeasureGUI_ShapeStatisticsDlg::getSourceObjects()
+{
+ QList res;
+ GEOM::GeomObjPtr aGeomObjPtr1(myMainObj);
+ res << aGeomObjPtr1;
+ return res;
+}
+
//=================================================================================
// function : onEditMainShape()
// purpose : called when selection button was clicked
@@ -216,8 +260,8 @@ void MeasureGUI_ShapeStatisticsDlg::onEditMainShape()
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 );
+ myMainObj = selShapes[0];
+ QString aName = selShapes.count() > 1 ? QString( "%1_objects").arg( selShapes.count() ) : GEOMBase::GetName( myMainObj.get() );
myEditMainShape->setText( aName );
}
@@ -304,19 +348,12 @@ TopAbs_ShapeEnum MeasureGUI_ShapeStatisticsDlg::currentType()
// function : clickOnPlot()
// purpose : called when Plot button was clicked
//=================================================================================
-bool MeasureGUI_ShapeStatisticsDlg::checkInput()
+bool MeasureGUI_ShapeStatisticsDlg::isValid(QString& theMessage)
{
- 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;
+ 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;
}
@@ -328,8 +365,11 @@ void MeasureGUI_ShapeStatisticsDlg::clickOnPlot()
{
GEOMUtils::Range aRange;
if ( myScalarRangeBox->isChecked() ) {
- if ( !checkInput() )
+ QString msg;
+ if ( !isValid( msg ) ) {
+ showError( msg );
return;
+ }
aRange.min = myMin->text().toDouble();
aRange.max = myMax->text().toDouble();
} else {
@@ -361,13 +401,10 @@ void MeasureGUI_ShapeStatisticsDlg::clickOnPlot()
SUIT_ViewManager* aViewManager = myApp->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary
if( !aViewManager )
return;
- Plot2d_Viewer* aView = dynamic_cast(aViewManager->getViewModel());
- if ( !aView )
- return;
+ aViewManager->getActiveView()->setFocus();
Plot2d_ViewWindow* aViewWnd = dynamic_cast(aViewManager->getActiveView());
if( !aViewWnd )
return;
- aViewWnd->setFocus();
Plot2d_ViewFrame* aPlot = aViewWnd->getViewFrame();
if ( !aPlot )
return;
@@ -419,18 +456,37 @@ void MeasureGUI_ShapeStatisticsDlg::clickOnCompute()
//=================================================================================
void MeasureGUI_ShapeStatisticsDlg::clickOnCreateGroups()
{
- GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
+ 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() ) {
- if ( !checkInput() )
- return;
+ 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
}
+ 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 );
@@ -448,31 +504,40 @@ void MeasureGUI_ShapeStatisticsDlg::clickOnCreateGroups()
ii++;
}
- if (CORBA::is_nil(myMainObj))
- return;
-
+ // Create an empty group
GEOM::GEOM_Object_var aGroup;
- aGroup = anOper->CreateGroup( myMainObj, currentType() );
+ aGroup = anOper->CreateGroup( myMainObj.get(), 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;
- }
+ return false;
+ // Add sub-shapes into group
anOper->UnionIDs(aGroup, aNewList);
if (!anOper->IsDone())
- return;
+ return false;
+
+ GEOMBase::PublishSubObject( aGroup );
+
+ // Set a correct group name
+ if (study) {
+ objIOR = GEOMBase::GetIORFromObject(aGroup);
+ if (objIOR != "") {
+ _PTR(SObject) SO (study->studyDS()->FindObjectIOR(objIOR.toLatin1().constData()));
+ if (SO) {
+ aMin = DlgRef::PrintDoubleValue( (*it).min, aPrecision );
+ aMax = DlgRef::PrintDoubleValue( (*it).max, aPrecision );
+ aGroupName = aTypePrefix + "_" + aMin + "_" + aMax;
+ _PTR(StudyBuilder) aBuilder (study->studyDS()->NewBuilder());
+ aBuilder->SetName(SO, aGroupName.toLatin1().constData());
+ }
+ }
+ }
+ // add group to be published
+ objects.push_back(aGroup._retn());
}
}
+
+ return true;
}
//=================================================================================
diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h
index 64c39f3bf..80131321b 100644
--- a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h
+++ b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h
@@ -53,6 +53,14 @@ 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 getSourceObjects();
+
private slots:
void onEditMainShape();
void clickOnCompute();
@@ -64,15 +72,13 @@ private:
void fillTypes( bool, bool, bool );
void updateTypes( QList theShapes );
TopAbs_ShapeEnum currentType();
- bool checkInput();
private:
SalomeApp_Application* myApp;
- QPointer myViewWindow;
QLineEdit* myEditMainShape;
QtxComboBox* myCBTypes;
std::list myShapes;
- GEOM::GEOM_Object_var myMainObj;
+ GEOM::GeomObjPtr myMainObj;
QtxIntSpinBox* myNbIntervals;
QGroupBox* myScalarRangeBox;
QLineEdit* myMin;