0024624: Lost word in license statement in source files
[occt.git] / src / BRepGProp / BRepGProp.cxx
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_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>
30 #ifdef DEB
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){
60   Standard_Integer i;
61 #ifdef DEB
62   Standard_Integer iErrorMax = 0;
63 #endif
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();
79       if(ErrorMax < Error) {
80         ErrorMax = Error;
81 #ifdef DEB
82         iErrorMax = i;
83 #endif
84       }
85     } else {
86       if(BF.NaturalRestriction()) G.Perform(BF);
87       else G.Perform(BF, BD);
88     }
89     Props.Add(G);
90 #ifdef DEB
91     if(AffichEps) cout<<"\n"<<i<<":\tEpsArea = "<< G.GetEpsilon();
92 #endif
93   }
94 #ifdef DEB
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){
120   Standard_Integer i;
121 #ifdef DEB
122   Standard_Integer iErrorMax = 0;
123 #endif
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();
140         if(ErrorMax < Error) {
141           ErrorMax = Error;
142 #ifdef DEB
143           iErrorMax = i;
144 #endif
145         }
146       }
147       else {
148         if(BF.NaturalRestriction()) G.Perform(BF);
149         else G.Perform(BF, BD);
150       }
151       Props.Add(G);
152 #ifdef DEB
153       if(AffichEps) cout<<"\n"<<i<<":\tEpsVolume = "<< G.GetEpsilon();
154 #endif
155     }
156   }
157 #ifdef DEB
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);
166   if(OnlyClosed){
167     TopExp_Explorer ex(S,TopAbs_SHELL);
168     for (; ex.More(); ex.Next()) {
169       const TopoDS_Shape& Sh = ex.Current();
170       if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0);
171     }
172   } else volumeProperties(S,Props,1.0);
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);
186   Standard_Integer i;
187 #ifdef DEB
188   Standard_Integer iErrorMax = 0;
189 #endif
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);
197         if(ErrorMax < Error) {
198           ErrorMax = Error;
199 #ifdef DEB
200           iErrorMax = i;
201 #endif
202         }
203       }
204     }
205   } else ErrorMax = volumeProperties(S,Props,Eps);
206 #ifdef DEB
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 }