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