0025630: Possible memory leaks in BRepGProp_Vinert and BRepGProp_Sinert
[occt.git] / src / BRepGProp / BRepGProp_Gauss.hxx
1 // Copyright (c) 2015 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _BRepGProp_Gauss_HeaderFile
15 #define _BRepGProp_Gauss_HeaderFile
16
17 #include <NCollection_Handle.hxx>
18 #include <NCollection_Array1.hxx>
19
20 class math_Vector;
21
22 //! Class performs computing of the global inertia properties
23 //! of geometric object in 3D space by adaptive and non-adaptive
24 //! 2D Gauss integration algorithms.
25 class BRepGProp_Gauss
26 {
27   //! Auxiliary structure for storing of inertial moments.
28   struct Inertia
29   {
30     //! Mass of the current system (without density).
31     //! May correspond to: length, area, volume.
32     Standard_Real Mass;
33
34     //! Static moments of inertia.
35     Standard_Real Ix;
36     Standard_Real Iy;
37     Standard_Real Iz;
38
39     //! Quadratic moments of inertia.
40     Standard_Real Ixx;
41     Standard_Real Iyy;
42     Standard_Real Izz;
43     Standard_Real Ixy;
44     Standard_Real Ixz;
45     Standard_Real Iyz;
46
47     //! Default constructor.
48     Inertia();
49
50     //! Zeroes all values.
51     void Reset();
52   };
53
54   typedef NCollection_Handle< NCollection_Array1<Inertia> > InertiaArray;
55   typedef NCollection_Handle<math_Vector>                   Handle_Vector;
56   typedef Standard_Real(*BRepGProp_GaussFunc)(const Standard_Real, const Standard_Real);
57
58 public: //! @name public API
59
60   //! Describes types of geometric objects.
61   //! - Vinert is 3D closed region of space delimited with:
62   //! -- Surface;
63   //! -- Point and Surface;
64   //! -- Plane and Surface.
65   //! - Sinert is face in 3D space.
66   typedef enum { Vinert = 0, Sinert } BRepGProp_GaussType;
67
68   //! Constructor
69   Standard_EXPORT explicit BRepGProp_Gauss(const BRepGProp_GaussType theType);
70
71   //! Computes the global properties of a solid region of 3D space which can be
72   //! delimited by the surface and point or surface and plane. Surface can be closed.
73   //! The method is quick and its precision is enough for many cases of analytical surfaces.
74   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points
75   //! is used. Numbers of points depend on types of surfaces and curves.
76   //! Error of the computation is not calculated.
77   //! @param theSurface - bounding surface of the region;
78   //! @param theLocation - location of the point or the plane;
79   //! @param theCoeff - plane coefficients;
80   //! @param theIsByPoint - flag of restricition (point/plane);
81   //! @param theOutMass[out] - mass (volume) of region;
82   //! @param theOutGravityCenter[out] - garvity center of region;
83   //! @param theOutInertia[out] - matrix of inertia;
84   Standard_EXPORT void Compute(
85     const BRepGProp_Face&  theSurface,
86     const gp_Pnt&          theLocation,
87     const Standard_Real    theCoeff[],
88     const Standard_Boolean theIsByPoint,
89     Standard_Real&         theOutMass,
90     gp_Pnt&                theOutGravityCenter,
91     gp_Mat&                theOutInertia);
92
93   //! Computes the global properties of a surface. Surface can be closed.
94   //! The method is quick and its precision is enough for many cases of analytical surfaces.
95   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points
96   //! is used. Numbers of points depend on types of surfaces and curves.
97   //! Error of the computation is not calculated.
98   //! @param theSurface - bounding surface of the region;
99   //! @param theLocation - surface location;
100   //! @param theOutMass[out] - mass (volume) of region;
101   //! @param theOutGravityCenter[out] - garvity center of region;
102   //! @param theOutInertia[out] - matrix of inertia;
103   Standard_EXPORT void Compute(
104     const BRepGProp_Face&  theSurface,
105     const gp_Pnt&          theLocation,
106     Standard_Real&         theOutMass,
107     gp_Pnt&                theOutGravityCenter,
108     gp_Mat&                theOutInertia);
109
110   //! Computes the global properties of a region of 3D space which can be
111   //! delimited by the surface and point or surface and plane. Surface can be closed.
112   //! The method is quick and its precision is enough for many cases of analytical surfaces.
113   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points is used.
114   //! Numbers of points depend on types of surfaces and curves.
115   //! Error of the computation is not calculated.
116   //! @param theSurface - bounding surface of the region;
117   //! @param theDomain - surface boundings;
118   //! @param theLocation - location of the point or the plane;
119   //! @param theCoeff - plane coefficients;
120   //! @param theIsByPoint - flag of restricition (point/plane);
121   //! @param theOutMass[out] - mass (volume) of region;
122   //! @param theOutGravityCenter[out] - garvity center of region;
123   //! @param theOutInertia[out] - matrix of inertia;
124   Standard_EXPORT void Compute(
125     BRepGProp_Face&        theSurface,
126     BRepGProp_Domain&      theDomain,
127     const gp_Pnt&          theLocation,
128     const Standard_Real    theCoeff[],
129     const Standard_Boolean theIsByPoint,
130     Standard_Real&         theOutMass,
131     gp_Pnt&                theOutGravityCenter,
132     gp_Mat&                theOutInertia);
133
134   //! Computes the global properties of a surface. Surface can be closed.
135   //! The method is quick and its precision is enough for many cases of analytical surfaces.
136   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points
137   //! is used. Numbers of points depend on types of surfaces and curves.
138   //! Error of the computation is not calculated.
139   //! @param theSurface - bounding surface of the region;
140   //! @param theDomain - surface boundings;
141   //! @param theLocation - surface location;
142   //! @param theOutMass[out] - mass (volume) of region;
143   //! @param theOutGravityCenter[out] - garvity center of region;
144   //! @param theOutInertia[out] - matrix of inertia;
145   Standard_EXPORT void Compute(
146     BRepGProp_Face&        theSurface,
147     BRepGProp_Domain&      theDomain,
148     const gp_Pnt&          theLocation,
149     Standard_Real&         theOutMass,
150     gp_Pnt&                theOutGravityCenter,
151     gp_Mat&                theOutInertia);
152
153   //! Computes the global properties of the region of 3D space which can be
154   //! delimited by the surface and point or surface and plane.
155   //! Adaptive 2D Gauss integration is used.
156   //! If Epsilon more than 0.001 then algorithm performs non-adaptive integration.
157   //! @param theSurface - bounding surface of the region;
158   //! @param theDomain - surface boundings;
159   //! @param theLocation - location of the point or the plane;
160   //! @param theEps - maximal relative error of computed mass (volume) for face;
161   //! @param theCoeff - plane coefficients;
162   //! @param theIsByPoint - flag of restricition (point/plane);
163   //! @param theOutMass[out] - mass (volume) of region;
164   //! @param theOutGravityCenter[out] - garvity center of region;
165   //! @param theOutInertia[out] - matrix of inertia;
166   //! @return value of error which is calculated as
167   //! Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values
168   //! for two successive steps of adaptive integration.
169   Standard_EXPORT Standard_Real Compute(
170     BRepGProp_Face&        theSurface,
171     BRepGProp_Domain&      theDomain,
172     const gp_Pnt&          theLocation,
173     const Standard_Real    theEps,
174     const Standard_Real    theCoeff[],
175     const Standard_Boolean theByPoint,
176     Standard_Real&         theOutMass,
177     gp_Pnt&                theOutGravityCenter,
178     gp_Mat&                theOutInertia);
179
180   //! Computes the global properties of the face. Adaptive 2D Gauss integration is used.
181   //! If Epsilon more than 0.001 then algorithm performs non-adaptive integration.
182   //! @param theSurface - bounding surface of the region;
183   //! @param theDomain - surface boundings;
184   //! @param theLocation - surface location;
185   //! @param theEps - maximal relative error of computed mass (square) for face;
186   //! @param theOutMass[out] - mass (volume) of region;
187   //! @param theOutGravityCenter[out] - garvity center of region;
188   //! @param theOutInertia[out] - matrix of inertia;
189   //! @return value of error which is calculated as
190   //! Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values
191   //! for two successive steps of adaptive integration.
192   Standard_EXPORT Standard_Real Compute(
193     BRepGProp_Face&        theSurface,
194     BRepGProp_Domain&      theDomain,
195     const gp_Pnt&          theLocation,
196     const Standard_Real    theEps,
197     Standard_Real&         theOutMass,
198     gp_Pnt&                theOutGravityCenter,
199     gp_Mat&                theOutInertia);
200
201 private: //! @name private methods
202
203   BRepGProp_Gauss(BRepGProp_Gauss const&);
204   BRepGProp_Gauss& operator= (BRepGProp_Gauss const&);
205
206   void computeVInertiaOfElementaryPart(
207     const gp_Pnt&             thePoint,
208     const gp_Vec&             theNormal,
209     const gp_Pnt&             theLocation,
210     const Standard_Real       theWeight,
211     const Standard_Real       theCoeff[],
212     const Standard_Boolean    theIsByPoint,
213     BRepGProp_Gauss::Inertia& theOutInertia);
214
215   void computeSInertiaOfElementaryPart(
216     const gp_Pnt&             thePoint,
217     const gp_Vec&             theNormal,
218     const gp_Pnt&             theLocation,
219     const Standard_Real       theWeight,
220     BRepGProp_Gauss::Inertia& theOutInertia);
221
222   void checkBounds(
223     const Standard_Real theU1,
224     const Standard_Real theU2,
225     const Standard_Real theV1,
226     const Standard_Real theV2);
227
228   void addAndRestoreInertia(
229     const BRepGProp_Gauss::Inertia& theInInertia,
230     BRepGProp_Gauss::Inertia&       theOutInertia);
231
232   void multAndRestoreInertia(
233     const Standard_Real       theValue,
234     BRepGProp_Gauss::Inertia& theInertia);
235
236   void convert(
237     const BRepGProp_Gauss::Inertia& theInertia,
238     gp_Pnt&                         theOutGravityCenter,
239     gp_Mat&                         theOutMatrixOfInertia,
240     Standard_Real&                  theOutMass);
241
242   void convert(
243     const BRepGProp_Gauss::Inertia& theInertia,
244     const Standard_Real             theCoeff[],
245     const Standard_Boolean          theIsByPoint,
246     gp_Pnt&                         theOutGravityCenter,
247     gp_Mat&                         theOutMatrixOfInertia,
248     Standard_Real&                  theOutMass);
249
250   static Standard_Integer MaxSubs(
251     const Standard_Integer theN,
252     const Standard_Integer theCoeff = 32);
253
254   static void Init(
255     Handle_Vector&         theOutVec,
256     const Standard_Real    theValue,
257     const Standard_Integer theFirst = 0,
258     const Standard_Integer theLast  = 0);
259
260   static void InitMass(
261     const Standard_Real    theValue,
262     const Standard_Integer theFirst,
263     const Standard_Integer theLast,
264     InertiaArray&          theArray);
265
266   static Standard_Integer FillIntervalBounds(
267     const Standard_Real         theA,
268     const Standard_Real         theB,
269     const TColStd_Array1OfReal& theKnots,
270     const Standard_Integer      theNumSubs,
271     InertiaArray&               theInerts,
272     Handle_Vector&              theParam1,
273     Handle_Vector&              theParam2,
274     Handle_Vector&              theError,
275     Handle_Vector&              theCommonError);
276
277 private: //! @name private fields
278
279   BRepGProp_GaussType myType; //!< Type of geometric object
280   BRepGProp_GaussFunc add;    //!< Pointer on the add function
281   BRepGProp_GaussFunc mult;   //!< Pointer on the mult function
282 };
283
284 #endif