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 | |
42cf5bc1 |
16 | |
17 | #include <BRepGProp_Face.hxx> |
18 | #include <BRepGProp_UFunction.hxx> |
19 | #include <gp_Pnt.hxx> |
20 | #include <gp_XYZ.hxx> |
424cd6bb |
21 | |
7fd59977 |
22 | //======================================================================= |
23 | //function : Constructor. |
24 | //purpose : |
25 | //======================================================================= |
424cd6bb |
26 | BRepGProp_UFunction::BRepGProp_UFunction(const BRepGProp_Face &theSurface, |
27 | const gp_Pnt &theVertex, |
28 | const Standard_Boolean IsByPoint, |
29 | const Standard_Address theCoeffs) |
30 | : mySurface(theSurface), |
31 | myVertex(theVertex), |
32 | myCoeffs(theCoeffs), |
33 | myVParam(0.), |
34 | myValueType(GProp_Unknown), |
35 | myIsByPoint(IsByPoint) |
7fd59977 |
36 | { |
37 | } |
38 | |
39 | //======================================================================= |
40 | //function : Value |
41 | //purpose : Returns a value of the function. |
42 | //======================================================================= |
43 | |
424cd6bb |
44 | Standard_Boolean BRepGProp_UFunction::Value(const Standard_Real X, |
45 | Standard_Real &F) |
7fd59977 |
46 | { |
47 | // Volume computation |
48 | if (myValueType == GProp_Mass) { |
49 | gp_XYZ aPMP0; |
50 | Standard_Real aTmpPar1; |
51 | Standard_Real aTmpPar2; |
52 | |
53 | F = VolumeValue(X, aPMP0, aTmpPar1, aTmpPar2); |
54 | |
55 | return Standard_True; |
56 | } |
57 | |
58 | // Center of mass computation |
59 | if (myValueType == GProp_CenterMassX || |
424cd6bb |
60 | myValueType == GProp_CenterMassY || |
61 | myValueType == GProp_CenterMassZ) |
7fd59977 |
62 | return CenterMassValue(X, F); |
63 | |
64 | // Inertia computation |
65 | if (myValueType == GProp_InertiaXX || |
424cd6bb |
66 | myValueType == GProp_InertiaYY || |
67 | myValueType == GProp_InertiaZZ || |
68 | myValueType == GProp_InertiaXY || |
69 | myValueType == GProp_InertiaXZ || |
70 | myValueType == GProp_InertiaYZ) |
7fd59977 |
71 | return InertiaValue(X, F); |
72 | |
73 | return Standard_False; |
74 | } |
75 | |
76 | //======================================================================= |
77 | //function : VolumeValue |
78 | //purpose : Returns the value for volume computation. |
79 | //======================================================================= |
80 | |
424cd6bb |
81 | Standard_Real BRepGProp_UFunction::VolumeValue(const Standard_Real X, |
82 | gp_XYZ &thePMP0, |
83 | Standard_Real &theS, |
84 | Standard_Real &theD1) |
7fd59977 |
85 | { |
86 | gp_Pnt aPnt; |
87 | gp_Vec aNorm; |
88 | |
89 | mySurface.Normal(X, myVParam, aPnt, aNorm); |
90 | |
91 | thePMP0 = aPnt.XYZ().Subtracted(myVertex.XYZ()); |
92 | |
93 | // Volume computation for ByPoint mode. |
94 | if (myIsByPoint) |
95 | return thePMP0.Dot(aNorm.XYZ()); |
96 | |
97 | // Volume and additional coefficients computation for ByPlane mode. |
98 | Standard_Real *aCoeff = (Standard_Real *)myCoeffs; |
99 | |
100 | theS = aNorm.X()*aCoeff[0] + aNorm.Y()*aCoeff[1] + aNorm.Z()*aCoeff[2]; |
101 | theD1 = thePMP0.X()*aCoeff[0] + thePMP0.Y()*aCoeff[1] |
424cd6bb |
102 | + thePMP0.Z()*aCoeff[2] - aCoeff[3]; |
7fd59977 |
103 | |
104 | return theS*theD1; |
105 | } |
106 | |
107 | //======================================================================= |
108 | //function : CenterMassValue |
109 | //purpose : Returns a value for the center of mass computation. |
110 | //======================================================================= |
111 | |
424cd6bb |
112 | Standard_Boolean BRepGProp_UFunction::CenterMassValue(const Standard_Real X, |
113 | Standard_Real &F) |
7fd59977 |
114 | { |
115 | gp_XYZ aPmP0; |
116 | Standard_Real aS; |
117 | Standard_Real aD1; |
118 | |
119 | F = VolumeValue(X, aPmP0, aS, aD1); |
120 | |
121 | // Center of mass computation for ByPoint mode. |
122 | if (myIsByPoint) { |
123 | switch (myValueType) { |
124 | case GProp_CenterMassX: F *= aPmP0.X(); break; |
125 | case GProp_CenterMassY: F *= aPmP0.Y(); break; |
126 | case GProp_CenterMassZ: F *= aPmP0.Z(); break; |
127 | default: |
128 | return Standard_False; |
129 | } |
130 | |
131 | return Standard_True; |
132 | } |
133 | |
134 | // Center of mass computation for ByPlane mode. |
135 | Standard_Real *aCoeff = (Standard_Real *)myCoeffs; |
136 | |
137 | switch (myValueType) { |
138 | case GProp_CenterMassX: F *= (aPmP0.X() - 0.5*aCoeff[0]*aD1); break; |
139 | case GProp_CenterMassY: F *= (aPmP0.Y() - 0.5*aCoeff[1]*aD1); break; |
140 | case GProp_CenterMassZ: F *= (aPmP0.Z() - 0.5*aCoeff[2]*aD1); break; |
141 | default: |
142 | return Standard_False; |
143 | } |
144 | |
145 | return Standard_True; |
146 | } |
147 | |
148 | //======================================================================= |
149 | //function : InertiaValue |
150 | //purpose : Compute the value of intertia. |
151 | //======================================================================= |
152 | |
424cd6bb |
153 | Standard_Boolean BRepGProp_UFunction::InertiaValue(const Standard_Real X, |
154 | Standard_Real &F) |
7fd59977 |
155 | { |
156 | gp_XYZ aPmP0; |
157 | Standard_Real aS; |
158 | Standard_Real aD1; |
159 | Standard_Real aParam1; |
160 | Standard_Real aParam2; |
161 | Standard_Real *aCoeffs = (Standard_Real *)myCoeffs; |
162 | |
163 | F = VolumeValue(X, aPmP0, aS, aD1); |
164 | |
165 | // Inertia computation for ByPoint mode. |
166 | if (myIsByPoint) { |
167 | switch(myValueType) { |
168 | case GProp_InertiaXX: |
169 | case GProp_InertiaYZ: |
170 | aParam1 = aPmP0.Y() - aCoeffs[1]; |
171 | aParam2 = aPmP0.Z() - aCoeffs[2]; |
172 | break; |
173 | case GProp_InertiaYY: |
174 | case GProp_InertiaXZ: |
175 | aParam1 = aPmP0.X() - aCoeffs[0]; |
176 | aParam2 = aPmP0.Z() - aCoeffs[2]; |
177 | break; |
178 | case GProp_InertiaZZ: |
179 | case GProp_InertiaXY: |
180 | aParam1 = aPmP0.X() - aCoeffs[0]; |
181 | aParam2 = aPmP0.Y() - aCoeffs[1]; |
182 | break; |
183 | default: |
184 | return Standard_False; |
185 | } |
186 | |
187 | if (myValueType == GProp_InertiaXX || |
424cd6bb |
188 | myValueType == GProp_InertiaYY || |
189 | myValueType == GProp_InertiaZZ) |
7fd59977 |
190 | F *= aParam1*aParam1 + aParam2*aParam2; |
191 | else |
192 | F *= -aParam1*aParam2; |
193 | |
194 | return Standard_True; |
195 | } |
196 | |
197 | // Inertia computation for ByPlane mode. |
198 | Standard_Real aD2 = aD1*aD1; |
199 | Standard_Real aD3 = aD1*aD2/3.; |
200 | Standard_Real aPPar1; |
201 | Standard_Real aPPar2; |
202 | Standard_Real aCoeff1; |
203 | Standard_Real aCoeff2; |
204 | |
205 | // Inertia computation for XX, YY and ZZ. |
206 | if (myValueType == GProp_InertiaXX || |
424cd6bb |
207 | myValueType == GProp_InertiaYY || |
208 | myValueType == GProp_InertiaZZ) { |
209 | |
210 | if (myValueType == GProp_InertiaXX) { |
211 | aPPar1 = aPmP0.Y(); |
212 | aPPar2 = aPmP0.Z(); |
213 | aCoeff1 = aCoeffs[1]; |
214 | aCoeff2 = aCoeffs[2]; |
215 | } else if (myValueType == GProp_InertiaYY) { |
216 | aPPar1 = aPmP0.X(); |
217 | aPPar2 = aPmP0.Z(); |
218 | aCoeff1 = aCoeffs[0]; |
219 | aCoeff2 = aCoeffs[2]; |
220 | } else { // myValueType == GProp_InertiaZZ |
221 | aPPar1 = aPmP0.X(); |
222 | aPPar2 = aPmP0.Y(); |
223 | aCoeff1 = aCoeffs[0]; |
224 | aCoeff2 = aCoeffs[1]; |
225 | } |
226 | |
227 | aPPar1 -= aCoeff1*aD1; |
228 | aPPar2 -= aCoeff2*aD1; |
229 | aParam1 = aPPar1*aPPar1*aD1 + aPPar1*aCoeff1*aD2 + aCoeff1*aCoeff1*aD3; |
230 | aParam2 = aPPar2*aPPar2*aD1 + aPPar2*aCoeff2*aD2 + aCoeff2*aCoeff2*aD3; |
231 | |
232 | F = (aParam1 + aParam2)*aS; |
233 | |
234 | return Standard_True; |
7fd59977 |
235 | } |
236 | |
237 | // Inertia computation for XY, YZ and XZ. |
238 | if (myValueType == GProp_InertiaXY || |
424cd6bb |
239 | myValueType == GProp_InertiaYZ || |
240 | myValueType == GProp_InertiaXZ) { |
241 | |
242 | if (myValueType == GProp_InertiaXY) { |
243 | aPPar1 = aPmP0.X(); |
244 | aPPar2 = aPmP0.Y(); |
245 | aCoeff1 = aCoeffs[0]; |
246 | aCoeff2 = aCoeffs[1]; |
247 | } else if (myValueType == GProp_InertiaYZ) { |
248 | aPPar1 = aPmP0.Y(); |
249 | aPPar2 = aPmP0.Z(); |
250 | aCoeff1 = aCoeffs[1]; |
251 | aCoeff2 = aCoeffs[2]; |
252 | } else { // myValueType == GProp_InertiaXZ |
253 | aPPar1 = aPmP0.X(); |
254 | aPPar2 = aPmP0.Z(); |
255 | aCoeff1 = aCoeffs[0]; |
256 | aCoeff2 = aCoeffs[2]; |
257 | } |
258 | |
259 | aD2 *= 0.5; |
260 | aPPar1 -= aCoeff1*aD1; |
261 | aPPar2 -= aCoeff2*aD1; |
262 | aParam1 = aPPar1*aPPar2*aD1 |
263 | + (aPPar1*aCoeff2 + aPPar2*aCoeff1)*aD2 + aCoeff1*aCoeff2*aD3; |
264 | |
265 | F = -aParam1*aS; |
266 | |
267 | return Standard_True; |
7fd59977 |
268 | } |
269 | |
270 | return Standard_False; |
271 | } |