b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
7fd59977 |
19 | |
20 | #include <BRepGProp.hxx> |
21 | #include <BRepGProp_Cinert.hxx> |
22 | #include <BRepGProp_Sinert.hxx> |
23 | #include <BRepGProp_Vinert.hxx> |
24 | #include <BRepGProp_VinertGK.hxx> |
25 | #include <BRepGProp_Face.hxx> |
26 | #include <BRepGProp_Domain.hxx> |
27 | #include <TopoDS.hxx> |
28 | #include <BRepAdaptor_Curve.hxx> |
29 | |
30 | #include <TopTools.hxx> |
31 | #include <BRep_Tool.hxx> |
32 | #include <TopTools_ListOfShape.hxx> |
33 | #include <BRepCheck_Shell.hxx> |
34 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
35 | #ifdef DEB |
36 | static Standard_Integer AffichEps = 0; |
37 | #endif |
38 | |
39 | static gp_Pnt roughBaryCenter(const TopoDS_Shape& S){ |
40 | Standard_Integer i; TopExp_Explorer ex; |
41 | gp_XYZ xyz(0,0,0); |
42 | for (ex.Init(S,TopAbs_VERTEX), i = 0; ex.More(); ex.Next(), i++) |
43 | xyz += BRep_Tool::Pnt(TopoDS::Vertex(ex.Current())).XYZ(); |
44 | if ( i > 0 ) xyz /= i; |
45 | return gp_Pnt(xyz); |
46 | } |
47 | |
48 | void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps){ |
49 | // find the origin |
50 | gp_Pnt P(0,0,0); |
51 | P.Transform(S.Location()); |
52 | SProps = GProp_GProps(P); |
53 | |
54 | BRepAdaptor_Curve BAC; |
55 | // Standard_Integer n,i; |
56 | TopExp_Explorer ex; |
57 | for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) { |
58 | BAC.Initialize(TopoDS::Edge(ex.Current())); |
59 | BRepGProp_Cinert CG(BAC,P); |
60 | SProps.Add(CG); |
61 | } |
62 | } |
63 | |
64 | static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps){ |
65 | Standard_Integer i, iErrorMax = 0; |
66 | Standard_Real ErrorMax = 0.0, Error; |
67 | TopExp_Explorer ex; |
68 | gp_Pnt P(roughBaryCenter(S)); |
69 | BRepGProp_Sinert G; G.SetLocation(P); |
70 | |
71 | BRepGProp_Face BF; |
72 | BRepGProp_Domain BD; |
73 | |
74 | for (ex.Init(S,TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) { |
75 | const TopoDS_Face& F = TopoDS::Face(ex.Current()); |
76 | BF.Load(F); |
77 | if(!BF.NaturalRestriction()) BD.Init(F); |
78 | if(Eps < 1.0) { |
79 | G.Perform(BF, BD, Eps); |
80 | Error = G.GetEpsilon(); |
81 | if(ErrorMax < Error){ ErrorMax = Error; iErrorMax = i;} |
82 | } else { |
83 | if(BF.NaturalRestriction()) G.Perform(BF); |
84 | else G.Perform(BF, BD); |
85 | } |
86 | Props.Add(G); |
87 | #ifdef DEB |
88 | if(AffichEps) cout<<"\n"<<i<<":\tEpsArea = "<< G.GetEpsilon(); |
89 | #endif |
90 | } |
91 | #ifdef DEB |
92 | if(AffichEps) cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n"; |
93 | #endif |
94 | return ErrorMax; |
95 | } |
96 | void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props){ |
97 | // find the origin |
98 | gp_Pnt P(0,0,0); |
99 | P.Transform(S.Location()); |
100 | Props = GProp_GProps(P); |
101 | surfaceProperties(S,Props,1.0); |
102 | } |
103 | Standard_Real BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps){ |
104 | // find the origin |
105 | gp_Pnt P(0,0,0); P.Transform(S.Location()); |
106 | Props = GProp_GProps(P); |
107 | Standard_Real ErrorMax = surfaceProperties(S,Props,Eps); |
108 | return ErrorMax; |
109 | } |
110 | |
111 | //======================================================================= |
112 | //function : volumeProperties |
113 | //purpose : |
114 | //======================================================================= |
115 | |
116 | static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps){ |
117 | Standard_Integer i, iErrorMax = 0; |
118 | Standard_Real ErrorMax = 0.0, Error = 0.0; |
119 | TopExp_Explorer ex; |
120 | gp_Pnt P(roughBaryCenter(S)); |
121 | BRepGProp_Vinert G; G.SetLocation(P); |
122 | |
123 | BRepGProp_Face BF; |
124 | BRepGProp_Domain BD; |
125 | |
126 | for (ex.Init(S,TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) { |
127 | const TopoDS_Face& F = TopoDS::Face(ex.Current()); |
128 | if ((F.Orientation() == TopAbs_FORWARD) || (F.Orientation() == TopAbs_REVERSED)){ |
129 | BF.Load(F); |
130 | if(!BF.NaturalRestriction()) BD.Init(F); |
131 | if(Eps < 1.0) { |
132 | G.Perform(BF, BD, Eps); |
133 | Error = G.GetEpsilon(); |
134 | if(ErrorMax < Error){ ErrorMax = Error; iErrorMax = i;} |
135 | } |
136 | else { |
137 | if(BF.NaturalRestriction()) G.Perform(BF); |
138 | else G.Perform(BF, BD); |
139 | } |
140 | Props.Add(G); |
141 | #ifdef DEB |
142 | if(AffichEps) cout<<"\n"<<i<<":\tEpsVolume = "<< G.GetEpsilon(); |
143 | #endif |
144 | } |
145 | } |
146 | #ifdef DEB |
147 | if(AffichEps) cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n"; |
148 | #endif |
149 | return ErrorMax; |
150 | } |
151 | void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean OnlyClosed){ |
152 | // find the origin |
153 | gp_Pnt P(0,0,0); P.Transform(S.Location()); |
154 | Props = GProp_GProps(P); |
155 | Standard_Real Error = 0.0; |
156 | if(OnlyClosed){ |
157 | TopExp_Explorer ex(S,TopAbs_SHELL); |
158 | for (; ex.More(); ex.Next()) { |
159 | const TopoDS_Shape& Sh = ex.Current(); |
160 | if(BRep_Tool::IsClosed(Sh)) Error = volumeProperties(Sh,Props,1.0); |
161 | } |
162 | } else Error = volumeProperties(S,Props,1.0); |
163 | } |
164 | |
165 | //======================================================================= |
166 | //function : VolumeProperties |
167 | //purpose : |
168 | //======================================================================= |
169 | |
170 | Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, |
171 | const Standard_Real Eps, const Standard_Boolean OnlyClosed) |
172 | { |
173 | // find the origin |
174 | gp_Pnt P(0,0,0); P.Transform(S.Location()); |
175 | Props = GProp_GProps(P); |
176 | Standard_Integer i, iErrorMax = 0; |
177 | Standard_Real ErrorMax = 0.0, Error = 0.0; |
178 | if(OnlyClosed){ |
179 | TopExp_Explorer ex(S,TopAbs_SHELL); |
180 | for (i = 1; ex.More(); ex.Next(), i++) { |
181 | const TopoDS_Shape& Sh = ex.Current(); |
182 | if(BRep_Tool::IsClosed(Sh)) { |
183 | Error = volumeProperties(Sh,Props,Eps); |
184 | if(ErrorMax < Error){ ErrorMax = Error; iErrorMax = i;} |
185 | } |
186 | } |
187 | } else ErrorMax = volumeProperties(S,Props,Eps); |
188 | #ifdef DEB |
189 | if(AffichEps) cout<<"\n\n==================="<<iErrorMax<<":\tMaxEpsVolume = "<<ErrorMax<<"\n"; |
190 | #endif |
191 | return ErrorMax; |
192 | } |
193 | |
194 | //===========================================================================================// |
195 | // Volume properties by Gauss-Kronrod integration |
196 | //===========================================================================================// |
197 | //======================================================================= |
198 | //function : VolumePropertiesGK |
199 | //purpose : |
200 | //======================================================================= |
201 | |
202 | static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape, |
203 | GProp_GProps &theProps, |
204 | const Standard_Real theTol, |
205 | const Standard_Boolean IsUseSpan, |
206 | const Standard_Boolean CGFlag, |
207 | const Standard_Boolean IFlag) |
208 | { |
209 | TopExp_Explorer anExp; |
210 | anExp.Init(theShape, TopAbs_FACE); |
211 | |
212 | Standard_Real aTol = theTol; |
213 | |
214 | // Compute properties. |
215 | gp_Pnt aLoc(roughBaryCenter(theShape)); |
216 | BRepGProp_VinertGK aVProps; |
217 | BRepGProp_Face aPropFace(IsUseSpan); |
218 | BRepGProp_Domain aPropDomain; |
219 | Standard_Real aLocalError; |
220 | Standard_Real anError = 0.; |
221 | |
222 | aVProps.SetLocation(aLoc); |
223 | |
224 | for (; anExp.More(); anExp.Next()) { |
225 | TopoDS_Face aFace = TopoDS::Face(anExp.Current()); |
226 | |
227 | if (aFace.Orientation() == TopAbs_FORWARD || |
228 | aFace.Orientation() == TopAbs_REVERSED) { |
229 | aPropFace.Load(aFace); |
230 | |
231 | if(aPropFace.NaturalRestriction()) |
232 | aLocalError = aVProps.Perform(aPropFace, aTol, CGFlag, IFlag); |
233 | else { |
234 | aPropDomain.Init(aFace); |
235 | aLocalError = aVProps.Perform(aPropFace, aPropDomain, aTol, CGFlag, IFlag); |
236 | } |
237 | |
238 | if (aLocalError < 0.) |
239 | return aLocalError; |
240 | |
241 | anError += aLocalError; |
242 | theProps.Add(aVProps); |
243 | } |
244 | } |
245 | |
246 | return anError; |
247 | } |
248 | |
249 | //======================================================================= |
250 | //function : VolumePropertiesGK |
251 | //purpose : |
252 | //======================================================================= |
253 | |
254 | Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S, |
255 | GProp_GProps &Props, |
256 | const Standard_Real Eps, |
257 | const Standard_Boolean OnlyClosed, |
258 | const Standard_Boolean IsUseSpan, |
259 | const Standard_Boolean CGFlag, |
260 | const Standard_Boolean IFlag) |
261 | { |
262 | gp_Pnt P(0,0,0); |
263 | Standard_Real anError = 0.; |
264 | |
265 | P.Transform(S.Location()); |
266 | Props = GProp_GProps(P); |
267 | |
268 | if(OnlyClosed) { |
269 | // To select closed shells. |
270 | TopExp_Explorer anExp; |
271 | TopTools_ListOfShape aClosedShells; |
272 | |
273 | anExp.Init(S, TopAbs_SHELL); |
274 | |
275 | for (; anExp.More(); anExp.Next()) { |
276 | const TopoDS_Shape &aShell = anExp.Current(); |
277 | |
278 | BRepCheck_Shell aChecker(TopoDS::Shell(aShell)); |
279 | BRepCheck_Status aStatus = aChecker.Closed(Standard_False); |
280 | |
281 | if(aStatus == BRepCheck_NoError) |
282 | aClosedShells.Append(aShell); |
283 | |
284 | } |
285 | |
286 | if (aClosedShells.IsEmpty()) |
287 | return -1.; |
288 | |
289 | // Compute the properties for each closed shell. |
290 | Standard_Real aTol = Eps; |
291 | Standard_Real aLocalError; |
292 | TopTools_ListIteratorOfListOfShape anIter(aClosedShells); |
293 | |
294 | for (; anIter.More(); anIter.Next()) { |
295 | const TopoDS_Shape &aShell = anIter.Value(); |
296 | |
297 | aLocalError = volumePropertiesGK(aShell, Props, aTol, IsUseSpan, CGFlag, IFlag); |
298 | |
299 | if (aLocalError < 0) |
300 | return aLocalError; |
301 | |
302 | anError += aLocalError; |
303 | } |
304 | |
305 | } else |
306 | anError = volumePropertiesGK(S, Props, Eps, IsUseSpan, CGFlag, IFlag); |
307 | |
308 | Standard_Real vol = Props.Mass(); |
309 | if(vol > Epsilon(1.)) anError /= vol; |
310 | return anError; |
311 | } |
312 | |
313 | //======================================================================= |
314 | //function : VolumeProperties |
315 | //purpose : |
316 | //======================================================================= |
317 | |
318 | static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape, |
319 | GProp_GProps &theProps, |
320 | const gp_Pln &thePln, |
321 | const Standard_Real theTol, |
322 | const Standard_Boolean IsUseSpan, |
323 | const Standard_Boolean CGFlag, |
324 | const Standard_Boolean IFlag) |
325 | { |
326 | TopExp_Explorer anExp; |
327 | anExp.Init(theShape, TopAbs_FACE); |
328 | |
329 | Standard_Real aTol = theTol; |
330 | |
331 | // Compute properties. |
332 | gp_Pnt aLoc(roughBaryCenter(theShape)); |
333 | BRepGProp_VinertGK aVProps; |
334 | BRepGProp_Face aPropFace(IsUseSpan); |
335 | BRepGProp_Domain aPropDomain; |
336 | Standard_Real aLocalError; |
337 | Standard_Real anError = 0.; |
338 | |
339 | aVProps.SetLocation(aLoc); |
340 | |
341 | for (; anExp.More(); anExp.Next()) { |
342 | TopoDS_Face aFace = TopoDS::Face(anExp.Current()); |
343 | |
344 | if (aFace.Orientation() == TopAbs_FORWARD || |
345 | aFace.Orientation() == TopAbs_REVERSED) { |
346 | aPropFace.Load(aFace); |
347 | |
348 | if(aPropFace.NaturalRestriction()) |
349 | aLocalError = aVProps.Perform(aPropFace, thePln, aTol, CGFlag, IFlag); |
350 | else { |
351 | aPropDomain.Init(aFace); |
352 | aLocalError = aVProps.Perform(aPropFace, aPropDomain, thePln, aTol, CGFlag, IFlag); |
353 | } |
354 | |
355 | if (aLocalError < 0.) |
356 | return aLocalError; |
357 | |
358 | anError += aLocalError; |
359 | theProps.Add(aVProps); |
360 | } |
361 | } |
362 | |
363 | return anError; |
364 | } |
365 | |
366 | //======================================================================= |
367 | //function : VolumeProperties |
368 | //purpose : |
369 | //======================================================================= |
370 | |
371 | Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S, |
372 | GProp_GProps &Props, |
373 | const gp_Pln &thePln, |
374 | const Standard_Real Eps, |
375 | const Standard_Boolean OnlyClosed, |
376 | const Standard_Boolean IsUseSpan, |
377 | const Standard_Boolean CGFlag, |
378 | const Standard_Boolean IFlag) |
379 | { |
380 | gp_Pnt P(0,0,0); |
381 | Standard_Real anError = 0.; |
382 | |
383 | P.Transform(S.Location()); |
384 | Props = GProp_GProps(P); |
385 | |
386 | if(OnlyClosed) { |
387 | // To select closed shells. |
388 | TopExp_Explorer anExp; |
389 | TopTools_ListOfShape aClosedShells; |
390 | |
391 | anExp.Init(S, TopAbs_SHELL); |
392 | |
393 | for (; anExp.More(); anExp.Next()) { |
394 | const TopoDS_Shape &aShell = anExp.Current(); |
395 | |
396 | BRepCheck_Shell aChecker(TopoDS::Shell(aShell)); |
397 | BRepCheck_Status aStatus = aChecker.Closed(Standard_False); |
398 | |
399 | if(aStatus == BRepCheck_NoError) |
400 | aClosedShells.Append(aShell); |
401 | |
402 | } |
403 | |
404 | if (aClosedShells.IsEmpty()) |
405 | return -1.; |
406 | |
407 | // Compute the properties for each closed shell. |
408 | Standard_Real aTol = Eps; |
409 | Standard_Real aLocalError; |
410 | TopTools_ListIteratorOfListOfShape anIter(aClosedShells); |
411 | |
412 | for (; anIter.More(); anIter.Next()) { |
413 | const TopoDS_Shape &aShell = anIter.Value(); |
414 | |
415 | aLocalError = volumePropertiesGK(aShell, Props, thePln, aTol, IsUseSpan, CGFlag, IFlag); |
416 | |
417 | if (aLocalError < 0) |
418 | return aLocalError; |
419 | |
420 | anError += aLocalError; |
421 | } |
422 | } else |
423 | anError = volumePropertiesGK(S, Props, thePln, Eps, IsUseSpan, CGFlag, IFlag); |
424 | |
425 | Standard_Real vol = Props.Mass(); |
426 | if(vol > Epsilon(1.)) anError /= vol; |
427 | |
428 | return anError; |
429 | } |