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