0028643: Coding rules - eliminate GCC compiler warnings -Wmisleading-indentation
[occt.git] / src / QABugs / QABugs_13.cxx
1 // Created on: 2002-05-16
2 // Created by: QA Admin
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <QABugs.hxx>
17
18 #include <Draw.hxx>
19 #include <Draw_Interpretor.hxx>
20 #include <DBRep.hxx>
21 #include <DrawTrSurf.hxx>
22 #include <AIS_InteractiveContext.hxx>
23 #include <ViewerTest.hxx>
24 #include <AIS_Shape.hxx>
25 #include <TopoDS_Shape.hxx>
26
27 #include <gp_Ax2.hxx>
28 #include <gp_Circ.hxx>
29 #include <gp_Pln.hxx>
30 #include <BRep_Builder.hxx>
31 #include <BRepBuilderAPI_MakeWire.hxx>
32 #include <BRepBuilderAPI_MakeEdge.hxx>
33 #include <BRepBuilderAPI_MakeFace.hxx>
34 #include <BRepCheck_Analyzer.hxx>
35 #include <BRepGProp.hxx>
36 #include <BRepOffsetAPI_MakePipeShell.hxx>
37 #include <GC_MakeArcOfCircle.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <Geom_Plane.hxx>
40 #include <Law_Linear.hxx>
41 #include <TopoDS.hxx>
42 #include <TopoDS_Shell.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Solid.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Wire.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <GProp_GProps.hxx>
49 #include <Standard_ErrorHandler.hxx>
50
51 //=======================================================================
52 //function :  OCC332
53 //purpose  : 
54 //=======================================================================
55 static Standard_Integer OCC332bug (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
56 {
57   // Used to Display Geometry or Topolgy
58   char name[255];
59   Standard_Boolean check = Standard_True;
60
61   // Set default arguments
62   double wall_thickness = 10.0;
63   double dia1 = 80.0;
64   double dia2 = 100.0;
65   double length = 400.0;
66   double major_radius = 280.0;
67
68   // Convert arguments
69   if (argc>1) wall_thickness = Draw::Atof(argv[1]);
70   if (argc>2) dia1 = Draw::Atof(argv[2]);
71   if (argc>3) dia2 = Draw::Atof(argv[3]);
72   if (argc>4) major_radius = Draw::Atof(argv[4]);
73   if (argc>5) length = Draw::Atof(argv[5]);
74   double bend_angle = length/major_radius;
75
76   //if ((bend_angle >= M_PI)) {
77   if ((bend_angle >= M_PI)) {
78     di << "The arguments are invalid.\n";
79     return 1;
80   }
81   di << "creating the shape for a bent tube\n";
82
83   double radius_l = dia1/2.0;
84   double radius_r = dia2/2.0;
85
86   // SUPPORT:
87   // 1. There is no need to normalize the direction - it's done automatically
88   //gp_Ax2 origin(gp_Pnt(5000.0,-300.0, 1000.0),
89                 //gp_Dir(0.0, -1.0/sqrt(2.0), -1.0/sqrt(2.0)));
90   gp_Ax2 origin(gp_Pnt(5000.0,-300.0,1000.0),gp_Dir(0.0,-1.0,-1.0));
91
92   TopoDS_Face myFace;
93   TopoDS_Shape myShape, gasSolid;
94   TopoDS_Solid wallSolid;
95
96   // Construct a circle for the first face, on the xy-plane at the origin
97   gp_Pln circ1Plane(origin.Location(), origin.Direction());
98   gp_Circ faceCircle(origin, radius_l);
99   gp_Circ outFaceCircle(origin, radius_l+wall_thickness);
100
101   // Construct center for a circle to be the spine of
102   // revolution, on the xz-plane at x=major_radius
103   gp_Pnt circ_center = origin.Location().Translated(major_radius*origin.XDirection());
104
105   // This point will be the center of the second face.
106   // SUPPORT:
107   // - There is no need in this point - we'll use angle instead.
108   //gp_Pnt endPoint = origin.Location();
109   //endPoint.Translate(major_radius*(1.0-cos(bend_angle))*origin.XDirection()) ;
110   //endPoint.Translate((-major_radius*sin(bend_angle))*origin.Direction());
111
112   // Construct the plane for the second face to sit on.
113   // SUPPORT:
114   // - It is better to use rotation instead of explicit calculations
115   //gp_Pln circ2Plane = gce_MakePln(circ_center, endPoint,
116   //                              endPoint.Translated(major_radius*origin.YDirection())
117   //                              ).Value();
118   gp_Ax1 circ_axis(circ_center,origin.YDirection());
119   gp_Pln circ2Plane = circ1Plane.Rotated(circ_axis,bend_angle);
120
121   // The circle used for the spine.
122   // SUPPORT:
123   // - Use direction (-X) instead of (X) to obtain correct right-handed system.
124   //   It is very important to maintain correct orientation between spine
125   //   and circles axes.
126   //gp_Ax2 spineAxis(circ_center, origin.YDirection(), origin.XDirection());
127   gp_Ax2 spineAxis(circ_center, origin.YDirection(), -origin.XDirection());
128   gp_Circ circle(spineAxis, major_radius);
129
130   // SUPPORT:
131   // - There is no need to create 2nd circles - they will be created by MakePipeShell.
132   //gp_Ax2 circ2axis(endPoint, circ2Plane.Axis().Direction(), origin.YDirection());
133   //gp_Circ faceCircle2(circ2axis,radius_r);
134   //gp_Circ outFaceCircle2(circ2axis,radius_r+wall_thickness);
135
136   TopoDS_Edge E1 = BRepBuilderAPI_MakeEdge(faceCircle);
137   TopoDS_Wire Wire1_ = BRepBuilderAPI_MakeWire(E1).Wire();
138   
139   // Create the face at the near end for the wall solid, an annular ring.
140   TopoDS_Edge Eout1 = BRepBuilderAPI_MakeEdge(outFaceCircle);
141   TopoDS_Wire outerWire1_ = BRepBuilderAPI_MakeWire(Eout1).Wire();
142
143   // SUPPORT:
144   // - There is no need to create 2nd circles -
145   //   they will be created by MakePipeShell
146   //TopoDS_Edge E2 = BRepBuilderAPI_MakeEdge(faceCircle2);
147   //TopoDS_Wire Wire2_ = BRepBuilderAPI_MakeWire(E2).Wire();
148   
149   // Create the face at the far end for the wall solid, an annular ring.
150   // SUPPORT:
151   // - There is no need to create 2nd circles -
152   //   they will be created by MakePipeShell
153   //TopoDS_Edge Eout2 = BRepBuilderAPI_MakeEdge(outFaceCircle2);
154   //TopoDS_Wire outerWire2_ = BRepBuilderAPI_MakeWire(Eout2).Wire();
155
156   // SUPPORT:
157   // - It is better to use bend angle calculated above
158   //Handle(Geom_Curve) SpineCurve = GC_MakeArcOfCircle(circle,
159   //                                                 endPoint,
160   //                                                 origin.Location(),
161   //                                                 Standard_True).Value();
162   Handle(Geom_Curve) SpineCurve (GC_MakeArcOfCircle (circle, 0.0, bend_angle, Standard_True).Value());
163
164   // SUPPORT:
165   // - Use correct formula for scaling laws
166   Handle(Law_Linear) myLaw1 = new Law_Linear();
167   Handle(Law_Linear) myLaw2 = new Law_Linear();
168   //if ((radius_r - radius_l) < Precision::Confusion())
169   //{
170     //myLaw1->Set(SpineCurve->FirstParameter(), 1.0,
171                 //SpineCurve->LastParameter(), 1.0);
172     //myLaw2->Set(SpineCurve->FirstParameter(), 1.0,
173                 //SpineCurve->LastParameter(), 1.0);
174   //}
175   //else
176   //{
177     //myLaw1->Set(SpineCurve->FirstParameter(), radius_r/(radius_r-radius_l),
178                 //SpineCurve->LastParameter(), 1.0);
179     //myLaw2->Set(SpineCurve->FirstParameter(), (radius_r+wall_thickness)/(radius_r-radius_l),
180                 //SpineCurve->LastParameter(), 1.0);
181   //}
182   myLaw1->Set(SpineCurve->FirstParameter(),1.0,
183               SpineCurve->LastParameter(),radius_r/radius_l);
184   myLaw2->Set(SpineCurve->FirstParameter(),1.0,
185               SpineCurve->LastParameter(),(radius_r+wall_thickness)/(radius_l+wall_thickness));
186
187   BRepBuilderAPI_MakeFace mkFace;
188
189   BRepBuilderAPI_MakeEdge mkEdge;
190
191   mkEdge.Init(SpineCurve);
192   if (!mkEdge.IsDone()) return 0;
193   TopoDS_Wire SpineWire = BRepBuilderAPI_MakeWire(mkEdge.Edge()).Wire();
194
195   Sprintf (name,"SpineWire");
196   DBRep::Set(name,SpineWire);
197
198   Sprintf (name,"Wire1_");
199   DBRep::Set(name,Wire1_);
200
201   Sprintf (name,"outerWire1_");
202   DBRep::Set(name,outerWire1_);
203
204   // SUPPORT:
205   // - There is no need to create 2nd circles
206   //Sprintf (name,"Wire2_");
207   //DBRep::Set(name,Wire2_);
208   //Sprintf (name,"outerWire2_");
209   //DBRep::Set(name,outerWire2_);
210
211   di.Eval("fit");
212
213   // SUPPORT:
214   // - There is no need in these vertices
215   //TopoDS_Vertex Location1, Location2;
216   //TopExp::Vertices(SpineWire, Location1, Location2);
217
218   // Make inner pipe shell
219   BRepOffsetAPI_MakePipeShell mkPipe1(SpineWire);
220   mkPipe1.SetTolerance(1.0e-8,1.0e-8,1.0e-6);
221   //mkPipe1.SetTransitionMode(BRepBuilderAPI_Transformed); // Default mode !!
222   mkPipe1.SetLaw(Wire1_, myLaw1/*, Location2*/, Standard_False, Standard_False);
223   mkPipe1.Build();
224   if (!mkPipe1.IsDone()) return 0;
225
226   // Make outer pipe shell
227   BRepOffsetAPI_MakePipeShell mkPipe2(SpineWire);
228   mkPipe2.SetTolerance(1.0e-8,1.0e-8,1.0e-6);
229   //mkPipe2.SetTransitionMode(BRepBuilderAPI_Transformed); // Default mode !!
230   mkPipe2.SetLaw(outerWire1_, myLaw2/*, Location2*/, Standard_False, Standard_False);
231   mkPipe2.Build();
232   if (!mkPipe2.IsDone()) return 0;
233
234   // Make face for first opening
235   Handle(Geom_Plane) Plane1 = new Geom_Plane(circ1Plane);
236   mkFace.Init(Plane1,Standard_False,Precision::Confusion());
237   // SUPPORT:
238   // - Use wires created by MakePipeShell
239   //mkFace.Add(TopoDS::Wire(outerWire1_));
240   //mkFace.Add(TopoDS::Wire(Wire1_.Reversed()));
241   mkFace.Add(TopoDS::Wire(mkPipe2.FirstShape()));
242   mkFace.Add(TopoDS::Wire(mkPipe1.FirstShape().Reversed()));
243   if (!mkFace.IsDone()) return 0;
244   TopoDS_Face Face1 = mkFace.Face();
245
246   // Make face for second opening
247   Handle(Geom_Plane) Plane2 = new Geom_Plane(circ2Plane);
248   mkFace.Init(Plane2,Standard_False,Precision::Confusion());
249   // SUPPORT:
250   // - Use wires created by MakePipeShell
251   //mkFace.Add(TopoDS::Wire(outerWire2_));
252   //mkFace.Add(TopoDS::Wire(Wire2_.Reversed()));
253   mkFace.Add(TopoDS::Wire(mkPipe2.LastShape()));
254   mkFace.Add(TopoDS::Wire(mkPipe1.LastShape().Reversed()));
255   if (!mkFace.IsDone()) return 0;
256   TopoDS_Face Face2 = mkFace.Face();
257
258   // Make tube
259   TopoDS_Shell TubeShell;
260   BRep_Builder B;
261   B.MakeShell(TubeShell);
262   TopExp_Explorer getFaces;
263   TopoDS_Face test_face;
264   getFaces.Init(mkPipe1.Shape(), TopAbs_FACE);
265   // SUPPORT:
266   // - In our case there should be only 1 pipe face
267   //while (getFaces.More())
268   //  {
269   //    test_face = TopoDS::Face(getFaces.Current());
270   //    Handle(Geom_Surface) S = BRep_Tool::Surface(test_face); 
271   //    GeomLib_IsPlanarSurface IsPl(S);
272   //    if (!IsPl.IsPlanar()) {
273   //    B.Add(TubeShell,getFaces.Current().Reversed());
274   //    }
275   //    getFaces.Next();
276   //  }
277   if (getFaces.More())
278     B.Add(TubeShell,getFaces.Current().Reversed());
279
280   // Grab the gas solid now that we've extracted the faces.
281   mkPipe1.MakeSolid();
282   gasSolid = mkPipe1.Shape();
283
284   Sprintf (name,"gasSolid_");
285   DBRep::Set(name,gasSolid);
286
287   //getFaces.Clear();
288   getFaces.Init(mkPipe2.Shape(), TopAbs_FACE);
289   // SUPPORT:
290   // - In our case there should be only 1 pipe face
291   //while (getFaces.More())
292   //  {
293   //    B.Add(TubeShell,getFaces.Current());
294   //    getFaces.Next();
295   //  }
296   if (getFaces.More())
297     B.Add(TubeShell,getFaces.Current());
298
299   B.Add(TubeShell,Face1.Reversed());
300   B.Add(TubeShell,Face2);
301   TubeShell.Closed (BRep_Tool::IsClosed (TubeShell));
302
303   B.MakeSolid(wallSolid);
304   B.Add(wallSolid,TubeShell);
305
306   Sprintf (name,"wallSolid_");
307   DBRep::Set(name,wallSolid);
308
309   // Now calculated the volume of the outside tube.
310   GProp_GProps gprops;
311   BRepGProp::VolumeProperties(wallSolid, gprops);
312   di << "The wallSolid's volume is: " << gprops.Mass() << "\n";
313
314   if (check) {
315     if (!(BRepCheck_Analyzer(wallSolid).IsValid()))
316       di << "The TopoDS_Solid was checked, and it was invalid!\n";
317     else
318       di << "The TopoDS_Solid was checked, and it was valid.\n";
319     if (!wallSolid.Closed())
320       di << "The TopoDS_Solid is not closed!\n";
321     else
322       di << "The TopoDS_Solid is closed.\n";
323     if (!wallSolid.Checked())
324       di << "The TopoDS_Solid is not checked!\n";
325     else
326       di << "The TopoDS_Solid has been checked.\n";
327     if (wallSolid.Infinite())
328       di << "The TopoDS_Solid is infinite!\n";
329     else
330       di << "The TopoDS_Solid is finite.\n";
331   }
332
333   di << "The result is a ";
334   // Check to see if we have a solid
335   switch (wallSolid.ShapeType()) {
336   case (TopAbs_COMPOUND):
337     di << "TopAbs_COMPOUND\n";
338     break;
339   case (TopAbs_COMPSOLID):
340     di << "TopAbs_COMPSOLID\n";
341     break;
342   case (TopAbs_SOLID):
343     di << "TopAbs_SOLID\n";
344     break;
345   case (TopAbs_SHELL):
346     di << "TopAbs_SHELL\n";
347     break;
348   case (TopAbs_FACE):
349     di << "TopAbs_FACE\n";
350     break;
351   case (TopAbs_WIRE):
352     di << "TopAbs_WIRE\n";
353     break;
354   case (TopAbs_EDGE):
355     di << "TopAbs_EDGE\n";
356     break;
357   case (TopAbs_VERTEX):
358     di << "TopAbs_VERTEX\n";
359     break;
360   case (TopAbs_SHAPE):
361     di << "TopAbs_SHAPE\n";
362   }
363   di << "Can we turn it into a solid? ";
364   try {
365     OCC_CATCH_SIGNALS
366     di << " yes\n";
367   }
368   catch (Standard_TypeMismatch) {
369     di << " no\n";
370   }
371
372   getFaces.Clear();
373   getFaces.Init(wallSolid, TopAbs_FACE);
374   int i =0;
375   while (getFaces.More())
376     {
377       i++;
378       Sprintf(name,"Face%d",i);
379       di << "Face named " << name << "\n";
380       DBRep::Set(name,getFaces.Current());
381       getFaces.Next();
382     }
383
384   return 0;
385 }
386
387 #include <gce_MakePln.hxx>
388 #include <TopExp.hxx>
389 #include <BRepOffsetAPI_Sewing.hxx>
390 #include <BRepAlgoAPI_Fuse.hxx>
391
392 //=======================================================================
393 //function :  OCC544
394 //purpose  : 
395 //=======================================================================
396 static Standard_Integer OCC544 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
397 {
398   if(argc > 6) {
399     di << "Usage : " << argv[0] << " [[[[[wT [[[[d1 [[[d2 [[R [length]]]]]\n";
400     return 1;
401   }
402
403   // Used to Display Geometry or Topolgy
404   char name[255];
405   Standard_Boolean check = Standard_True;
406
407   // Set default arguments
408   double radius_l = 20.0;
409   double radius_r = 80.0;
410   // mkv 15.07.03 double bend_angle = M_PI/2.0;
411   double bend_angle = M_PI/2.0;
412
413   double major_rad = 280.0;
414   double wall_thickness = 10.0;
415                     
416
417   // Convert arguments
418   if (argc>1) radius_l = Draw::Atof(argv[1]);
419   if (argc>2) radius_r = Draw::Atof(argv[2]);
420   if (argc>3) bend_angle = Draw::Atof(argv[3]);
421   if (argc>4) major_rad = Draw::Atof(argv[4]);
422   if (argc>5) wall_thickness = Draw::Atof(argv[5]);
423
424   // mkv 15.07.03 if ((bend_angle >= 2.0*M_PI)) {
425   if ((bend_angle >= 2.0*M_PI)) {
426     di << "The arguments are invalid.\n";
427     return 1;
428   }
429   di << "creating the shape for a bent tube\n";
430  
431   gp_Ax2 origin(gp_Pnt(500.0,-300.0, 100.0),
432                 gp_Dir(0.0, -1.0/sqrt(2.0), -1.0/sqrt(2.0)));
433
434   TopoDS_Face firstFace, lastFace;
435   TopoDS_Solid wallSolid, myShape;
436   // Construct a circle for the first face, on the xy-plane at the origin
437   gp_Pln circ1Plane(origin.Location(), origin.Direction());
438   gp_Circ faceCircle(origin, radius_l);
439   gp_Circ outFaceCircle(origin, radius_l+wall_thickness);
440
441   // Construct center for a circle to be the spine of
442   // revolution, on the xz-plane at x=major_rad
443   gp_Pnt circ_center = origin.Location().Translated(
444                                                     major_rad*origin.XDirection()
445                                                     );
446
447   // This point will be the center of the second face.
448   gp_Pnt endPoint = origin.Location();
449   endPoint.Translate(major_rad*(1.0-cos(bend_angle))*origin.XDirection()) ;
450   endPoint.Translate((-major_rad*sin(bend_angle))*origin.Direction());
451
452   // Construct the plane for the second face to sit on.
453   gp_Pln circ2Plane = gce_MakePln(circ_center, endPoint,
454                                   endPoint.Translated(major_rad*origin.YDirection())
455                                   ).Value();
456
457   // The circle used for the spine.
458   gp_Ax2 spineAxis(circ_center, origin.YDirection(), origin.XDirection());
459   gp_Circ circle(spineAxis, major_rad);
460
461   gp_Ax2 circ2axis(endPoint, circ2Plane.Axis().Direction(), origin.YDirection());
462   gp_Circ faceCircle2(circ2axis,radius_r);
463   gp_Circ outFaceCircle2(circ2axis,radius_r+wall_thickness);
464
465   TopoDS_Edge E1_1 = BRepBuilderAPI_MakeEdge(faceCircle, 0, M_PI);
466   TopoDS_Edge E1_2 = BRepBuilderAPI_MakeEdge(faceCircle, M_PI, 2.*M_PI);
467   TopoDS_Wire Wire1_ = BRepBuilderAPI_MakeWire(E1_1, E1_2);
468   
469   // Create the face at the near end for the wall solid, an annular ring.
470   TopoDS_Edge Eout1_1 = BRepBuilderAPI_MakeEdge(outFaceCircle, 0, M_PI);
471   TopoDS_Edge Eout1_2 = BRepBuilderAPI_MakeEdge(outFaceCircle, M_PI, 2.*M_PI);
472   TopoDS_Wire outerWire1_ = BRepBuilderAPI_MakeWire(Eout1_1, Eout1_2);
473  
474   TopoDS_Edge E2_1 = BRepBuilderAPI_MakeEdge(faceCircle2, 0, M_PI);
475   TopoDS_Edge E2_2 = BRepBuilderAPI_MakeEdge(faceCircle2, M_PI, 2.*M_PI);
476   TopoDS_Wire Wire2_ = BRepBuilderAPI_MakeWire(E2_1, E2_2);
477   
478   // Create the face at the far end for the wall solid, an annular ring.
479   TopoDS_Edge Eout2_1 = BRepBuilderAPI_MakeEdge(outFaceCircle2, 0, M_PI);
480   TopoDS_Edge Eout2_2 = BRepBuilderAPI_MakeEdge(outFaceCircle2, M_PI, 2.*M_PI);
481   TopoDS_Wire outerWire2_ = BRepBuilderAPI_MakeWire(Eout2_1, Eout2_2);
482
483   BRepBuilderAPI_MakeFace mkFace;
484
485   Handle(Geom_Curve) SpineCurve (GC_MakeArcOfCircle (circle, endPoint, origin.Location(), Standard_True).Value());
486   Handle(Law_Linear) myLaw = new Law_Linear();
487   Handle(Law_Linear) myLaw2 = new Law_Linear();
488
489   myLaw->Set(SpineCurve->FirstParameter(),
490              radius_r/radius_l,
491              SpineCurve->LastParameter(),
492              1.0);
493
494   myLaw2->Set(SpineCurve->FirstParameter(),
495               (radius_r+wall_thickness)/(radius_l+wall_thickness),
496               SpineCurve->LastParameter(),
497               1.0);
498
499   di << "SpineCurve->FirstParameter() is " << SpineCurve->FirstParameter() << "\n";
500   di << "SpineCurve->LastParameter() is " << SpineCurve->LastParameter() << "\n";
501   di << "Law1 Value at FirstParameter() is " << myLaw->Value(SpineCurve->FirstParameter()) << "\n";
502   di << "Law1 Value at LastParameter() is " << myLaw->Value(SpineCurve->LastParameter()) << "\n";
503   di << "radius_r / radius_l is " << radius_r/radius_l << "\n";
504
505   BRepBuilderAPI_MakeEdge mkEdge;
506
507   mkEdge.Init(SpineCurve);
508   if (!mkEdge.IsDone()) 
509     return 1;
510   TopoDS_Wire SpineWire = BRepBuilderAPI_MakeWire(mkEdge.Edge()).Wire();
511
512   Sprintf (name,"SpineWire");
513   DBRep::Set(name,SpineWire);
514
515   Sprintf (name,"Wire1_");
516   DBRep::Set(name,Wire1_);
517
518   Sprintf (name,"outerWire1_");
519   DBRep::Set(name,outerWire1_);
520
521   Sprintf (name,"Wire2_");
522   DBRep::Set(name,Wire2_);
523
524   Sprintf (name,"outerWire2_");
525   DBRep::Set(name,outerWire2_);
526
527   di.Eval("fit");
528
529   TopoDS_Vertex Location1, Location2;
530
531   TopExp::Vertices(SpineWire, Location2, Location1);
532
533   Sprintf (name,"Location1");
534   DBRep::Set(name,Location1);
535
536   Sprintf (name,"Location2");
537   DBRep::Set(name,Location2);
538
539   // Make inner pipe shell
540   BRepOffsetAPI_MakePipeShell mkPipe1(SpineWire);
541   mkPipe1.SetTolerance(1.0e-8,1.0e-8,1.0e-6);
542   mkPipe1.SetTransitionMode(BRepBuilderAPI_Transformed);
543   mkPipe1.SetMode(Standard_False);
544   mkPipe1.SetLaw(Wire1_, myLaw, Location1, Standard_False, Standard_False);
545   mkPipe1.Build();
546   if (!mkPipe1.IsDone()) 
547     return 1;
548
549   // Make outer pipe shell
550   BRepOffsetAPI_MakePipeShell mkPipe2(SpineWire);
551   mkPipe2.SetTolerance(1.0e-8,1.0e-8,1.0e-6);
552   mkPipe2.SetTransitionMode(BRepBuilderAPI_Transformed);
553   mkPipe2.SetMode(Standard_False);
554   mkPipe2.SetLaw(outerWire1_, myLaw2, Location1, Standard_False, Standard_False);
555  mkPipe2.Build();
556   if (!mkPipe2.IsDone()) 
557     return 1;
558
559 //    Sprintf(name,"w1-first");
560 //    DBRep::Set(name,mkPipe1.FirstShape());
561
562 //    Sprintf(name,"w1-last");
563 //    DBRep::Set(name,mkPipe1.LastShape());
564
565 //    Sprintf(name,"w2-first");
566 //    DBRep::Set(name,mkPipe2.FirstShape());
567
568 //    Sprintf(name,"w2-last");
569 //    DBRep::Set(name,mkPipe2.LastShape());
570
571   BRepOffsetAPI_Sewing SewIt(1.0e-4);
572
573   // Make tube
574   TopExp_Explorer getFaces;
575   TopoDS_Face test_face;
576   getFaces.Init(mkPipe1.Shape(), TopAbs_FACE);
577   while (getFaces.More())
578     {
579       SewIt.Add(getFaces.Current().Reversed());
580       getFaces.Next();
581     }
582
583   // Make face for first opening
584   Handle(Geom_Plane) Plane1 = new Geom_Plane(circ1Plane);
585   mkFace.Init(Plane1,Standard_False,Precision::Confusion());
586   mkFace.Add(TopoDS::Wire(outerWire1_));
587   mkFace.Add(TopoDS::Wire(Wire1_.Reversed()));
588   if (!mkFace.IsDone()) 
589     return 1;
590   TopoDS_Face Face1 = mkFace.Face();
591
592   // Make face for second opening
593   Handle(Geom_Plane) Plane2 = new Geom_Plane(circ2Plane);
594   mkFace.Init(Plane2,Standard_False,Precision::Confusion());
595   mkFace.Add(TopoDS::Wire(outerWire2_));
596   mkFace.Add(TopoDS::Wire(Wire2_.Reversed()));
597   if (!mkFace.IsDone()) 
598     return 1;
599   TopoDS_Face Face2 = mkFace.Face();
600
601   // Grab the gas solid now that we've extracted the faces.
602   mkPipe1.MakeSolid();
603   myShape = TopoDS::Solid(mkPipe1.Shape());
604
605   getFaces.Clear();
606   getFaces.Init(mkPipe2.Shape(), TopAbs_FACE);
607   while (getFaces.More())
608     {
609       SewIt.Add(getFaces.Current());
610       getFaces.Next();
611     }
612
613   SewIt.Add(Face1.Reversed());
614   SewIt.Add(Face2);
615
616   SewIt.Perform();
617
618   di << "The result of the Sewing operation is a ";
619   // Check to see if we have a solid
620   switch (SewIt.SewedShape().ShapeType()) {
621   case (TopAbs_COMPOUND):
622     di << "TopAbs_COMPOUND\n";
623     break;
624   case (TopAbs_COMPSOLID):
625     di << "TopAbs_COMPSOLID\n";
626     break;
627   case (TopAbs_SOLID):
628     di << "TopAbs_SOLID\n";
629     break;
630   case (TopAbs_SHELL):
631     di << "TopAbs_SHELL\n";
632     break;
633   case (TopAbs_FACE):
634     di << "TopAbs_FACE\n";
635     break;
636   case (TopAbs_WIRE):
637     di << "TopAbs_WIRE\n";
638     break;
639   case (TopAbs_EDGE):
640     di << "TopAbs_EDGE\n";
641     break;
642   case (TopAbs_VERTEX):
643     di << "TopAbs_VERTEX\n";
644     break;
645   case (TopAbs_SHAPE):
646     di << "TopAbs_SHAPE\n";
647   }
648
649   BRep_Builder B;
650
651   TopoDS_Shell TubeShell;
652   di << "Can we turn it into a shell? ";
653   try {
654     OCC_CATCH_SIGNALS
655     TubeShell = TopoDS::Shell(SewIt.SewedShape());
656     B.MakeSolid(wallSolid);
657     B.Add(wallSolid,TubeShell);
658     di << " yes\n";
659   }
660   catch (Standard_TypeMismatch) {
661     di << "Can't convert to shell...\n";
662     TopExp_Explorer getSol;
663     getSol.Init(SewIt.SewedShape(), TopAbs_SOLID);
664     if (getSol.More()) {
665       di << "First solid found in compound\n";
666       wallSolid = TopoDS::Solid(getSol.Current());
667       TopoDS_Solid test_solid;
668       while (getSol.More())
669       {
670         di << "Next solid found in compound\n";
671         getSol.Next();
672         test_solid = TopoDS::Solid(getSol.Current());
673
674         di << "BRepAlgoAPI_Fuse fuser(test_solid, wallSolid)\n";
675         BRepAlgoAPI_Fuse fuser(test_solid, wallSolid);
676         TopExp_Explorer aExpS(fuser.Shape(), TopAbs_SOLID);
677         if (aExpS.More()) {
678           wallSolid = TopoDS::Solid(aExpS.Current());
679         }
680       }
681     } else {
682       // Let's see if we can extract shells instead of solids.
683       TopExp_Explorer getShel;
684       getShel.Init(SewIt.SewedShape(), TopAbs_SHELL);
685       if (getShel.More()) {
686         di << "First shell found in compound\n";
687         B.MakeSolid(wallSolid);
688         di << "B.Add(wallSolid,TopoDS::Shell(getShel.Current()));\n";
689         int i = 1;
690         while (getShel.More())
691           {
692             di << "Next shell found in compound\n";
693             di << "B.Add(wallSolid,TopoDS::Shell(getShel.Current()));\n";
694             Sprintf(name,"shell%d", i++);
695             DBRep::Set(name,getShel.Current());
696             B.Add(wallSolid,TopoDS::Shell(getShel.Current()));
697             getShel.Next();
698           }
699       }
700     }
701   }
702
703   Sprintf(name,"result");
704   DBRep::Set(name,wallSolid);
705
706   // Now calculated the volume of the outside tube.
707   GProp_GProps gprops;
708   BRepGProp::VolumeProperties(wallSolid, gprops);
709   di << "The wallSolid's volume is: " << gprops.Mass() << "\n";
710
711   if (check) {
712     if (!(BRepCheck_Analyzer(wallSolid).IsValid()))
713       di << "The TopoDS_Solid was checked, and it was invalid!\n";
714     else
715       di << "The TopoDS_Solid was checked, and it was valid.\n";
716     if (!wallSolid.Closed())
717       di << "The TopoDS_Solid is not closed!\n";
718     else
719       di << "The TopoDS_Solid is closed.\n";
720     if (!wallSolid.Checked())
721       di << "The TopoDS_Solid is not checked!\n";
722     else
723       di << "The TopoDS_Solid has been checked.\n";
724     if (wallSolid.Infinite())
725       di << "The TopoDS_Solid is infinite!\n";
726     else
727       di << "The TopoDS_Solid is finite.\n";
728   }
729
730   di << "The result is a ";
731   // Check to see if we have a solid
732   switch (wallSolid.ShapeType()) {
733   case (TopAbs_COMPOUND):
734     di << "TopAbs_COMPOUND\n";
735     break;
736   case (TopAbs_COMPSOLID):
737     di << "TopAbs_COMPSOLID\n";
738     break;
739   case (TopAbs_SOLID):
740     di << "TopAbs_SOLID\n";
741     break;
742   case (TopAbs_SHELL):
743     di << "TopAbs_SHELL\n";
744     break;
745   case (TopAbs_FACE):
746     di << "TopAbs_FACE\n";
747     break;
748   case (TopAbs_WIRE):
749     di << "TopAbs_WIRE\n";
750     break;
751   case (TopAbs_EDGE):
752     di << "TopAbs_EDGE\n";
753     break;
754   case (TopAbs_VERTEX):
755     di << "TopAbs_VERTEX\n";
756     break;
757   case (TopAbs_SHAPE):
758     di << "TopAbs_SHAPE\n";
759   }
760
761   return 0;
762 }
763
764 #include <BRepPrimAPI_MakeBox.hxx>
765 #include <BRepBndLib.hxx>
766 #include <TopTools_Array1OfShape.hxx>
767 #include <TColStd_Array1OfReal.hxx>
768 #include <BRepBuilderAPI_Copy.hxx>
769 #include <BRepAlgoAPI_Cut.hxx>
770 #include <BRepAlgoAPI_Common.hxx>
771 #include <Precision.hxx>
772
773 static Standard_Integer OCC817 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
774 {
775   if(argc != 3) {
776     di << "Usage : " << argv[0] << " result mesh_delta\n";
777     return 1;
778   }
779
780   Standard_Real delt = 5.0*Precision::Confusion();
781   Standard_Real mesh_delt = Draw::Atof(argv[2]);
782   if (mesh_delt <= 0.0)
783   {
784     di<<"Error: mesh_delta must be positive value\n";
785     return -1;
786   }
787
788   // Create outer box solid
789   gp_Pnt P(0,0,0);
790   TopoDS_Solid fullSolid = BRepPrimAPI_MakeBox(P, 30.0, 30.0, 30.0).Solid();
791
792   // Create inner box solid
793   P.SetX(10); P.SetY(10); P.SetZ(10);
794   TopoDS_Solid internalSolid = BRepPrimAPI_MakeBox(P, 10.0, 10.0, 10.0).Solid();
795
796   // Cut inner from outer
797   di << "BRepAlgoAPI_Cut cut( fullSolid, internalSolid )\n";
798   BRepAlgoAPI_Cut cut(fullSolid, internalSolid);
799   if (!cut.IsDone())
800   {
801     di << "Error: Could not cut volumes\n";
802     return -1;
803   }
804   const TopoDS_Shape& cut_shape = cut.Shape();
805
806   // see if we have a solid
807   Standard_Integer found_solid = 0;
808   TopoDS_Solid cutSolid;
809   TopExp_Explorer Ex;
810   for (Ex.Init(cut_shape, TopAbs_SOLID); Ex.More(); Ex.Next())
811   {
812     TopoDS_Solid sol = TopoDS::Solid(Ex.Current());
813     if (!sol.IsNull()) { cutSolid = sol; found_solid++; }
814   }
815   if ( found_solid != 1 )
816   {
817     di << "Error: Cut operation produced " << found_solid << " solids\n";
818     return -1;
819   }
820   DBRep::Set(argv[1],cutSolid);
821
822   // Calculate initial volume
823   GProp_GProps volumeVProps;
824   BRepGProp::VolumeProperties (cutSolid, volumeVProps);
825   di << "Info: Original volume  = " << volumeVProps.Mass() << "\n";
826
827   //
828   // build bounding box and calculate bounds for initial mesh
829   //
830   Bnd_Box bndBox;
831   BRepBndLib::Add( cutSolid, bndBox );
832   Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
833   bndBox.Get( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
834   Xmin -= delt;
835   Ymin -= delt;
836   Zmin -= delt;
837   Xmax += delt;
838   Ymax += delt;
839   Zmax += delt;
840   di<<"Info: Bounds\n  ("<<Xmin<<","<<Ymin<<","<<Zmin<<")\n  ("<<Xmax<<","<<Ymax<<","<<Zmax<<")\n";
841
842   // grid the bounding box
843   Standard_Integer NumXsubvolumes = (Standard_Integer)((Xmax - Xmin) / mesh_delt); if (NumXsubvolumes <= 0) NumXsubvolumes = 1;
844   Standard_Integer NumYsubvolumes = (Standard_Integer)((Ymax - Ymin) / mesh_delt); if (NumYsubvolumes <= 0) NumYsubvolumes = 1;
845   Standard_Integer NumZsubvolumes = (Standard_Integer)((Zmax - Zmin) / mesh_delt); if (NumZsubvolumes <= 0) NumZsubvolumes = 1;
846   const Standard_Real StepX = (Xmax - Xmin) / NumXsubvolumes;
847   const Standard_Real StepY = (Ymax - Ymin) / NumYsubvolumes;
848   const Standard_Real StepZ = (Zmax - Zmin) / NumZsubvolumes;
849   const Standard_Integer NumSubvolumes = NumXsubvolumes * NumYsubvolumes * NumZsubvolumes;
850   di << "Info: NumSubvolumesX = " << NumXsubvolumes << "\n";
851   di << "Info: NumSubvolumesY = " << NumYsubvolumes << "\n";
852   di << "Info: NumSubvolumesZ = " << NumZsubvolumes << "\n";
853   di << "Info: NumSubvolumes = " << NumSubvolumes << "\n";
854
855   //
856   // construct initial mesh of cutSolid
857   //
858   TopTools_Array1OfShape SubvolumeSolid(0,NumSubvolumes-1);
859   TColStd_Array1OfReal SubvolumeVol(0,NumSubvolumes-1);
860   Standard_Real accumulatedVolume = 0.0;
861   Standard_Integer i, j, k, l = 0;
862   Standard_Real x = Xmin;
863   for ( i = 0; i < NumXsubvolumes; i++ )
864   {
865     Standard_Real y = Ymin;
866     for ( j = 0; j < NumYsubvolumes; j++ )
867     {
868       Standard_Real z = Zmin;
869       for ( k = 0; k < NumZsubvolumes; k++ )
870       {
871         P.SetX(x);
872         P.SetY(y);
873         P.SetZ(z);
874         TopoDS_Shape aSubvolume = BRepPrimAPI_MakeBox(P, StepX, StepY, StepZ).Solid();
875         di<<"Info: box b_"<<l<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" "<<StepX<<" "<<StepY<<" "<<StepZ<<"\n";
876         if ( aSubvolume.IsNull())
877         {
878           di << "Error: could not construct subvolume " << l << "\n";
879           return 1;
880         }
881         SubvolumeSolid.SetValue(l,aSubvolume);
882         GProp_GProps subvolumeVProps;
883         BRepGProp::VolumeProperties (SubvolumeSolid(l), subvolumeVProps);
884         const Standard_Real vol = subvolumeVProps.Mass();
885         di << "Info: original subvolume " << l << " volume = " << vol << "\n";
886         SubvolumeVol.SetValue(l,vol);
887         accumulatedVolume += vol;
888         l++;
889         z += StepZ;
890       }
891       y += StepY;
892     }
893     x += StepX;
894   }
895   di << "Info: Accumulated mesh volume = " << accumulatedVolume << "\n";
896
897   //  
898   // trim mesh to cutSolid
899   //
900   accumulatedVolume = 0.0;
901   for ( l = 0; l < NumSubvolumes; l++ )
902   {
903     TopoDS_Shape copySolid = BRepBuilderAPI_Copy(cutSolid).Shape();
904
905     // perform common
906     di << "BRepAlgoAPI_Common common(copySolid/*cutSolid*/, SubvolumeSolid(l))\n";
907     BRepAlgoAPI_Common common(copySolid/*cutSolid*/, SubvolumeSolid(l));
908     if (!common.IsDone())
909     {
910       di << "Error: could not construct a common solid " << l << "\n";
911       return 1;
912     }
913     const TopoDS_Shape& aCommonShape = common.Shape();
914
915     // see if we have a solid
916     found_solid = 0;
917     TopoDS_Shape commonShape;
918     //////////for (Ex.Init(common.Shape(), TopAbs_SOLID); Ex.More(); Ex.Next())
919     for (Ex.Init(aCommonShape, TopAbs_SOLID); Ex.More(); Ex.Next())
920     {
921       TopoDS_Solid sol = TopoDS::Solid(Ex.Current());
922       if (!sol.IsNull()) { commonShape = sol; found_solid++; }
923     }
924     if ( found_solid != 1 )
925     {
926       di << "Info: Common operation " << l << " produced " << found_solid << " solids\n";
927     }
928     else
929     {
930       SubvolumeSolid.SetValue(l,commonShape);
931       GProp_GProps subvolumeVProps;
932       BRepGProp::VolumeProperties (SubvolumeSolid(l), subvolumeVProps);
933       const Standard_Real vol = subvolumeVProps.Mass();
934       const Standard_Boolean err = (vol > SubvolumeVol(l)) || (vol <= 0.0);
935       //cout << (err? "ERROR" : "Info") << ": final subvolume " << l << " volume = " << vol << endl;
936       if (err)
937         di << "ERROR: final subvolume " << l << " volume = " << vol << "\n";
938       else
939         di << "Info: final subvolume " << l << " volume = " << vol << "\n";
940       accumulatedVolume += vol;
941       if (err)
942       {
943         char astr[80];
944         Sprintf(astr,"e_%d",l);
945         DBRep::Set(astr,commonShape);
946       }
947     }
948   }
949   di << "Info: Accumulated meshed volume = " << accumulatedVolume << "\n";
950
951   return 0;     
952 }
953
954 void QABugs::Commands_13(Draw_Interpretor& theCommands) {
955   const char *group = "QABugs";
956
957   theCommands.Add ("OCC332", "OCC332 [wall_thickness [dia1 [dia2 [length [major_radius]]]]]", __FILE__, OCC332bug, group);
958   //////theCommands.Add("OCC544", "OCC544 [[[[[wT [[[[d1 [[[d2 [[R [length]]]]]", __FILE__, OCC544, group);
959   theCommands.Add("OCC544", "OCC544 [[[[[wT [[[[d1 [[[d2 [[R [length ]]]]]", __FILE__, OCC544, group);
960   //////theCommands.Add("OCC817", "OCC817 result mesh_delta", __FILE__, OCC817, group);
961   theCommands.Add("OCC817", "OCC817 result mesh_delta ", __FILE__, OCC817, group);
962
963   return;
964 }