0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / BRepGProp / BRepGProp.cxx
CommitLineData
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
36static Standard_Integer AffichEps = 0;
37#endif
38
39static 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
48void 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
64static 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}
96void 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}
103Standard_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
116static 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}
151void 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
170Standard_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
202static 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
254Standard_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
318static 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
371Standard_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}