8607820b897f5a50ac96e475c3a94047f177c7f2
[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 Standard_Real(*BRepGProp_GaussFunc)(const Standard_Real, const Standard_Real);
56
57 public: //! @name public API
58
59   //! Describes types of geometric objects.
60   //! - Vinert is 3D closed region of space delimited with:
61   //! -- Surface;
62   //! -- Point and Surface;
63   //! -- Plane and Surface.
64   //! - Sinert is face in 3D space.
65   typedef enum { Vinert = 0, Sinert } BRepGProp_GaussType;
66
67   //! Constructor
68   Standard_EXPORT explicit BRepGProp_Gauss(const BRepGProp_GaussType theType);
69
70   //! Computes the global properties of a solid region of 3D space which can be
71   //! delimited by the surface and point or surface and plane. Surface can be closed.
72   //! The method is quick and its precision is enough for many cases of analytical surfaces.
73   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points
74   //! is used. Numbers of points depend on types of surfaces and curves.
75   //! Error of the computation is not calculated.
76   //! @param theSurface - bounding surface of the region;
77   //! @param theLocation - location of the point or the plane;
78   //! @param theCoeff - plane coefficients;
79   //! @param theIsByPoint - flag of restricition (point/plane);
80   //! @param theOutMass[out] - mass (volume) of region;
81   //! @param theOutGravityCenter[out] - garvity center of region;
82   //! @param theOutInertia[out] - matrix of inertia;
83   Standard_EXPORT void Compute(
84     const BRepGProp_Face&  theSurface,
85     const gp_Pnt&          theLocation,
86     const Standard_Real    theCoeff[],
87     const Standard_Boolean theIsByPoint,
88     Standard_Real&         theOutMass,
89     gp_Pnt&                theOutGravityCenter,
90     gp_Mat&                theOutInertia);
91
92   //! Computes the global properties of a surface. Surface can be closed.
93   //! The method is quick and its precision is enough for many cases of analytical surfaces.
94   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points
95   //! is used. Numbers of points depend on types of surfaces and curves.
96   //! Error of the computation is not calculated.
97   //! @param theSurface - bounding surface of the region;
98   //! @param theLocation - surface location;
99   //! @param theOutMass[out] - mass (volume) of region;
100   //! @param theOutGravityCenter[out] - garvity center of region;
101   //! @param theOutInertia[out] - matrix of inertia;
102   Standard_EXPORT void Compute(
103     const BRepGProp_Face&  theSurface,
104     const gp_Pnt&          theLocation,
105     Standard_Real&         theOutMass,
106     gp_Pnt&                theOutGravityCenter,
107     gp_Mat&                theOutInertia);
108
109   //! Computes the global properties of a region of 3D space which can be
110   //! delimited by the surface and point or surface and plane. Surface can be closed.
111   //! The method is quick and its precision is enough for many cases of analytical surfaces.
112   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points is used.
113   //! Numbers of points depend on types of surfaces and curves.
114   //! Error of the computation is not calculated.
115   //! @param theSurface - bounding surface of the region;
116   //! @param theDomain - surface boundings;
117   //! @param theLocation - location of the point or the plane;
118   //! @param theCoeff - plane coefficients;
119   //! @param theIsByPoint - flag of restricition (point/plane);
120   //! @param theOutMass[out] - mass (volume) of region;
121   //! @param theOutGravityCenter[out] - garvity center of region;
122   //! @param theOutInertia[out] - matrix of inertia;
123   Standard_EXPORT void Compute(
124     BRepGProp_Face&        theSurface,
125     BRepGProp_Domain&      theDomain,
126     const gp_Pnt&          theLocation,
127     const Standard_Real    theCoeff[],
128     const Standard_Boolean theIsByPoint,
129     Standard_Real&         theOutMass,
130     gp_Pnt&                theOutGravityCenter,
131     gp_Mat&                theOutInertia);
132
133   //! Computes the global properties of a surface. Surface can be closed.
134   //! The method is quick and its precision is enough for many cases of analytical surfaces.
135   //! Non-adaptive 2D Gauss integration with predefined numbers of Gauss points
136   //! is used. Numbers of points depend on types of surfaces and curves.
137   //! Error of the computation is not calculated.
138   //! @param theSurface - bounding surface of the region;
139   //! @param theDomain - surface boundings;
140   //! @param theLocation - surface location;
141   //! @param theOutMass[out] - mass (volume) of region;
142   //! @param theOutGravityCenter[out] - garvity center of region;
143   //! @param theOutInertia[out] - matrix of inertia;
144   Standard_EXPORT void Compute(
145     BRepGProp_Face&        theSurface,
146     BRepGProp_Domain&      theDomain,
147     const gp_Pnt&          theLocation,
148     Standard_Real&         theOutMass,
149     gp_Pnt&                theOutGravityCenter,
150     gp_Mat&                theOutInertia);
151
152   //! Computes the global properties of the region of 3D space which can be
153   //! delimited by the surface and point or surface and plane.
154   //! Adaptive 2D Gauss integration is used.
155   //! If Epsilon more than 0.001 then algorithm performs non-adaptive integration.
156   //! @param theSurface - bounding surface of the region;
157   //! @param theDomain - surface boundings;
158   //! @param theLocation - location of the point or the plane;
159   //! @param theEps - maximal relative error of computed mass (volume) for face;
160   //! @param theCoeff - plane coefficients;
161   //! @param theIsByPoint - flag of restricition (point/plane);
162   //! @param theOutMass[out] - mass (volume) of region;
163   //! @param theOutGravityCenter[out] - garvity center of region;
164   //! @param theOutInertia[out] - matrix of inertia;
165   //! @return value of error which is calculated as
166   //! Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values
167   //! for two successive steps of adaptive integration.
168   Standard_EXPORT Standard_Real Compute(
169     BRepGProp_Face&        theSurface,
170     BRepGProp_Domain&      theDomain,
171     const gp_Pnt&          theLocation,
172     const Standard_Real    theEps,
173     const Standard_Real    theCoeff[],
174     const Standard_Boolean theByPoint,
175     Standard_Real&         theOutMass,
176     gp_Pnt&                theOutGravityCenter,
177     gp_Mat&                theOutInertia);
178
179   //! Computes the global properties of the face. Adaptive 2D Gauss integration is used.
180   //! If Epsilon more than 0.001 then algorithm performs non-adaptive integration.
181   //! @param theSurface - bounding surface of the region;
182   //! @param theDomain - surface boundings;
183   //! @param theLocation - surface location;
184   //! @param theEps - maximal relative error of computed mass (square) for face;
185   //! @param theOutMass[out] - mass (volume) of region;
186   //! @param theOutGravityCenter[out] - garvity center of region;
187   //! @param theOutInertia[out] - matrix of inertia;
188   //! @return value of error which is calculated as
189   //! Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values
190   //! for two successive steps of adaptive integration.
191   Standard_EXPORT Standard_Real Compute(
192     BRepGProp_Face&        theSurface,
193     BRepGProp_Domain&      theDomain,
194     const gp_Pnt&          theLocation,
195     const Standard_Real    theEps,
196     Standard_Real&         theOutMass,
197     gp_Pnt&                theOutGravityCenter,
198     gp_Mat&                theOutInertia);
199
200 private: //! @name private methods
201
202   BRepGProp_Gauss(BRepGProp_Gauss const&);
203   BRepGProp_Gauss& operator= (BRepGProp_Gauss const&);
204
205   void computeVInertiaOfElementaryPart(
206     const gp_Pnt&             thePoint,
207     const gp_Vec&             theNormal,
208     const gp_Pnt&             theLocation,
209     const Standard_Real       theWeight,
210     const Standard_Real       theCoeff[],
211     const Standard_Boolean    theIsByPoint,
212     BRepGProp_Gauss::Inertia& theOutInertia);
213
214   void computeSInertiaOfElementaryPart(
215     const gp_Pnt&             thePoint,
216     const gp_Vec&             theNormal,
217     const gp_Pnt&             theLocation,
218     const Standard_Real       theWeight,
219     BRepGProp_Gauss::Inertia& theOutInertia);
220
221   void checkBounds(
222     const Standard_Real theU1,
223     const Standard_Real theU2,
224     const Standard_Real theV1,
225     const Standard_Real theV2);
226
227   void addAndRestoreInertia(
228     const BRepGProp_Gauss::Inertia& theInInertia,
229     BRepGProp_Gauss::Inertia&       theOutInertia);
230
231   void multAndRestoreInertia(
232     const Standard_Real       theValue,
233     BRepGProp_Gauss::Inertia& theInertia);
234
235   void convert(
236     const BRepGProp_Gauss::Inertia& theInertia,
237     gp_Pnt&                         theOutGravityCenter,
238     gp_Mat&                         theOutMatrixOfInertia,
239     Standard_Real&                  theOutMass);
240
241   void convert(
242     const BRepGProp_Gauss::Inertia& theInertia,
243     const Standard_Real             theCoeff[],
244     const Standard_Boolean          theIsByPoint,
245     gp_Pnt&                         theOutGravityCenter,
246     gp_Mat&                         theOutMatrixOfInertia,
247     Standard_Real&                  theOutMass);
248
249   static Standard_Integer MaxSubs(
250     const Standard_Integer theN,
251     const Standard_Integer theCoeff = 32);
252
253   static void Init(
254     Handle(Vector)&         theOutVec,
255     const Standard_Real    theValue,
256     const Standard_Integer theFirst = 0,
257     const Standard_Integer theLast  = 0);
258
259   static void InitMass(
260     const Standard_Real    theValue,
261     const Standard_Integer theFirst,
262     const Standard_Integer theLast,
263     InertiaArray&          theArray);
264
265   static Standard_Integer FillIntervalBounds(
266     const Standard_Real         theA,
267     const Standard_Real         theB,
268     const TColStd_Array1OfReal& theKnots,
269     const Standard_Integer      theNumSubs,
270     InertiaArray&               theInerts,
271     Handle(Vector)&              theParam1,
272     Handle(Vector)&              theParam2,
273     Handle(Vector)&              theError,
274     Handle(Vector)&              theCommonError);
275
276 private: //! @name private fields
277
278   BRepGProp_GaussType myType; //!< Type of geometric object
279   BRepGProp_GaussFunc add;    //!< Pointer on the add function
280   BRepGProp_GaussFunc mult;   //!< Pointer on the mult function
281 };
282
283 #endif