0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepGProp / BRepGProp_TFunction.cxx
CommitLineData
b311480e 1// Created on: 2005-12-09
2// Created by: Sergey KHROMOV
973c2be1 3// Copyright (c) 2005-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
424cd6bb 16
42cf5bc1 17#include <BRepGProp_Face.hxx>
18#include <BRepGProp_TFunction.hxx>
19#include <gp_Pnt.hxx>
7fd59977 20#include <math_KronrodSingleIntegration.hxx>
21#include <Precision.hxx>
42cf5bc1 22#include <TColStd_HArray1OfReal.hxx>
7fd59977 23
24//=======================================================================
25//function : Constructor.
26//purpose :
27//=======================================================================
424cd6bb 28BRepGProp_TFunction::BRepGProp_TFunction(const BRepGProp_Face &theSurface,
29 const gp_Pnt &theVertex,
30 const Standard_Boolean IsByPoint,
31 const Standard_Address theCoeffs,
32 const Standard_Real theUMin,
33 const Standard_Real theTolerance):
34 mySurface(theSurface),
35 myUFunction(mySurface, theVertex, IsByPoint, theCoeffs),
36 myUMin(theUMin),
37 myTolerance(theTolerance),
38 myTolReached(0.),
39 myErrReached(0.),
40 myAbsError(0.),
41 myValueType(GProp_Unknown),
42 myIsByPoint(IsByPoint),
43 myNbPntOuter(3)
7fd59977 44{
45}
46
47//=======================================================================
48//function : Init
49//purpose :
50//=======================================================================
51
424cd6bb 52void BRepGProp_TFunction::Init()
7fd59977 53{
54 myTolReached = 0.;
55 myErrReached = 0.;
56 myAbsError = 0.;
57}
58
59//=======================================================================
60//function : Value
61//purpose :
62//=======================================================================
63
424cd6bb 64Standard_Boolean BRepGProp_TFunction::Value(const Standard_Real X,
65 Standard_Real &F)
7fd59977 66{
7fd59977 67 const Standard_Real tolU = 1.e-9;
68
69 gp_Pnt2d aP2d;
70 gp_Vec2d aV2d;
71 Standard_Real aUMax;
72 Handle(TColStd_HArray1OfReal) anUKnots;
73
74 mySurface.D12d(X, aP2d, aV2d);
75 aUMax = aP2d.X();
76
424cd6bb 77 if(aUMax - myUMin < tolU)
78 {
7fd59977 79 F = 0.;
80 return Standard_True;
424cd6bb 81 }
7fd59977 82
83 mySurface.GetUKnots(myUMin, aUMax, anUKnots);
84 myUFunction.SetVParam(aP2d.Y());
85
86 // Compute the integral from myUMin to aUMax of myUFunction.
87 Standard_Integer i;
88 Standard_Real aCoeff = aV2d.Y();
6e6cd5d9 89 //Standard_Integer aNbUIntervals = anUKnots->Length() - 1;
7fd59977 90 //Standard_Real aTol = myTolerance/aNbUIntervals;
91 Standard_Real aTol = myTolerance;
92
93 //aTol /= myNbPntOuter;
94
95 if (myValueType == GProp_Mass) {
96 if (myIsByPoint)
97 aCoeff /= 3.;
98 } else if (myValueType == GProp_CenterMassX ||
424cd6bb 99 myValueType == GProp_CenterMassY ||
100 myValueType == GProp_CenterMassZ) {
101 if (myIsByPoint)
102 aCoeff *= 0.25;
7fd59977 103 } else if (myValueType == GProp_InertiaXX ||
424cd6bb 104 myValueType == GProp_InertiaYY ||
105 myValueType == GProp_InertiaZZ ||
106 myValueType == GProp_InertiaXY ||
107 myValueType == GProp_InertiaXZ ||
108 myValueType == GProp_InertiaYZ) {
109 if (myIsByPoint)
110 aCoeff *= 0.2;
7fd59977 111 } else
112 return Standard_False;
113
114 Standard_Real aAbsCoeff = Abs(aCoeff);
115
116 if (aAbsCoeff <= Precision::Angular()) {
117 // No need to compute the integral. The value will be equal to 0.
118 F = 0.;
119 return Standard_True;
120 }
121 //else if (aAbsCoeff > 10.*aTol)
122 // aTol /= aAbsCoeff;
123 //else
124 // aTol = 0.1;
125
126 Standard_Integer iU = anUKnots->Upper();
127 Standard_Integer aNbPntsStart;
128 Standard_Integer aNbMaxIter = 1000;
129 math_KronrodSingleIntegration anIntegral;
130 Standard_Real aLocalErr = 0.;
131
132 i = anUKnots->Lower();
133 F = 0.;
424cd6bb 134
7fd59977 135 // Epmirical criterion
136 aNbPntsStart = Min(15, mySurface.UIntegrationOrder()/(anUKnots->Length() - 1)+1);
137 aNbPntsStart = Max(5, aNbPntsStart);
138
424cd6bb 139 while (i < iU) {
7fd59977 140 Standard_Real aU1 = anUKnots->Value(i++);
141 Standard_Real aU2 = anUKnots->Value(i);
142
143 if(aU2 - aU1 < tolU) continue;
144
145 anIntegral.Perform(myUFunction, aU1, aU2, aNbPntsStart, aTol, aNbMaxIter);
146
147 if (!anIntegral.IsDone())
148 return Standard_False;
149
150 F += anIntegral.Value();
151 aLocalErr += anIntegral.AbsolutError();
152 //cout << " TFunction : " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << endl;
153 }
154
155 F *= aCoeff;
156 aLocalErr *= aAbsCoeff;
157 myAbsError = Max(myAbsError, aLocalErr);
158
159 myTolReached += aLocalErr;
160
161 if(Abs(F) > Epsilon(1.)) aLocalErr /= Abs(F);
162
163 myErrReached = Max(myErrReached, aLocalErr);
164
165
166 return Standard_True;
167}
168
169//=======================================================================
170//function : GetStateNumber
171//purpose :
172//=======================================================================
173
424cd6bb 174Standard_Integer BRepGProp_TFunction::GetStateNumber()
7fd59977 175{
176 //myErrReached = myTolReached;
177 //myTolReached = 0.;
178 //myNbPntOuter += RealToInt(0.5*myNbPntOuter);
179
180 //if (myNbPntOuter%2 == 0)
424cd6bb 181 //myNbPntOuter++;
7fd59977 182
183 return 0;
184}