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> | |
4b114473 | 19 | #include <BRepGProp_MeshProps.hxx> |
20 | #include <BRepGProp_MeshCinert.hxx> | |
7fd59977 | 21 | #include <BRepGProp_VinertGK.hxx> |
a4ed7309 | 22 | #include <GProp_PGProps.hxx> |
7fd59977 | 23 | #include <BRepGProp_Face.hxx> |
24 | #include <BRepGProp_Domain.hxx> | |
25 | #include <TopoDS.hxx> | |
26 | #include <BRepAdaptor_Curve.hxx> | |
27 | ||
28 | #include <TopTools.hxx> | |
29 | #include <BRep_Tool.hxx> | |
30 | #include <TopTools_ListOfShape.hxx> | |
fe3e01db | 31 | #include <TopTools_MapOfShape.hxx> |
7fd59977 | 32 | #include <BRepCheck_Shell.hxx> |
33 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
4b114473 | 34 | |
0797d9d3 | 35 | #ifdef OCCT_DEBUG |
7fd59977 | 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(); | |
4b114473 | 44 | if (i > 0) |
45 | { | |
46 | xyz /= i; | |
47 | } | |
48 | else | |
49 | { | |
50 | //Try using triangulation | |
51 | ex.Init(S, TopAbs_FACE); | |
52 | for (; ex.More(); ex.Next()) | |
53 | { | |
54 | const TopoDS_Shape& aF = ex.Current(); | |
55 | TopLoc_Location aLocDummy; | |
56 | const Handle(Poly_Triangulation)& aTri = | |
57 | BRep_Tool::Triangulation(TopoDS::Face(aF), aLocDummy); | |
58 | if (!aTri.IsNull()) | |
59 | { | |
60 | xyz = aTri->Node(1).XYZ(); | |
61 | if (!aLocDummy.IsIdentity()) | |
62 | { | |
63 | aLocDummy.Transformation().Transforms(xyz); | |
64 | } | |
65 | break; | |
66 | } | |
67 | } | |
68 | } | |
7fd59977 | 69 | return gp_Pnt(xyz); |
70 | } | |
71 | ||
4b114473 | 72 | |
73 | ||
74 | void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Boolean SkipShared, | |
75 | const Standard_Boolean UseTriangulation) | |
76 | { | |
7fd59977 | 77 | // find the origin |
78 | gp_Pnt P(0,0,0); | |
79 | P.Transform(S.Location()); | |
80 | SProps = GProp_GProps(P); | |
81 | ||
82 | BRepAdaptor_Curve BAC; | |
fe3e01db | 83 | TopTools_MapOfShape anEMap; |
7fd59977 | 84 | TopExp_Explorer ex; |
85 | for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) { | |
a4ed7309 | 86 | const TopoDS_Edge& aE = TopoDS::Edge(ex.Current()); |
fe3e01db | 87 | if(SkipShared && !anEMap.Add(aE)) |
88 | { | |
89 | continue; | |
90 | } | |
4b114473 | 91 | |
92 | Handle(TColgp_HArray1OfPnt) theNodes; | |
93 | Standard_Boolean IsGeom = BRep_Tool::IsGeometric(aE); | |
94 | if (UseTriangulation || !IsGeom) | |
a4ed7309 | 95 | { |
4b114473 | 96 | BRepGProp_MeshCinert::PreparePolygon(aE, theNodes); |
97 | } | |
98 | if(!theNodes.IsNull()) | |
99 | { | |
100 | BRepGProp_MeshCinert MG; | |
101 | MG.SetLocation(P); | |
102 | MG.Perform(theNodes->Array1()); | |
103 | SProps.Add(MG); | |
a4ed7309 | 104 | } |
105 | else | |
106 | { | |
4b114473 | 107 | if (IsGeom) |
108 | { | |
109 | BAC.Initialize(aE); | |
110 | BRepGProp_Cinert CG(BAC, P); | |
111 | SProps.Add(CG); | |
112 | } | |
a4ed7309 | 113 | } |
7fd59977 | 114 | } |
115 | } | |
116 | ||
4b114473 | 117 | static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared, |
118 | const Standard_Boolean UseTriangulation) | |
119 | { | |
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; |
125 | TopExp_Explorer ex; | |
126 | gp_Pnt P(roughBaryCenter(S)); | |
127 | BRepGProp_Sinert G; G.SetLocation(P); | |
4b114473 | 128 | BRepGProp_MeshProps MG(BRepGProp_MeshProps::Sinert); |
129 | MG.SetLocation(P); | |
7fd59977 | 130 | |
131 | BRepGProp_Face BF; | |
132 | BRepGProp_Domain BD; | |
fe3e01db | 133 | TopTools_MapOfShape aFMap; |
4d19a2c5 | 134 | TopLoc_Location aLocDummy; |
7fd59977 | 135 | |
4b114473 | 136 | for (ex.Init(S, TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) { |
7fd59977 | 137 | const TopoDS_Face& F = TopoDS::Face(ex.Current()); |
4b114473 | 138 | if (SkipShared && !aFMap.Add(F)) |
fe3e01db | 139 | { |
140 | continue; | |
141 | } | |
4d19a2c5 | 142 | |
4b114473 | 143 | Standard_Boolean NoSurf = Standard_False, NoTri = Standard_False; |
4d19a2c5 | 144 | { |
4b114473 | 145 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, aLocDummy); |
4d19a2c5 | 146 | if (aSurf.IsNull()) |
147 | { | |
4b114473 | 148 | NoSurf = Standard_True; |
149 | } | |
150 | const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy); | |
151 | if (aTri.IsNull()) | |
152 | { | |
153 | NoTri = Standard_True; | |
154 | } | |
155 | if (NoTri && NoSurf) | |
156 | { | |
4d19a2c5 | 157 | continue; |
158 | } | |
159 | } | |
160 | ||
4b114473 | 161 | if ((UseTriangulation && !NoTri) || (NoSurf && !NoTri)) |
162 | { | |
163 | TopAbs_Orientation anOri = F.Orientation(); | |
164 | const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy); | |
165 | MG.Perform(aTri, aLocDummy, anOri); | |
166 | Props.Add(MG); | |
167 | } | |
168 | else | |
169 | { | |
170 | BF.Load(F); | |
171 | Standard_Boolean IsNatRestr = (F.NbChildren() == 0); | |
172 | if (!IsNatRestr) BD.Init(F); | |
173 | if (Eps < 1.0) { | |
174 | G.Perform(BF, BD, Eps); | |
175 | Error = G.GetEpsilon(); | |
176 | if (ErrorMax < Error) { | |
177 | ErrorMax = Error; | |
0797d9d3 | 178 | #ifdef OCCT_DEBUG |
4b114473 | 179 | iErrorMax = i; |
96a95605 | 180 | #endif |
4b114473 | 181 | } |
96a95605 | 182 | } |
4b114473 | 183 | else { |
184 | if (IsNatRestr) G.Perform(BF); | |
185 | else G.Perform(BF, BD); | |
186 | } | |
187 | Props.Add(G); | |
0797d9d3 | 188 | #ifdef OCCT_DEBUG |
4b114473 | 189 | if(AffichEps) cout<<"\n"<<i<<":\tEpsArea = "<< G.GetEpsilon(); |
7fd59977 | 190 | #endif |
4b114473 | 191 | } |
7fd59977 | 192 | } |
0797d9d3 | 193 | #ifdef OCCT_DEBUG |
7fd59977 | 194 | if(AffichEps) cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n"; |
195 | #endif | |
196 | return ErrorMax; | |
197 | } | |
4b114473 | 198 | void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean SkipShared, |
199 | const Standard_Boolean UseTriangulation) | |
200 | { | |
7fd59977 | 201 | // find the origin |
202 | gp_Pnt P(0,0,0); | |
203 | P.Transform(S.Location()); | |
204 | Props = GProp_GProps(P); | |
4b114473 | 205 | surfaceProperties(S,Props,1.0, SkipShared, UseTriangulation); |
7fd59977 | 206 | } |
fe3e01db | 207 | Standard_Real BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){ |
7fd59977 | 208 | // find the origin |
209 | gp_Pnt P(0,0,0); P.Transform(S.Location()); | |
210 | Props = GProp_GProps(P); | |
4b114473 | 211 | Standard_Real ErrorMax = surfaceProperties(S,Props,Eps,SkipShared, Standard_False); |
7fd59977 | 212 | return ErrorMax; |
213 | } | |
214 | ||
215 | //======================================================================= | |
216 | //function : volumeProperties | |
217 | //purpose : | |
218 | //======================================================================= | |
219 | ||
4b114473 | 220 | static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared, |
221 | const Standard_Boolean UseTriangulation) | |
222 | { | |
96a95605 | 223 | Standard_Integer i; |
0797d9d3 | 224 | #ifdef OCCT_DEBUG |
96a95605 DB |
225 | Standard_Integer iErrorMax = 0; |
226 | #endif | |
7fd59977 | 227 | Standard_Real ErrorMax = 0.0, Error = 0.0; |
228 | TopExp_Explorer ex; | |
229 | gp_Pnt P(roughBaryCenter(S)); | |
230 | BRepGProp_Vinert G; G.SetLocation(P); | |
4b114473 | 231 | BRepGProp_MeshProps MG(BRepGProp_MeshProps::Vinert); |
232 | MG.SetLocation(P); | |
7fd59977 | 233 | |
234 | BRepGProp_Face BF; | |
235 | BRepGProp_Domain BD; | |
fe3e01db | 236 | TopTools_MapOfShape aFwdFMap; |
237 | TopTools_MapOfShape aRvsFMap; | |
c894a5fd | 238 | TopLoc_Location aLocDummy; |
7fd59977 | 239 | |
240 | for (ex.Init(S,TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) { | |
241 | const TopoDS_Face& F = TopoDS::Face(ex.Current()); | |
fe3e01db | 242 | TopAbs_Orientation anOri = F.Orientation(); |
243 | Standard_Boolean isFwd = anOri == TopAbs_FORWARD; | |
244 | Standard_Boolean isRvs = Standard_False; | |
245 | if(!isFwd) | |
246 | { | |
247 | isRvs = anOri == TopAbs_REVERSED; | |
248 | } | |
249 | if(SkipShared) | |
250 | { | |
251 | if((isFwd && !aFwdFMap.Add(F)) || (isRvs && !aRvsFMap.Add(F))) | |
252 | { | |
253 | continue; | |
254 | } | |
255 | } | |
4b114473 | 256 | Standard_Boolean NoSurf = Standard_False, NoTri = Standard_False; |
c894a5fd | 257 | { |
258 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (F, aLocDummy); | |
259 | if (aSurf.IsNull()) | |
260 | { | |
4b114473 | 261 | NoSurf = Standard_True; |
262 | } | |
263 | const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy); | |
264 | if (aTri.IsNull()) | |
265 | { | |
266 | NoTri = Standard_True; | |
267 | } | |
268 | if (NoTri && NoSurf) | |
269 | { | |
c894a5fd | 270 | continue; |
271 | } | |
272 | } | |
273 | ||
4b114473 | 274 | if (isFwd || isRvs) |
275 | { | |
276 | if ((UseTriangulation && !NoTri) || (NoSurf && !NoTri)) | |
277 | { | |
278 | const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy); | |
279 | MG.Perform(aTri, aLocDummy, anOri); | |
280 | Props.Add(MG); | |
281 | } | |
282 | else | |
283 | { | |
284 | BF.Load(F); | |
285 | Standard_Boolean IsNatRestr = (F.NbChildren () == 0); | |
286 | if (!IsNatRestr) BD.Init(F); | |
287 | if (Eps < 1.0) { | |
288 | G.Perform(BF, BD, Eps); | |
289 | Error = G.GetEpsilon(); | |
290 | if (ErrorMax < Error) { | |
291 | ErrorMax = Error; | |
0797d9d3 | 292 | #ifdef OCCT_DEBUG |
4b114473 | 293 | iErrorMax = i; |
96a95605 | 294 | #endif |
4b114473 | 295 | } |
5b0f2540 | 296 | } |
4b114473 | 297 | else { |
298 | if (IsNatRestr) G.Perform(BF); | |
299 | else G.Perform(BF, BD); | |
300 | } | |
301 | Props.Add(G); | |
0797d9d3 | 302 | #ifdef OCCT_DEBUG |
4b114473 | 303 | if(AffichEps) cout<<"\n"<<i<<":\tEpsVolume = "<< G.GetEpsilon(); |
7fd59977 | 304 | #endif |
4b114473 | 305 | } |
7fd59977 | 306 | } |
307 | } | |
0797d9d3 | 308 | #ifdef OCCT_DEBUG |
7fd59977 | 309 | if(AffichEps) cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n"; |
310 | #endif | |
311 | return ErrorMax; | |
312 | } | |
4b114473 | 313 | void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared, |
314 | const Standard_Boolean UseTriangulation) | |
315 | { | |
7fd59977 | 316 | // find the origin |
317 | gp_Pnt P(0,0,0); P.Transform(S.Location()); | |
318 | Props = GProp_GProps(P); | |
7fd59977 | 319 | if(OnlyClosed){ |
fe3e01db | 320 | TopTools_MapOfShape aShMap; |
7fd59977 | 321 | TopExp_Explorer ex(S,TopAbs_SHELL); |
322 | for (; ex.More(); ex.Next()) { | |
323 | const TopoDS_Shape& Sh = ex.Current(); | |
fe3e01db | 324 | if(SkipShared && !aShMap.Add(Sh)) |
325 | { | |
326 | continue; | |
327 | } | |
4b114473 | 328 | if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0,SkipShared, UseTriangulation); |
7fd59977 | 329 | } |
4b114473 | 330 | } else volumeProperties(S,Props,1.0,SkipShared, UseTriangulation); |
7fd59977 | 331 | } |
332 | ||
333 | //======================================================================= | |
334 | //function : VolumeProperties | |
335 | //purpose : | |
336 | //======================================================================= | |
337 | ||
338 | Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, | |
fe3e01db | 339 | const Standard_Real Eps, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared) |
7fd59977 | 340 | { |
341 | // find the origin | |
342 | gp_Pnt P(0,0,0); P.Transform(S.Location()); | |
343 | Props = GProp_GProps(P); | |
96a95605 | 344 | Standard_Integer i; |
0797d9d3 | 345 | #ifdef OCCT_DEBUG |
96a95605 DB |
346 | Standard_Integer iErrorMax = 0; |
347 | #endif | |
7fd59977 | 348 | Standard_Real ErrorMax = 0.0, Error = 0.0; |
349 | if(OnlyClosed){ | |
fe3e01db | 350 | TopTools_MapOfShape aShMap; |
7fd59977 | 351 | TopExp_Explorer ex(S,TopAbs_SHELL); |
352 | for (i = 1; ex.More(); ex.Next(), i++) { | |
353 | const TopoDS_Shape& Sh = ex.Current(); | |
fe3e01db | 354 | if(SkipShared && !aShMap.Add(Sh)) |
355 | { | |
356 | continue; | |
357 | } | |
7fd59977 | 358 | if(BRep_Tool::IsClosed(Sh)) { |
4b114473 | 359 | Error = volumeProperties(Sh,Props,Eps,SkipShared, Standard_False); |
5b0f2540 | 360 | if(ErrorMax < Error) { |
361 | ErrorMax = Error; | |
0797d9d3 | 362 | #ifdef OCCT_DEBUG |
5b0f2540 | 363 | iErrorMax = i; |
96a95605 | 364 | #endif |
5b0f2540 | 365 | } |
7fd59977 | 366 | } |
367 | } | |
4b114473 | 368 | } else ErrorMax = volumeProperties(S,Props,Eps,SkipShared, Standard_False); |
0797d9d3 | 369 | #ifdef OCCT_DEBUG |
7fd59977 | 370 | if(AffichEps) cout<<"\n\n==================="<<iErrorMax<<":\tMaxEpsVolume = "<<ErrorMax<<"\n"; |
371 | #endif | |
372 | return ErrorMax; | |
373 | } | |
374 | ||
375 | //===========================================================================================// | |
376 | // Volume properties by Gauss-Kronrod integration | |
377 | //===========================================================================================// | |
378 | //======================================================================= | |
379 | //function : VolumePropertiesGK | |
380 | //purpose : | |
381 | //======================================================================= | |
382 | ||
383 | static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape, | |
5b0f2540 | 384 | GProp_GProps &theProps, |
385 | const Standard_Real theTol, | |
386 | const Standard_Boolean IsUseSpan, | |
387 | const Standard_Boolean CGFlag, | |
fe3e01db | 388 | const Standard_Boolean IFlag, const Standard_Boolean SkipShared) |
7fd59977 | 389 | { |
390 | TopExp_Explorer anExp; | |
391 | anExp.Init(theShape, TopAbs_FACE); | |
5b0f2540 | 392 | |
7fd59977 | 393 | Standard_Real aTol = theTol; |
394 | ||
395 | // Compute properties. | |
396 | gp_Pnt aLoc(roughBaryCenter(theShape)); | |
397 | BRepGProp_VinertGK aVProps; | |
398 | BRepGProp_Face aPropFace(IsUseSpan); | |
399 | BRepGProp_Domain aPropDomain; | |
400 | Standard_Real aLocalError; | |
401 | Standard_Real anError = 0.; | |
fe3e01db | 402 | TopTools_MapOfShape aFwdFMap; |
403 | TopTools_MapOfShape aRvsFMap; | |
c894a5fd | 404 | TopLoc_Location aLocDummy; |
7fd59977 | 405 | |
406 | aVProps.SetLocation(aLoc); | |
407 | ||
408 | for (; anExp.More(); anExp.Next()) { | |
409 | TopoDS_Face aFace = TopoDS::Face(anExp.Current()); | |
fe3e01db | 410 | TopAbs_Orientation anOri = aFace.Orientation(); |
411 | Standard_Boolean isFwd = anOri == TopAbs_FORWARD; | |
412 | Standard_Boolean isRvs = Standard_False; | |
413 | if(!isFwd) | |
414 | { | |
415 | isRvs = anOri == TopAbs_REVERSED; | |
416 | } | |
417 | if(SkipShared) | |
418 | { | |
419 | if((isFwd && !aFwdFMap.Add(aFace)) || (isRvs && !aRvsFMap.Add(aFace))) | |
420 | { | |
421 | continue; | |
422 | } | |
423 | } | |
c894a5fd | 424 | { |
425 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLocDummy); | |
426 | if (aSurf.IsNull()) | |
427 | { | |
428 | // skip faces without geometry | |
429 | continue; | |
430 | } | |
431 | } | |
432 | ||
fe3e01db | 433 | if (isFwd || isRvs){ |
5b0f2540 | 434 | aPropFace.Load(aFace); |
435 | ||
b2d1851c | 436 | Standard_Boolean IsNatRestr = (aFace.NbChildren () == 0); |
5b0f2540 | 437 | if(IsNatRestr) |
438 | aLocalError = aVProps.Perform(aPropFace, aTol, CGFlag, IFlag); | |
439 | else { | |
440 | aPropDomain.Init(aFace); | |
441 | aLocalError = aVProps.Perform(aPropFace, aPropDomain, aTol, CGFlag, IFlag); | |
442 | } | |
443 | ||
444 | if (aLocalError < 0.) | |
445 | return aLocalError; | |
446 | ||
447 | anError += aLocalError; | |
448 | theProps.Add(aVProps); | |
7fd59977 | 449 | } |
450 | } | |
451 | ||
452 | return anError; | |
453 | } | |
454 | ||
455 | //======================================================================= | |
456 | //function : VolumePropertiesGK | |
457 | //purpose : | |
458 | //======================================================================= | |
459 | ||
460 | Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S, | |
5b0f2540 | 461 | GProp_GProps &Props, |
462 | const Standard_Real Eps, | |
463 | const Standard_Boolean OnlyClosed, | |
464 | const Standard_Boolean IsUseSpan, | |
465 | const Standard_Boolean CGFlag, | |
fe3e01db | 466 | const Standard_Boolean IFlag, const Standard_Boolean SkipShared) |
7fd59977 | 467 | { |
468 | gp_Pnt P(0,0,0); | |
469 | Standard_Real anError = 0.; | |
470 | ||
471 | P.Transform(S.Location()); | |
472 | Props = GProp_GProps(P); | |
473 | ||
474 | if(OnlyClosed) { | |
475 | // To select closed shells. | |
476 | TopExp_Explorer anExp; | |
477 | TopTools_ListOfShape aClosedShells; | |
fe3e01db | 478 | TopTools_MapOfShape aShMap; |
7fd59977 | 479 | |
480 | anExp.Init(S, TopAbs_SHELL); | |
481 | ||
482 | for (; anExp.More(); anExp.Next()) { | |
483 | const TopoDS_Shape &aShell = anExp.Current(); | |
fe3e01db | 484 | if(SkipShared && !aShMap.Add(aShell)) |
485 | { | |
486 | continue; | |
487 | } | |
7fd59977 | 488 | |
489 | BRepCheck_Shell aChecker(TopoDS::Shell(aShell)); | |
490 | BRepCheck_Status aStatus = aChecker.Closed(Standard_False); | |
491 | ||
492 | if(aStatus == BRepCheck_NoError) | |
5b0f2540 | 493 | aClosedShells.Append(aShell); |
7fd59977 | 494 | |
495 | } | |
496 | ||
497 | if (aClosedShells.IsEmpty()) | |
498 | return -1.; | |
499 | ||
500 | // Compute the properties for each closed shell. | |
501 | Standard_Real aTol = Eps; | |
502 | Standard_Real aLocalError; | |
503 | TopTools_ListIteratorOfListOfShape anIter(aClosedShells); | |
504 | ||
505 | for (; anIter.More(); anIter.Next()) { | |
506 | const TopoDS_Shape &aShell = anIter.Value(); | |
507 | ||
fe3e01db | 508 | aLocalError = volumePropertiesGK(aShell, Props, aTol, IsUseSpan, CGFlag, IFlag,SkipShared); |
7fd59977 | 509 | |
510 | if (aLocalError < 0) | |
5b0f2540 | 511 | return aLocalError; |
7fd59977 | 512 | |
513 | anError += aLocalError; | |
514 | } | |
5b0f2540 | 515 | |
7fd59977 | 516 | } else |
fe3e01db | 517 | anError = volumePropertiesGK(S, Props, Eps, IsUseSpan, CGFlag, IFlag,SkipShared); |
7fd59977 | 518 | |
519 | Standard_Real vol = Props.Mass(); | |
520 | if(vol > Epsilon(1.)) anError /= vol; | |
521 | return anError; | |
522 | } | |
523 | ||
524 | //======================================================================= | |
525 | //function : VolumeProperties | |
526 | //purpose : | |
527 | //======================================================================= | |
528 | ||
529 | static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape, | |
5b0f2540 | 530 | GProp_GProps &theProps, |
531 | const gp_Pln &thePln, | |
532 | const Standard_Real theTol, | |
533 | const Standard_Boolean IsUseSpan, | |
534 | const Standard_Boolean CGFlag, | |
fe3e01db | 535 | const Standard_Boolean IFlag, const Standard_Boolean SkipShared) |
7fd59977 | 536 | { |
537 | TopExp_Explorer anExp; | |
538 | anExp.Init(theShape, TopAbs_FACE); | |
539 | ||
540 | Standard_Real aTol = theTol; | |
541 | ||
542 | // Compute properties. | |
543 | gp_Pnt aLoc(roughBaryCenter(theShape)); | |
544 | BRepGProp_VinertGK aVProps; | |
545 | BRepGProp_Face aPropFace(IsUseSpan); | |
546 | BRepGProp_Domain aPropDomain; | |
547 | Standard_Real aLocalError; | |
548 | Standard_Real anError = 0.; | |
fe3e01db | 549 | TopTools_MapOfShape aFwdFMap; |
550 | TopTools_MapOfShape aRvsFMap; | |
c894a5fd | 551 | TopLoc_Location aLocDummy; |
7fd59977 | 552 | |
553 | aVProps.SetLocation(aLoc); | |
554 | ||
555 | for (; anExp.More(); anExp.Next()) { | |
556 | TopoDS_Face aFace = TopoDS::Face(anExp.Current()); | |
fe3e01db | 557 | TopAbs_Orientation anOri = aFace.Orientation(); |
558 | Standard_Boolean isFwd = anOri == TopAbs_FORWARD; | |
559 | Standard_Boolean isRvs = Standard_False; | |
560 | if(!isFwd) | |
561 | { | |
562 | isRvs = anOri == TopAbs_REVERSED; | |
563 | } | |
564 | if(SkipShared) | |
565 | { | |
566 | if((isFwd && !aFwdFMap.Add(aFace)) || (isRvs && !aRvsFMap.Add(aFace))) | |
567 | { | |
568 | continue; | |
569 | } | |
570 | } | |
c894a5fd | 571 | { |
572 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLocDummy); | |
573 | if (aSurf.IsNull()) | |
574 | { | |
575 | // skip faces without geometry | |
576 | continue; | |
577 | } | |
578 | } | |
579 | ||
fe3e01db | 580 | if (isFwd || isRvs){ |
5b0f2540 | 581 | aPropFace.Load(aFace); |
582 | ||
b2d1851c | 583 | Standard_Boolean IsNatRestr = (aFace.NbChildren () == 0); |
5b0f2540 | 584 | if(IsNatRestr) |
585 | aLocalError = aVProps.Perform(aPropFace, thePln, aTol, CGFlag, IFlag); | |
586 | else { | |
587 | aPropDomain.Init(aFace); | |
588 | aLocalError = aVProps.Perform(aPropFace, aPropDomain, thePln, aTol, CGFlag, IFlag); | |
589 | } | |
590 | ||
591 | if (aLocalError < 0.) | |
592 | return aLocalError; | |
593 | ||
594 | anError += aLocalError; | |
595 | theProps.Add(aVProps); | |
7fd59977 | 596 | } |
597 | } | |
598 | ||
599 | return anError; | |
600 | } | |
601 | ||
602 | //======================================================================= | |
603 | //function : VolumeProperties | |
604 | //purpose : | |
605 | //======================================================================= | |
606 | ||
607 | Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S, | |
5b0f2540 | 608 | GProp_GProps &Props, |
609 | const gp_Pln &thePln, | |
610 | const Standard_Real Eps, | |
611 | const Standard_Boolean OnlyClosed, | |
612 | const Standard_Boolean IsUseSpan, | |
613 | const Standard_Boolean CGFlag, | |
fe3e01db | 614 | const Standard_Boolean IFlag, const Standard_Boolean SkipShared) |
7fd59977 | 615 | { |
616 | gp_Pnt P(0,0,0); | |
617 | Standard_Real anError = 0.; | |
618 | ||
619 | P.Transform(S.Location()); | |
620 | Props = GProp_GProps(P); | |
621 | ||
622 | if(OnlyClosed) { | |
623 | // To select closed shells. | |
624 | TopExp_Explorer anExp; | |
625 | TopTools_ListOfShape aClosedShells; | |
fe3e01db | 626 | TopTools_MapOfShape aShMap; |
7fd59977 | 627 | |
628 | anExp.Init(S, TopAbs_SHELL); | |
629 | ||
630 | for (; anExp.More(); anExp.Next()) { | |
631 | const TopoDS_Shape &aShell = anExp.Current(); | |
fe3e01db | 632 | if(SkipShared && !aShMap.Add(aShell)) |
633 | { | |
634 | continue; | |
635 | } | |
7fd59977 | 636 | |
637 | BRepCheck_Shell aChecker(TopoDS::Shell(aShell)); | |
638 | BRepCheck_Status aStatus = aChecker.Closed(Standard_False); | |
639 | ||
640 | if(aStatus == BRepCheck_NoError) | |
5b0f2540 | 641 | aClosedShells.Append(aShell); |
7fd59977 | 642 | |
643 | } | |
644 | ||
645 | if (aClosedShells.IsEmpty()) | |
646 | return -1.; | |
647 | ||
648 | // Compute the properties for each closed shell. | |
649 | Standard_Real aTol = Eps; | |
650 | Standard_Real aLocalError; | |
651 | TopTools_ListIteratorOfListOfShape anIter(aClosedShells); | |
652 | ||
653 | for (; anIter.More(); anIter.Next()) { | |
654 | const TopoDS_Shape &aShell = anIter.Value(); | |
655 | ||
fe3e01db | 656 | aLocalError = volumePropertiesGK(aShell, Props, thePln, aTol, IsUseSpan, CGFlag, IFlag,SkipShared); |
7fd59977 | 657 | |
658 | if (aLocalError < 0) | |
5b0f2540 | 659 | return aLocalError; |
7fd59977 | 660 | |
661 | anError += aLocalError; | |
662 | } | |
663 | } else | |
fe3e01db | 664 | anError = volumePropertiesGK(S, Props, thePln, Eps, IsUseSpan, CGFlag, IFlag,SkipShared); |
7fd59977 | 665 | |
666 | Standard_Real vol = Props.Mass(); | |
667 | if(vol > Epsilon(1.)) anError /= vol; | |
668 | ||
669 | return anError; | |
670 | } |