1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <BRepGProp.hxx>
16 #include <BRepGProp_Cinert.hxx>
17 #include <BRepGProp_Sinert.hxx>
18 #include <BRepGProp_Vinert.hxx>
19 #include <BRepGProp_MeshProps.hxx>
20 #include <BRepGProp_MeshCinert.hxx>
21 #include <BRepGProp_VinertGK.hxx>
22 #include <GProp_PGProps.hxx>
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>
31 #include <TopTools_MapOfShape.hxx>
32 #include <BRepCheck_Shell.hxx>
33 #include <TopTools_ListIteratorOfListOfShape.hxx>
34
35 #ifdef OCCT_DEBUG
36 static Standard_Integer AffichEps = 0;
37 #endif
38
roughBaryCenter(const TopoDS_Shape & S)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)
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() && aTri->NbNodes() > 0)
59 {
60 xyz = aTri->Node(1).XYZ();
61 if (!aLocDummy.IsIdentity())
62 {
63 aLocDummy.Transformation().Transforms(xyz);
64 }
65 break;
66 }
67 }
68 }
69 return gp_Pnt(xyz);
70 }
71
72
73
LinearProperties(const TopoDS_Shape & S,GProp_GProps & SProps,const Standard_Boolean SkipShared,const Standard_Boolean UseTriangulation)74 void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Boolean SkipShared,
75 const Standard_Boolean UseTriangulation)
76 {
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;
83 TopTools_MapOfShape anEMap;
84 TopExp_Explorer ex;
85 for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
86 const TopoDS_Edge& aE = TopoDS::Edge(ex.Current());
87 if(SkipShared && !anEMap.Add(aE))
88 {
89 continue;
90 }
91
92 Handle(TColgp_HArray1OfPnt) theNodes;
93 Standard_Boolean IsGeom = BRep_Tool::IsGeometric(aE);
94 if (UseTriangulation || !IsGeom)
95 {
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);
104 }
105 else
106 {
107 if (IsGeom)
108 {
109 BAC.Initialize(aE);
110 BRepGProp_Cinert CG(BAC, P);
111 SProps.Add(CG);
112 }
113 }
114 }
115 }
116
surfaceProperties(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Real Eps,const Standard_Boolean SkipShared,const Standard_Boolean UseTriangulation)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 {
120 Standard_Integer i;
121 #ifdef OCCT_DEBUG
122 Standard_Integer iErrorMax = 0;
123 #endif
124 Standard_Real ErrorMax = 0.0, Error;
125 TopExp_Explorer ex;
126 gp_Pnt P(roughBaryCenter(S));
127 BRepGProp_Sinert G; G.SetLocation(P);
128 BRepGProp_MeshProps MG(BRepGProp_MeshProps::Sinert);
129 MG.SetLocation(P);
130
131 BRepGProp_Face BF;
132 BRepGProp_Domain BD;
133 TopTools_MapOfShape aFMap;
134 TopLoc_Location aLocDummy;
135
136 for (ex.Init(S, TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) {
137 const TopoDS_Face& F = TopoDS::Face(ex.Current());
138 if (SkipShared && !aFMap.Add(F))
139 {
140 continue;
141 }
142
143 Standard_Boolean NoSurf = Standard_False, NoTri = Standard_False;
144 {
145 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, aLocDummy);
146 if (aSurf.IsNull())
147 {
148 NoSurf = Standard_True;
149 }
150 const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
151 if (aTri.IsNull() || aTri->NbNodes() == 0 || aTri->NbTriangles() == 0)
152 {
153 NoTri = Standard_True;
154 }
155 if (NoTri && NoSurf)
156 {
157 continue;
158 }
159 }
160
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;
178 #ifdef OCCT_DEBUG
179 iErrorMax = i;
180 #endif
181 }
182 }
183 else {
184 if (IsNatRestr) G.Perform(BF);
185 else G.Perform(BF, BD);
186 }
187 Props.Add(G);
188 #ifdef OCCT_DEBUG
189 if(AffichEps) std::cout<<"\n"<<i<<":\tEpsArea = "<< G.GetEpsilon();
190 #endif
191 }
192 }
193 #ifdef OCCT_DEBUG
194 if(AffichEps) std::cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n";
195 #endif
196 return ErrorMax;
197 }
SurfaceProperties(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Boolean SkipShared,const Standard_Boolean UseTriangulation)198 void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean SkipShared,
199 const Standard_Boolean UseTriangulation)
200 {
201 // find the origin
202 gp_Pnt P(0,0,0);
203 P.Transform(S.Location());
204 Props = GProp_GProps(P);
205 surfaceProperties(S,Props,1.0, SkipShared, UseTriangulation);
206 }
SurfaceProperties(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Real Eps,const Standard_Boolean SkipShared)207 Standard_Real BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){
208 // find the origin
209 gp_Pnt P(0,0,0); P.Transform(S.Location());
210 Props = GProp_GProps(P);
211 Standard_Real ErrorMax = surfaceProperties(S,Props,Eps,SkipShared, Standard_False);
212 return ErrorMax;
213 }
214
215 //=======================================================================
216 //function : volumeProperties
217 //purpose :
218 //=======================================================================
219
volumeProperties(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Real Eps,const Standard_Boolean SkipShared,const Standard_Boolean UseTriangulation)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 {
223 Standard_Integer i;
224 #ifdef OCCT_DEBUG
225 Standard_Integer iErrorMax = 0;
226 #endif
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);
231 BRepGProp_MeshProps MG(BRepGProp_MeshProps::Vinert);
232 MG.SetLocation(P);
233
234 BRepGProp_Face BF;
235 BRepGProp_Domain BD;
236 TopTools_MapOfShape aFwdFMap;
237 TopTools_MapOfShape aRvsFMap;
238 TopLoc_Location aLocDummy;
239
240 for (ex.Init(S,TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) {
241 const TopoDS_Face& F = TopoDS::Face(ex.Current());
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 }
256 Standard_Boolean NoSurf = Standard_False, NoTri = Standard_False;
257 {
258 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (F, aLocDummy);
259 if (aSurf.IsNull())
260 {
261 NoSurf = Standard_True;
262 }
263 const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
264 if (aTri.IsNull() || aTri->NbNodes() == 0 || aTri->NbTriangles() == 0)
265 {
266 NoTri = Standard_True;
267 }
268 if (NoTri && NoSurf)
269 {
270 continue;
271 }
272 }
273
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;
292 #ifdef OCCT_DEBUG
293 iErrorMax = i;
294 #endif
295 }
296 }
297 else {
298 if (IsNatRestr) G.Perform(BF);
299 else G.Perform(BF, BD);
300 }
301 Props.Add(G);
302 #ifdef OCCT_DEBUG
303 if(AffichEps) std::cout<<"\n"<<i<<":\tEpsVolume = "<< G.GetEpsilon();
304 #endif
305 }
306 }
307 }
308 #ifdef OCCT_DEBUG
309 if(AffichEps) std::cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n";
310 #endif
311 return ErrorMax;
312 }
VolumeProperties(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Boolean OnlyClosed,const Standard_Boolean SkipShared,const Standard_Boolean UseTriangulation)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 {
316 // find the origin
317 gp_Pnt P(0,0,0); P.Transform(S.Location());
318 Props = GProp_GProps(P);
319 if(OnlyClosed){
320 TopTools_MapOfShape aShMap;
321 TopExp_Explorer ex(S,TopAbs_SHELL);
322 for (; ex.More(); ex.Next()) {
323 const TopoDS_Shape& Sh = ex.Current();
324 if(SkipShared && !aShMap.Add(Sh))
325 {
326 continue;
327 }
328 if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0,SkipShared, UseTriangulation);
329 }
330 } else volumeProperties(S,Props,1.0,SkipShared, UseTriangulation);
331 }
332
333 //=======================================================================
334 //function : VolumeProperties
335 //purpose :
336 //=======================================================================
337
VolumeProperties(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Real Eps,const Standard_Boolean OnlyClosed,const Standard_Boolean SkipShared)338 Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props,
339 const Standard_Real Eps, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared)
340 {
341 // find the origin
342 gp_Pnt P(0,0,0); P.Transform(S.Location());
343 Props = GProp_GProps(P);
344 Standard_Integer i;
345 #ifdef OCCT_DEBUG
346 Standard_Integer iErrorMax = 0;
347 #endif
348 Standard_Real ErrorMax = 0.0, Error = 0.0;
349 if(OnlyClosed){
350 TopTools_MapOfShape aShMap;
351 TopExp_Explorer ex(S,TopAbs_SHELL);
352 for (i = 1; ex.More(); ex.Next(), i++) {
353 const TopoDS_Shape& Sh = ex.Current();
354 if(SkipShared && !aShMap.Add(Sh))
355 {
356 continue;
357 }
358 if(BRep_Tool::IsClosed(Sh)) {
359 Error = volumeProperties(Sh,Props,Eps,SkipShared, Standard_False);
360 if(ErrorMax < Error) {
361 ErrorMax = Error;
362 #ifdef OCCT_DEBUG
363 iErrorMax = i;
364 #endif
365 }
366 }
367 }
368 } else ErrorMax = volumeProperties(S,Props,Eps,SkipShared, Standard_False);
369 #ifdef OCCT_DEBUG
370 if(AffichEps) std::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
volumePropertiesGK(const TopoDS_Shape & theShape,GProp_GProps & theProps,const Standard_Real theTol,const Standard_Boolean IsUseSpan,const Standard_Boolean CGFlag,const Standard_Boolean IFlag,const Standard_Boolean SkipShared)383 static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape,
384 GProp_GProps &theProps,
385 const Standard_Real theTol,
386 const Standard_Boolean IsUseSpan,
387 const Standard_Boolean CGFlag,
388 const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
389 {
390 TopExp_Explorer anExp;
391 anExp.Init(theShape, TopAbs_FACE);
392
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.;
402 TopTools_MapOfShape aFwdFMap;
403 TopTools_MapOfShape aRvsFMap;
404 TopLoc_Location aLocDummy;
405
406 aVProps.SetLocation(aLoc);
407
408 for (; anExp.More(); anExp.Next()) {
409 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
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 }
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
433 if (isFwd || isRvs){
434 aPropFace.Load(aFace);
435
436 Standard_Boolean IsNatRestr = (aFace.NbChildren () == 0);
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);
449 }
450 }
451
452 return anError;
453 }
454
455 //=======================================================================
456 //function : VolumePropertiesGK
457 //purpose :
458 //=======================================================================
459
VolumePropertiesGK(const TopoDS_Shape & S,GProp_GProps & Props,const Standard_Real Eps,const Standard_Boolean OnlyClosed,const Standard_Boolean IsUseSpan,const Standard_Boolean CGFlag,const Standard_Boolean IFlag,const Standard_Boolean SkipShared)460 Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
461 GProp_GProps &Props,
462 const Standard_Real Eps,
463 const Standard_Boolean OnlyClosed,
464 const Standard_Boolean IsUseSpan,
465 const Standard_Boolean CGFlag,
466 const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
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;
478 TopTools_MapOfShape aShMap;
479
480 anExp.Init(S, TopAbs_SHELL);
481
482 for (; anExp.More(); anExp.Next()) {
483 const TopoDS_Shape &aShell = anExp.Current();
484 if(SkipShared && !aShMap.Add(aShell))
485 {
486 continue;
487 }
488
489 BRepCheck_Shell aChecker(TopoDS::Shell(aShell));
490 BRepCheck_Status aStatus = aChecker.Closed(Standard_False);
491
492 if(aStatus == BRepCheck_NoError)
493 aClosedShells.Append(aShell);
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
508 aLocalError = volumePropertiesGK(aShell, Props, aTol, IsUseSpan, CGFlag, IFlag,SkipShared);
509
510 if (aLocalError < 0)
511 return aLocalError;
512
513 anError += aLocalError;
514 }
515
516 } else
517 anError = volumePropertiesGK(S, Props, Eps, IsUseSpan, CGFlag, IFlag,SkipShared);
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
volumePropertiesGK(const TopoDS_Shape & theShape,GProp_GProps & theProps,const gp_Pln & thePln,const Standard_Real theTol,const Standard_Boolean IsUseSpan,const Standard_Boolean CGFlag,const Standard_Boolean IFlag,const Standard_Boolean SkipShared)529 static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape,
530 GProp_GProps &theProps,
531 const gp_Pln &thePln,
532 const Standard_Real theTol,
533 const Standard_Boolean IsUseSpan,
534 const Standard_Boolean CGFlag,
535 const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
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.;
549 TopTools_MapOfShape aFwdFMap;
550 TopTools_MapOfShape aRvsFMap;
551 TopLoc_Location aLocDummy;
552
553 aVProps.SetLocation(aLoc);
554
555 for (; anExp.More(); anExp.Next()) {
556 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
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 }
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
580 if (isFwd || isRvs){
581 aPropFace.Load(aFace);
582
583 Standard_Boolean IsNatRestr = (aFace.NbChildren () == 0);
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);
596 }
597 }
598
599 return anError;
600 }
601
602 //=======================================================================
603 //function : VolumeProperties
604 //purpose :
605 //=======================================================================
606
VolumePropertiesGK(const TopoDS_Shape & S,GProp_GProps & Props,const gp_Pln & thePln,const Standard_Real Eps,const Standard_Boolean OnlyClosed,const Standard_Boolean IsUseSpan,const Standard_Boolean CGFlag,const Standard_Boolean IFlag,const Standard_Boolean SkipShared)607 Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
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,
614 const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
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;
626 TopTools_MapOfShape aShMap;
627
628 anExp.Init(S, TopAbs_SHELL);
629
630 for (; anExp.More(); anExp.Next()) {
631 const TopoDS_Shape &aShell = anExp.Current();
632 if(SkipShared && !aShMap.Add(aShell))
633 {
634 continue;
635 }
636
637 BRepCheck_Shell aChecker(TopoDS::Shell(aShell));
638 BRepCheck_Status aStatus = aChecker.Closed(Standard_False);
639
640 if(aStatus == BRepCheck_NoError)
641 aClosedShells.Append(aShell);
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
656 aLocalError = volumePropertiesGK(aShell, Props, thePln, aTol, IsUseSpan, CGFlag, IFlag,SkipShared);
657
658 if (aLocalError < 0)
659 return aLocalError;
660
661 anError += aLocalError;
662 }
663 } else
664 anError = volumePropertiesGK(S, Props, thePln, Eps, IsUseSpan, CGFlag, IFlag,SkipShared);
665
666 Standard_Real vol = Props.Mass();
667 if(vol > Epsilon(1.)) anError /= vol;
668
669 return anError;
670 }
671