edf6e81f6902e5ade7da54fbfb3aadecffbb249f
[occt.git] / src / BRepTest / BRepTest_GPropCommands.cxx
1 // Created on: 1994-02-18
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_Stream.hxx>
18 #include <BRepTest.hxx>
19 #include <Draw_Interpretor.hxx>
20 #include <Draw_Appli.hxx>
21 #include <DBRep.hxx>
22 #include <BRepGProp.hxx>
23 #include <TopoDS_Shape.hxx>
24 #include <GProp_PrincipalProps.hxx>
25 #include <gp_Ax2.hxx>
26 #include <gp_Ax3.hxx>
27
28 #include <Draw_Axis3D.hxx>
29 #include <Precision.hxx>
30 #include <OSD_Chronometer.hxx>
31 #include <Geom_Surface.hxx>
32 #include <DrawTrSurf.hxx>
33 #include <Geom_Plane.hxx>
34 #include <gp_Pln.hxx>
35
36 #ifdef _WIN32
37 Standard_IMPORT Draw_Viewer dout;
38 #endif
39
40
41 Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
42 {
43   if (n < 2) {
44     di << "Use: " << a[0] << " shape [epsilon] [c[losed]] [x y z] [-skip] [-full]\n";
45     di << "Compute properties of the shape\n";
46     di << "The epsilon, if given, defines relative precision of computation\n";
47     di << "The \"closed\" flag, if present, do computation only closed shells of the shape\n";
48     di << "The centroid coordinates will be put to DRAW variables x y z (if given)\n";
49     di << "Shared entities will be take in account only one time in the skip mode\n";
50     di << "All values are outputted with the full precision in the full mode.\n\n";
51     return 1;
52   }
53
54   Standard_Boolean isFullMode = Standard_False;
55   if (n >= 2 && strcmp(a[n-1], "-full") == 0)
56   {
57     isFullMode = Standard_True;
58     --n;
59   }
60   Standard_Boolean SkipShared = Standard_False;
61   if (n >= 2 && strcmp(a[n-1], "-skip") == 0)
62   {
63     SkipShared = Standard_True;
64     --n;
65   }
66
67   TopoDS_Shape S = DBRep::Get(a[1]);
68   if (S.IsNull()) return 0;
69
70   GProp_GProps G;
71
72   Standard_Boolean onlyClosed = Standard_False;
73   Standard_Real eps = 1.0;
74   Standard_Boolean witheps = Standard_False;
75   if((n > 2 && *a[2]=='c') || (n > 3 && *a[3]=='c')) onlyClosed = Standard_True;
76   if(n > 2 && *a[2]!='c' && n != 5) {eps = Draw::Atof (a[2]); witheps = Standard_True;}
77
78   if (witheps){
79     if (Abs(eps) < Precision::Angular()) return 2;
80     if (*a[0] == 'l')
81       BRepGProp::LinearProperties(S,G,SkipShared);
82     else if (*a[0] == 's')
83       eps = BRepGProp::SurfaceProperties(S,G,eps,SkipShared);
84     else 
85       eps = BRepGProp::VolumeProperties(S,G,eps,onlyClosed,SkipShared);
86   }
87   else {
88     if (*a[0] == 'l')
89       BRepGProp::LinearProperties(S,G,SkipShared);
90     else if (*a[0] == 's')
91       BRepGProp::SurfaceProperties(S,G,SkipShared);
92     else 
93       BRepGProp::VolumeProperties(S,G,onlyClosed,SkipShared);
94   }
95   
96   gp_Pnt P = G.CentreOfMass();
97   gp_Mat I = G.MatrixOfInertia();
98
99   if (n >= 5) {
100     Standard_Integer shift =  n - 5;
101     Draw::Set(a[shift+2],P.X());
102     Draw::Set(a[shift+3],P.Y());
103     Draw::Set(a[shift+4],P.Z());
104   }
105
106   GProp_PrincipalProps Pr = G.PrincipalProperties();
107   Standard_Real Ix,Iy,Iz;
108   Pr.Moments(Ix,Iy,Iz);
109
110   if (!isFullMode)
111   {
112     Standard_SStream aSStream1;
113     aSStream1 << "\n\n";
114     aSStream1 << "Mass : " << setw(15) << G.Mass() << "\n\n";
115     if(witheps && *a[0] != 'l') aSStream1 << "Relative error of mass computation : " <<  setw(15) << eps <<  "\n\n";
116   
117     aSStream1 << "Center of gravity : \n";
118     aSStream1 << "X = " << setw(15) << P.X() << "\n";
119     aSStream1 << "Y = " << setw(15) << P.Y() << "\n";
120     aSStream1 << "Z = " << setw(15) << P.Z() << "\n";
121     aSStream1 << "\n";
122   
123     aSStream1 << "Matrix of Inertia : \n";
124     aSStream1 << setw(15) << I(1,1);
125     aSStream1 << " " << setw(15) << I(1,2);
126     aSStream1 << " " << setw(15) << I(1,3) << "\n";
127     aSStream1 << setw(15) << I(2,1);
128     aSStream1 << " " << setw(15) << I(2,2);
129     aSStream1 << " " << setw(15) << I(2,3) << "\n";
130     aSStream1 << setw(15) << I(3,1);
131     aSStream1 << " " << setw(15) << I(3,2);
132     aSStream1 << " " << setw(15) << I(3,3) << "\n";
133     aSStream1 << "\n";
134     aSStream1 << ends;
135     di << aSStream1;
136
137     Standard_SStream aSStream2;
138     aSStream2 << "Moments : \n";
139     aSStream2 << "IX = " << setw(15) << Ix << "\n";
140     aSStream2 << "IY = " << setw(15) << Iy << "\n";
141     aSStream2 << "IZ = " << setw(15) << Iz << "\n";
142     aSStream2 << "\n";
143     aSStream2 << ends;
144     di << aSStream2;
145   }
146   else
147   {
148     di << "\n\nMass : " << G.Mass() << "\n\n";
149     if (witheps && *a[0] != 'l')
150     {
151       di << "Relative error of mass computation : " << eps <<  "\n\n";
152     }
153
154     di << "Center of gravity : \n";
155     di << "X = " << P.X() << "\n";
156     di << "Y = " << P.Y() << "\n";
157     di << "Z = " << P.Z() << "\n\n";
158
159     di << "Matrix of Inertia :\n";
160     di << I(1,1) << "    " << I(1,2) << "    " << I(1,3) << "\n";
161     di << I(2,1) << "    " << I(2,2) << "    " << I(2,3) << "\n";
162     di << I(3,1) << "    " << I(3,2) << "    " << I(3,3) << "\n\n";
163
164     di << "Moments :\n";
165     di << "IX = " << Ix << "\n";
166     di << "IY = " << Iy << "\n";
167     di << "IZ = " << Iz << "\n\n";
168   }
169
170   //if (n == 2) {  
171     gp_Ax2 axes(P,Pr.ThirdAxisOfInertia(),Pr.FirstAxisOfInertia());
172     
173     Handle(Draw_Axis3D) Dax = new Draw_Axis3D(axes,Draw_orange,30);
174     dout << Dax;
175   //}
176
177   return 0;
178 }
179
180
181 Standard_Integer vpropsgk(Draw_Interpretor& di, Standard_Integer n, const char** a)
182 {
183   if (n < 2) {
184     di << "Use: " << a[0] << " shape epsilon closed span mode [x y z] [-skip]\n";
185     di << "Compute properties of the shape\n";
186     di << "The epsilon defines relative precision of computation\n";
187     di << "The \"closed\" flag, if equal 1, causes computation only closed shells of the shape\n";
188     di << "The \"span\" flag, if equal 1, says that computation is performed on spans\n";
189     di << "      This option makes effect only for BSpline surfaces.\n";
190     di << "mode can be 0 - only volume calculations\n";
191     di << "            1 - volume and gravity center\n";
192     di << "            2 - volume, gravity center and matrix of inertia\n";
193     di << "The centroid coordinates will be put to DRAW variables x y z (if given)\n\n";
194     return 1;
195   }
196
197   if ( n > 2 && n < 6) {
198     di << "Wrong arguments\n";
199     return 1;
200   }
201
202   TopoDS_Shape S = DBRep::Get(a[1]);
203   if (S.IsNull()) return 0;
204
205   GProp_GProps G;
206   Standard_Boolean SkipShared = Standard_False;
207   if (n >= 2 && strcmp(a[n-1], "-skip") == 0)
208   {
209     SkipShared = Standard_True;
210     --n;
211   }
212
213   Standard_Boolean onlyClosed  = Standard_False;
214   Standard_Boolean isUseSpan   = Standard_False;
215   Standard_Boolean CGFlag = Standard_False;
216   Standard_Boolean IFlag = Standard_False;
217   Standard_Real    eps         = 1.e-3;
218 //Standard_Real    aDefaultTol = 1.e-3;
219   Standard_Integer mode = 0;
220
221   eps = Draw::Atof(a[2]);
222   mode = Draw::Atoi(a[3]);
223   if(mode > 0) onlyClosed = Standard_True;
224   mode = Draw::Atoi(a[4]);
225   if(mode > 0) isUseSpan = Standard_True;
226
227   mode = Draw::Atoi(a[5]);
228   if(mode == 1 || mode == 3) CGFlag = Standard_True;
229   if(mode == 2 || mode == 3) IFlag = Standard_True;
230
231   //OSD_Chronometer aChrono;
232
233   //aChrono.Reset();
234   //aChrono.Start();
235   eps = BRepGProp::VolumePropertiesGK(S, G, eps, onlyClosed, isUseSpan, CGFlag, IFlag, SkipShared);
236   //aChrono.Stop();
237
238   Standard_SStream aSStream0;
239   Standard_Integer anOutWidth = 24;
240
241   aSStream0.precision(15);
242   aSStream0 << "\n\n";
243   aSStream0 << "Mass : " << setw(anOutWidth) << G.Mass() << "\n\n";
244   aSStream0 << "Relative error of mass computation : " <<  setw(anOutWidth) << eps <<  "\n\n";
245   aSStream0 << ends;
246   di << aSStream0;
247
248   if(CGFlag || IFlag) {
249     Standard_SStream aSStream1;
250     gp_Pnt P = G.CentreOfMass();
251     if (n > 6) {
252       Draw::Set(a[6],P.X());
253     }
254     if (n > 7) {
255       Draw::Set(a[7],P.Y());
256     }
257     if (n > 8) {
258       Draw::Set(a[8],P.Z());
259     }
260   
261     aSStream1.precision(15);
262     aSStream1 << "Center of gravity : \n";
263     aSStream1 << "X = " << setw(anOutWidth) << P.X() << "\n";
264     aSStream1 << "Y = " << setw(anOutWidth) << P.Y() << "\n";
265     aSStream1 << "Z = " << setw(anOutWidth) << P.Z() << "\n";
266     aSStream1 << "\n";
267  
268     if(IFlag) {
269       gp_Mat I = G.MatrixOfInertia();
270
271       aSStream1 << "Matrix of Inertia : \n";
272       aSStream1 << setw(anOutWidth) << I(1,1);
273       aSStream1 << " " << setw(anOutWidth) << I(1,2);
274       aSStream1 << " " << setw(anOutWidth) << I(1,3) << "\n";
275       aSStream1 << setw(anOutWidth) << I(2,1);
276       aSStream1 << " " << setw(anOutWidth) << I(2,2);
277       aSStream1 << " " << setw(anOutWidth) << I(2,3) << "\n";
278       aSStream1 << setw(anOutWidth) << I(3,1);
279       aSStream1 << " " << setw(anOutWidth) << I(3,2);
280       aSStream1 << " " << setw(anOutWidth) << I(3,3) << "\n";
281       aSStream1 << "\n";
282     }
283     aSStream1 << ends;
284     di << aSStream1;
285   }
286
287   if(IFlag) {
288
289     GProp_PrincipalProps Pr = G.PrincipalProperties();
290
291     Standard_Real Ix,Iy,Iz;
292     Pr.Moments(Ix,Iy,Iz);
293     gp_Pnt P = G.CentreOfMass();
294   
295     Standard_SStream aSStream2;
296
297     aSStream2.precision(15);
298     aSStream2 << "Moments : \n";
299     aSStream2 << "IX = " << setw(anOutWidth) << Ix << "\n";
300     aSStream2 << "IY = " << setw(anOutWidth) << Iy << "\n";
301     aSStream2 << "IZ = " << setw(anOutWidth) << Iz << "\n";
302     aSStream2 << "\n";
303     aSStream2 << "\n";
304     aSStream2 << ends;
305     di << aSStream2;
306
307     gp_Ax2 axes(P,Pr.ThirdAxisOfInertia(),Pr.FirstAxisOfInertia());
308     
309     Handle(Draw_Axis3D) Dax = new Draw_Axis3D(axes,Draw_orange,30);
310     dout << Dax;
311   }
312   return 0;
313 }
314
315
316 //=======================================================================
317 //function : GPropCommands
318 //purpose  : 
319 //=======================================================================
320
321 void  BRepTest::GPropCommands(Draw_Interpretor& theCommands)
322 {
323   static Standard_Boolean done = Standard_False;
324   if (done) return;
325   done = Standard_True;
326
327   DBRep::BasicCommands(theCommands);
328
329   const char* g = "Global properties";
330   theCommands.Add("lprops",
331     "lprops name [x y z] [-skip] [-full] : compute linear properties",
332     __FILE__, props, g);
333   theCommands.Add("sprops", "sprops name [epsilon] [x y z] [-skip] [-full] :\n"
334 "  compute surfacic properties", __FILE__, props, g);
335   theCommands.Add("vprops", "vprops name [epsilon] [c[losed]] [x y z] [-skip] [-full] :\n"
336 "  compute volumic properties", __FILE__, props, g);
337
338   theCommands.Add("vpropsgk",
339                   "vpropsgk name epsilon closed span mode [x y z] [-skip] : compute volumic properties",
340                   __FILE__,
341                   vpropsgk,
342                   g);
343 }