0024774: Convertation of the generic classes to the non-generic. Part 8
[occt.git] / src / BRepGProp / BRepGProp_VinertGK.cxx
1 // Created on: 2005-12-09
2 // Created by: Sergey KHROMOV
3 // Copyright (c) 2005-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <BRepGProp_VinertGK.ixx>
17
18 #include <TColStd_HArray1OfReal.hxx>
19 #include <TColStd_Array1OfBoolean.hxx>
20 #include <math_KronrodSingleIntegration.hxx>
21
22 #include <BRepGProp_TFunction.hxx>
23
24 //==========================================================================
25 //function : Constructor
26 //==========================================================================
27
28 BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face        &theSurface,
29                                        const gp_Pnt          &theLocation,
30                                        const Standard_Real    theTolerance,
31                                        const Standard_Boolean theCGFlag,
32                                        const Standard_Boolean theIFlag):
33   myErrorReached(0.)
34 {
35   SetLocation(theLocation);
36   Perform(theSurface, theTolerance, theCGFlag, theIFlag);
37 }
38
39 //==========================================================================
40 //function : Constructor
41 //           
42 //==========================================================================
43
44 BRepGProp_VinertGK::BRepGProp_VinertGK(      BRepGProp_Face          &theSurface,
45                                        const gp_Pnt        &thePoint,
46                                        const gp_Pnt        &theLocation,
47                                        const Standard_Real  theTolerance,
48                                        const Standard_Boolean theCGFlag,
49                                        const Standard_Boolean theIFlag):
50   myErrorReached(0.)
51 {
52   SetLocation(theLocation);
53   Perform(theSurface, thePoint, theTolerance, theCGFlag, theIFlag);
54 }
55
56 //==========================================================================
57 //function : Constructor
58 //           
59 //==========================================================================
60
61 BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face        &theSurface,
62                                        BRepGProp_Domain      &theDomain,
63                                        const gp_Pnt          &theLocation,
64                                        const Standard_Real    theTolerance,
65                                        const Standard_Boolean theCGFlag,
66                                        const Standard_Boolean theIFlag):
67   myErrorReached(0.)
68 {
69   SetLocation(theLocation);
70   Perform(theSurface, theDomain, theTolerance, theCGFlag, theIFlag);
71 }
72
73 //==========================================================================
74 //function : Constructor
75 //           
76 //==========================================================================
77
78 BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face        &theSurface,
79                                        BRepGProp_Domain      &theDomain,
80                                        const gp_Pnt          &thePoint,
81                                        const gp_Pnt          &theLocation,
82                                        const Standard_Real    theTolerance,
83                                        const Standard_Boolean theCGFlag,
84                                        const Standard_Boolean theIFlag):
85   myErrorReached(0.)
86 {
87   SetLocation(theLocation);
88   Perform(theSurface, theDomain, thePoint, theTolerance, theCGFlag, theIFlag);
89 }
90
91 //==========================================================================
92 //function : Constructor
93 //           
94 //==========================================================================
95
96 BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face        &theSurface,
97                                        const gp_Pln          &thePlane,
98                                        const gp_Pnt          &theLocation,
99                                        const Standard_Real    theTolerance,
100                                        const Standard_Boolean theCGFlag,
101                                        const Standard_Boolean theIFlag):
102   myErrorReached(0.)
103 {
104   SetLocation(theLocation);
105   Perform(theSurface, thePlane, theTolerance, theCGFlag, theIFlag);
106 }
107
108 //==========================================================================
109 //function : Constructor
110 //           
111 //==========================================================================
112
113 BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face        &theSurface,
114                                        BRepGProp_Domain      &theDomain,
115                                        const gp_Pln          &thePlane,
116                                        const gp_Pnt          &theLocation,
117                                        const Standard_Real    theTolerance,
118                                        const Standard_Boolean theCGFlag,
119                                        const Standard_Boolean theIFlag):
120   myErrorReached(0.)
121 {
122   SetLocation(theLocation);
123   Perform(theSurface, theDomain, thePlane, theTolerance, theCGFlag, theIFlag);
124 }
125
126 //==========================================================================
127 //function : Perform
128 //           Compute the properties.
129 //==========================================================================
130
131 Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face        &theSurface,
132                                           const Standard_Real    theTolerance,
133                                           const Standard_Boolean theCGFlag,
134                                           const Standard_Boolean theIFlag)
135
136 {
137   Standard_Real aShift[] = { 0., 0., 0. };
138
139   return PrivatePerform(theSurface, NULL, Standard_True, &aShift, theTolerance, 
140     theCGFlag, theIFlag);
141 }
142
143 //==========================================================================
144 //function : Perform
145 //           Compute the properties.
146 //==========================================================================
147
148 Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face        &theSurface,
149                                           const gp_Pnt          &thePoint,
150                                           const Standard_Real    theTolerance,
151                                           const Standard_Boolean theCGFlag,
152                                           const Standard_Boolean theIFlag)
153
154 {
155   gp_XYZ        aXYZ(thePoint.XYZ().Subtracted(loc.XYZ()));
156   Standard_Real aShift[3];
157
158   aXYZ.Coord(aShift[0], aShift[1], aShift[2]);
159
160   return PrivatePerform(theSurface, NULL, Standard_True, &aShift, theTolerance, 
161     theCGFlag, theIFlag);
162 }
163
164 //==========================================================================
165 //function : Perform
166 //           Compute the properties.
167 //==========================================================================
168
169 Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face        &theSurface,
170                                           BRepGProp_Domain      &theDomain,
171                                           const Standard_Real    theTolerance,
172                                           const Standard_Boolean theCGFlag,
173                                           const Standard_Boolean theIFlag)
174
175 {
176   Standard_Real aShift[] = { 0., 0., 0. };
177
178   return PrivatePerform(theSurface, &theDomain,
179     Standard_True, &aShift, theTolerance, 
180     theCGFlag, theIFlag);
181 }
182
183 //==========================================================================
184 //function : Perform
185 //           Compute the properties.
186 //==========================================================================
187
188 Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face        &theSurface,
189                                           BRepGProp_Domain      &theDomain,
190                                           const gp_Pnt          &thePoint,
191                                           const Standard_Real    theTolerance,
192                                           const Standard_Boolean theCGFlag,
193                                           const Standard_Boolean theIFlag)
194
195 {
196   gp_XYZ        aXYZ(thePoint.XYZ().Subtracted(loc.XYZ()));
197   Standard_Real aShift[3];
198
199   aXYZ.Coord(aShift[0], aShift[1], aShift[2]);
200
201   return PrivatePerform(theSurface, &theDomain,
202     Standard_True, &aShift, theTolerance, 
203     theCGFlag, theIFlag);
204 }
205
206 //==========================================================================
207 //function : Perform
208 //           Compute the properties.
209 //==========================================================================
210
211 Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face        &theSurface,
212                                           const gp_Pln          &thePlane,
213                                           const Standard_Real    theTolerance,
214                                           const Standard_Boolean theCGFlag,
215                                           const Standard_Boolean theIFlag)
216
217 {
218   Standard_Real aCoeff[4];
219   Standard_Real aXLoc;
220   Standard_Real aYLoc;
221   Standard_Real aZLoc;
222
223   loc.Coord(aXLoc, aYLoc, aZLoc);
224   thePlane.Coefficients (aCoeff[0], aCoeff[1], aCoeff[2], aCoeff[3]);
225   aCoeff[3] = aCoeff[3] - aCoeff[0]*aXLoc - aCoeff[1]*aYLoc - aCoeff[2]*aZLoc;
226
227   return PrivatePerform(theSurface, NULL,
228     Standard_False, &aCoeff, theTolerance, 
229     theCGFlag, theIFlag);
230 }
231
232 //==========================================================================
233 //function : Perform
234 //           Compute the properties.
235 //==========================================================================
236
237 Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face        &theSurface,
238                                           BRepGProp_Domain      &theDomain,
239                                           const gp_Pln          &thePlane,
240                                           const Standard_Real    theTolerance,
241                                           const Standard_Boolean theCGFlag,
242                                           const Standard_Boolean theIFlag)
243
244 {
245   Standard_Real aCoeff[4];
246   Standard_Real aXLoc;
247   Standard_Real aYLoc;
248   Standard_Real aZLoc;
249
250   loc.Coord(aXLoc, aYLoc, aZLoc);
251   thePlane.Coefficients (aCoeff[0], aCoeff[1], aCoeff[2], aCoeff[3]);
252   aCoeff[3] = aCoeff[3] - aCoeff[0]*aXLoc - aCoeff[1]*aYLoc - aCoeff[2]*aZLoc;
253
254   return PrivatePerform(theSurface, &theDomain,
255     Standard_False, &aCoeff, theTolerance, 
256     theCGFlag, theIFlag);
257 }
258
259 //==========================================================================
260 //function : PrivatePerform
261 //           Compute the properties.
262 //==========================================================================
263
264 Standard_Real BRepGProp_VinertGK::PrivatePerform
265 (BRepGProp_Face        &theSurface,
266  const Standard_Address thePtrDomain,
267  const Standard_Boolean IsByPoint,
268  const Standard_Address theCoeffs,
269  const Standard_Real    theTolerance,
270  const Standard_Boolean theCGFlag,
271  const Standard_Boolean theIFlag)
272
273 {
274
275   const Standard_Real aTTol = 1.e-9;
276   Standard_Real *aCoeffs = (Standard_Real *)theCoeffs;
277
278   // Compute the number of 2d bounding curves of the face.
279   BRepGProp_Domain           *aPDomain = NULL;
280   Standard_Integer  aNbCurves = 0;
281
282   // If the pointer to the domain is NULL, there is only one curve to treat:
283   // U isoline with the UMax parameter.
284   if (thePtrDomain == NULL)
285     aNbCurves = 1;
286   else {
287     aPDomain = (BRepGProp_Domain *)thePtrDomain;
288
289     for (aPDomain->Init(); aPDomain->More(); aPDomain->Next())
290       aNbCurves++;
291   }
292
293   if (aNbCurves == 0) {
294     myErrorReached = -1.;
295
296     return myErrorReached;
297   }
298
299   //Standard_Real    aCrvTol = 0.5*theTolerance/aNbCurves;
300   Standard_Real    aCrvTol = 0.1*theTolerance;
301   Standard_Real    aUMin;
302   Standard_Real    aUMax;
303   Standard_Real    aTMin;
304   Standard_Real    aTMax;
305   Standard_Integer aNbPnts;
306   Standard_Integer aNbMaxIter = 1000;
307   Standard_Integer aNbVal = 10;
308   Standard_Integer k;
309   math_Vector      aLocalValue(1, aNbVal);
310   math_Vector      aLocalTolReached(1, aNbVal);
311   math_Vector      aValue(1, aNbVal);
312   math_Vector      aTolReached(1, aNbVal);
313   TColStd_Array1OfBoolean CFlags(1, aNbVal); 
314   CFlags.Init(Standard_False);
315   Standard_Boolean isMore;
316
317   //aNbVal = 1;
318   aValue.Init(0.);
319   aTolReached.Init(0.);
320
321   CFlags.Init(Standard_False);
322   CFlags(1) = Standard_True;
323
324   if(theCGFlag || theIFlag) {
325     Standard_Integer i;
326     for(i = 2; i <= 4; ++i) {CFlags(i) = Standard_True;}
327   }
328
329   if(theIFlag) {
330     Standard_Integer i;
331     for(i = 5; i <= 10; ++i) {CFlags(i) = Standard_True;}
332   }
333
334   theSurface.Bounds(aUMin, aUMax, aTMin, aTMax);
335
336   if (thePtrDomain == NULL)
337     isMore = Standard_True;
338   else {
339     aPDomain->Init();
340     isMore = aPDomain->More();
341   }
342
343   while(isMore) {
344     // If the pointer to the domain is NULL, there is only one curve to treat:
345     // U isoline with the UMax parameter.
346
347     if (thePtrDomain == NULL)
348       theSurface.Load(Standard_False, GeomAbs_IsoU);
349     else
350       theSurface.Load(aPDomain->Value());
351
352     aTMin = theSurface.FirstParameter();
353     aTMax = theSurface.LastParameter();
354
355
356     // Get the spans on the curve.
357     Handle(TColStd_HArray1OfReal) aTKnots;
358     BRepGProp_TFunction               aTFunc(theSurface, loc, IsByPoint, theCoeffs,
359       aUMin, aCrvTol);
360
361     theSurface.GetTKnots(aTMin, aTMax, aTKnots);
362
363     Standard_Integer              iU             = aTKnots->Upper();
364     Standard_Integer              aNbTIntervals  = aTKnots->Length() - 1;
365     //Standard_Real                 aTolSpan       = aCrvTol/aNbTIntervals;
366     Standard_Real                 aTolSpan       = 0.9*theTolerance; //Relative error
367     math_KronrodSingleIntegration anIntegral;
368     GProp_ValueType               aValueType;
369
370
371     // Empirical criterion.
372     aNbPnts = Min(15, theSurface.IntegrationOrder()/aNbTIntervals + 1);
373     aNbPnts = Max(5, aNbPnts);
374     //     aNbPnts = theSurface.IntegrationOrder();
375
376     aLocalValue.Init(0.);
377     aLocalTolReached.Init(0.);
378
379     for (k = 1; k <= aNbVal; k++) {
380
381       if(!CFlags(k)) continue;
382
383       Standard_Integer i = aTKnots->Lower();
384
385       switch (k) {
386       case 1:   aValueType = GProp_Mass;        break;
387       case 2:   aValueType = GProp_CenterMassX; break;
388       case 3:   aValueType = GProp_CenterMassY; break;
389       case 4:   aValueType = GProp_CenterMassZ; break;
390       case 5:   aValueType = GProp_InertiaXX;   break;
391       case 6:   aValueType = GProp_InertiaYY;   break;
392       case 7:   aValueType = GProp_InertiaZZ;   break;
393       case 8:   aValueType = GProp_InertiaXY;   break;
394       case 9:   aValueType = GProp_InertiaXZ;   break;
395       case 10:  aValueType = GProp_InertiaYZ;   break;
396
397       default: myErrorReached = -1.; return myErrorReached;
398       }
399       aTFunc.SetValueType(aValueType);
400
401       Standard_Real err1 = 0.;
402       while (i < iU) {
403
404         //cout << "-------------- Span " << i << " nbp: " << aNbPnts << endl;
405         Standard_Real aT1 = aTKnots->Value(i++);
406         Standard_Real aT2 = aTKnots->Value(i);
407
408         if(aT2 - aT1 < aTTol) continue;
409
410         aTFunc.SetNbKronrodPoints(aNbPnts);
411         aTFunc.Init();
412         aTFunc.SetTolerance(aCrvTol/(aT2-aT1));
413         anIntegral.Perform(aTFunc, aT1, aT2, aNbPnts, aTolSpan, aNbMaxIter);
414
415         if (!anIntegral.IsDone()) {
416           myErrorReached = -1.;
417
418           return myErrorReached;
419         }
420
421         aLocalValue(k)      += anIntegral.Value();
422         err1 = aTFunc.AbsolutError()*(aT2 - aT1); 
423         //cout << "Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << endl;
424         aLocalTolReached(k) += anIntegral.AbsolutError() + err1; 
425         //cout << "--- Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << endl;
426       }
427
428       aValue(k)      += aLocalValue(k);
429       aTolReached(k) += aLocalTolReached(k);
430     }
431
432     // If the pointer to the domain is NULL, there is only one curve to treat:
433     // U isoline with the UMax parameter.
434     if (thePtrDomain == NULL)
435       isMore = Standard_False;
436     else {
437       aPDomain->Next();
438       isMore = aPDomain->More();
439     }
440   }
441
442   // Get volume value.
443   dim            = aValue(1);
444   myErrorReached = aTolReached(1);
445   myAbsolutError = myErrorReached;
446   Standard_Real anAbsDim = Abs(dim);
447   Standard_Real aVolTol  = Epsilon(myAbsolutError);
448   if(anAbsDim >= aVolTol) myErrorReached /= anAbsDim;
449
450   if(theCGFlag || theIFlag) {
451     // Compute values of center of mass.
452     if(anAbsDim >= aVolTol) {
453       if (IsByPoint) {
454         aValue(2) = aCoeffs[0] + aValue(2)/dim;
455         aValue(3) = aCoeffs[1] + aValue(3)/dim;
456         aValue(4) = aCoeffs[2] + aValue(4)/dim;
457       } else {
458         aValue(2) /= dim;
459         aValue(3) /= dim;
460         aValue(4) /= dim;
461       }
462     } else {
463       aValue(2) = 0.;
464       aValue(3) = 0.;
465       aValue(4) = 0.;
466       dim = 0.;
467     }
468     g.SetCoord(aValue(2), aValue(3), aValue(4));
469   }
470
471   if(theIFlag) {
472     // Fill the matrix of inertia.
473     inertia.SetCols (gp_XYZ (aValue(5), aValue(8),  aValue(9)),
474       gp_XYZ (aValue(8), aValue(6),  aValue(10)),
475       gp_XYZ (aValue(9), aValue(10), aValue(7)));
476   }
477   //return myErrorReached;
478   return myAbsolutError;
479 }
480