1 // Copyright (C) 2015-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : GEOMUtils_ShapeStatisticsDlg.cxx
21 // Author : Alexander KOVALEV, OPEN CASCADE S.A.S.
23 #include "GEOMUtils_ShapeStatistics.hxx"
25 #include <BRepGProp.hxx>
26 #include <GProp_GProps.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopTools_IndexedMapOfShape.hxx>
33 //=================================================================================
34 // function : ComputeMeasures()
35 // purpose : gets measures of the given type for list of shapes in the range
36 //=================================================================================
37 std::map<int,double> ComputeMeasures( std::list<TopoDS_Shape> shapes,
38 TopAbs_ShapeEnum entity,
41 bool hasRange = (range.min != -1.0); // -1.0 means that range must not be used
43 range.min = 1e+32, range.max = 0.0;
44 // list of measures of entities
45 std::map<int, double> measures;
47 std::list<TopoDS_Shape>::const_iterator it;
49 for ( it = shapes.begin(); it != shapes.end(); ++it ) {
51 TopTools_IndexedMapOfShape aSubShapesMap;
52 TopExp::MapShapes(*it, aSubShapesMap); // map of all global indices
53 TopTools_IndexedMapOfShape aMx;
54 TopExp::MapShapes( *it, entity, aMx ); // map of current type sub-shape indices
55 int aNbS = aMx.Extent();
57 for ( int i = 1; i <= aNbS; ++i ) {
59 const TopoDS_Shape& aSubShape = aMx( i );
60 //Get the measure: length, area or volume
61 GProp_GProps LProps, SProps, VProps;
62 if ( entity == TopAbs_EDGE ) {
63 BRepGProp::LinearProperties( aSubShape, LProps );
64 aMeasure = LProps.Mass();
65 } else if ( entity == TopAbs_FACE ) {
66 BRepGProp::SurfaceProperties( aSubShape, SProps );
67 aMeasure = SProps.Mass();
68 } else if ( entity == TopAbs_SOLID ) {
69 BRepGProp::VolumeProperties( aSubShape, VProps );
70 aMeasure = VProps.Mass();
72 // Don't pass sub-shapes with out of range measure, if range is used
74 if ( aMeasure < range.min || aMeasure > range.max )
77 // get range min and max
78 if ( aMeasure < range.min ) range.min = aMeasure;
79 if ( aMeasure > range.max ) range.max = aMeasure;
81 // get global index of sub-shape
82 index = aSubShapesMap.FindIndex( aSubShape );
83 // keep measures to distribute it
84 measures[shift+index] = aMeasure;
86 shift += aSubShapesMap.Extent();
91 //=================================================================================
92 // function : ComputeDistribution()
93 // purpose : gets distribution data for single shape
94 //=================================================================================
95 Distribution ComputeDistribution( TopoDS_Shape shape,
96 TopAbs_ShapeEnum entity,
100 std::list<TopoDS_Shape> aShapes;
101 aShapes.push_back( shape );
102 return ComputeDistribution( aShapes, entity, intervals, range );
105 //=================================================================================
106 // function : ComputeDistribution()
107 // purpose : gets distribution data for list of shapes
108 //=================================================================================
109 Distribution ComputeDistribution( std::list<TopoDS_Shape> shapes,
110 TopAbs_ShapeEnum entity,
114 // get list of measures and compute range (if it was not specified)
115 std::map<int,double> measures = ComputeMeasures( shapes, entity, range );
118 double aStep = (range.max - range.min) / nbIntervals;
120 // compute distribution in intervals
122 std::map<int,double>::iterator dit;
123 for ( int i = 0; i < nbIntervals; i++ ) {
124 Range localRange; // range of current interval
125 localRange.min = range.min + ( i * aStep );
126 localRange.max = range.min + ( (i+1) * aStep );
127 localRange.count = 0;
129 std::vector<int> indicesToErase;
130 for ( dit = measures.begin(); dit != measures.end(); dit++ ) {
131 if ( ( dit->second >= localRange.min && dit->second < localRange.max ) ||
132 ( i == nbIntervals-1 && dit->second == localRange.max ) ) {
134 localRange.indices.push_back( dit->first );
135 // measure is in interval, so remove it from map of search
136 indicesToErase.push_back( dit->first );
139 aDistr.push_back( localRange );
140 for( size_t j=0; j < indicesToErase.size(); j++ )
141 measures.erase( indicesToErase[j] );
147 } //namespace GEOMUtils