1 // Copyright (C) 2015 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;
48 for ( it = shapes.begin(); it != shapes.end(); ++it ) {
50 TopTools_IndexedMapOfShape aSubShapesMap;
51 TopExp::MapShapes(*it, aSubShapesMap); // map of all global indices
52 TopTools_IndexedMapOfShape aMx;
53 TopExp::MapShapes( *it, entity, aMx ); // map of current type sub-shape indices
54 int aNbS = aMx.Extent();
56 for ( int i = 1; i <= aNbS; ++i ) {
58 const TopoDS_Shape& aSubShape = aMx( i );
59 //Get the measure: length, area or volume
60 GProp_GProps LProps, SProps, VProps;
61 if ( entity == TopAbs_EDGE ) {
62 BRepGProp::LinearProperties( aSubShape, LProps );
63 aMeasure = LProps.Mass();
64 } else if ( entity == TopAbs_FACE ) {
65 BRepGProp::SurfaceProperties( aSubShape, SProps );
66 aMeasure = SProps.Mass();
67 } else if ( entity == TopAbs_SOLID ) {
68 BRepGProp::VolumeProperties( aSubShape, VProps );
69 aMeasure = VProps.Mass();
71 // Don't pass sub-shapes with out of range measure, if range is used
73 if ( aMeasure < range.min || aMeasure > range.max )
76 // get range min and max
77 if ( aMeasure < range.min ) range.min = aMeasure;
78 if ( aMeasure > range.max ) range.max = aMeasure;
80 // get global index of sub-shape
81 index = aSubShapesMap.FindIndex( aSubShape );
82 // keep measures to distribute it
83 measures[index] = aMeasure;
89 //=================================================================================
90 // function : ComputeDistribution()
91 // purpose : gets distribution data for single shape
92 //=================================================================================
93 Distribution ComputeDistribution( TopoDS_Shape shape,
94 TopAbs_ShapeEnum entity,
98 std::list<TopoDS_Shape> aShapes;
99 aShapes.push_back( shape );
100 return ComputeDistribution( aShapes, entity, intervals, range );
103 //=================================================================================
104 // function : ComputeDistribution()
105 // purpose : gets distribution data for list of shapes
106 //=================================================================================
107 Distribution ComputeDistribution( std::list<TopoDS_Shape> shapes,
108 TopAbs_ShapeEnum entity,
112 // get list of measures and compute range (if it was not specified)
113 std::map<int,double> measures = ComputeMeasures( shapes, entity, range );
116 double aStep = (range.max - range.min) / nbIntervals;
118 // compute distribution in intervals
120 std::map<int,double>::iterator dit;
121 for ( int i = 0; i < nbIntervals; i++ ) {
122 Range localRange; // range of current interval
123 localRange.min = range.min + ( i * aStep );
124 localRange.max = range.min + ( (i+1) * aStep );
125 localRange.count = 0;
127 std::vector<int> indicesToErase;
128 for ( dit = measures.begin(); dit != measures.end(); dit++ ) {
129 if ( ( dit->second >= localRange.min && dit->second < localRange.max ) ||
130 ( i == nbIntervals-1 && dit->second == localRange.max ) ) {
132 localRange.indices.push_back( dit->first );
133 // measure is in interval, so remove it from map of search
134 indicesToErase.push_back( dit->first );
137 aDistr.push_back( localRange );
138 for( int j=0; j < indicesToErase.size(); j++ )
139 measures.erase( indicesToErase[j] );
145 } //namespace GEOMUtils