d965af3f21987bb288f823a2423d65acac9fec71
[occt.git] / samples / qt / Tutorial / src / MakeBottle.cxx
1 #include <BRep_Tool.hxx>
2
3 #include <BRepAlgoAPI_Fuse.hxx>
4
5 #include <BRepBuilderAPI_MakeEdge.hxx>
6 #include <BRepBuilderAPI_MakeFace.hxx>
7 #include <BRepBuilderAPI_MakeWire.hxx>
8 #include <BRepBuilderAPI_Transform.hxx>
9
10 #include <BRepFilletAPI_MakeFillet.hxx>
11
12 #include <BRepLib.hxx>
13
14 #include <BRepOffsetAPI_MakeThickSolid.hxx>
15 #include <BRepOffsetAPI_ThruSections.hxx>
16
17 #include <BRepPrimAPI_MakeCylinder.hxx>
18 #include <BRepPrimAPI_MakePrism.hxx>
19
20 #include <GC_MakeArcOfCircle.hxx>
21 #include <GC_MakeSegment.hxx>
22
23 #include <GCE2d_MakeSegment.hxx>
24
25 #include <gp.hxx>
26 #include <gp_Ax1.hxx>
27 #include <gp_Ax2.hxx>
28 #include <gp_Ax2d.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Dir2d.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Trsf.hxx>
34 #include <gp_Vec.hxx>
35
36 #include <Geom_CylindricalSurface.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_Surface.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40
41 #include <Geom2d_Ellipse.hxx>
42 #include <Geom2d_TrimmedCurve.hxx>
43
44 #include <TopExp_Explorer.hxx>
45
46 #include <TopoDS.hxx>
47 #include <TopoDS_Edge.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Wire.hxx>
50 #include <TopoDS_Shape.hxx>
51 #include <TopoDS_Compound.hxx>
52
53 #include <TopTools_ListOfShape.hxx>
54
55
56 TopoDS_Shape
57 MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight,
58            const Standard_Real myThickness)
59 {
60   // Profile : Define Support Points
61   gp_Pnt aPnt1(-myWidth / 2., 0, 0);        
62   gp_Pnt aPnt2(-myWidth / 2., -myThickness / 4., 0);
63   gp_Pnt aPnt3(0, -myThickness / 2., 0);
64   gp_Pnt aPnt4(myWidth / 2., -myThickness / 4., 0);
65   gp_Pnt aPnt5(myWidth / 2., 0, 0);
66
67   // Profile : Define the Geometry
68   Handle(Geom_TrimmedCurve) anArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3,aPnt4);
69   Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1, aPnt2);
70   Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4, aPnt5);
71
72   // Profile : Define the Topology
73   TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(aSegment1);
74   TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(anArcOfCircle);
75   TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);
76   TopoDS_Wire aWire  = BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3);
77
78   // Complete Profile
79   gp_Ax1 xAxis = gp::OX();
80   gp_Trsf aTrsf;
81
82   aTrsf.SetMirror(xAxis);
83   BRepBuilderAPI_Transform aBRepTrsf(aWire, aTrsf);
84   TopoDS_Shape aMirroredShape = aBRepTrsf.Shape();
85   TopoDS_Wire aMirroredWire = TopoDS::Wire(aMirroredShape);
86
87   BRepBuilderAPI_MakeWire mkWire;
88   mkWire.Add(aWire);
89   mkWire.Add(aMirroredWire);
90   TopoDS_Wire myWireProfile = mkWire.Wire();
91
92   // Body : Prism the Profile
93   TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile);
94   gp_Vec aPrismVec(0, 0, myHeight);
95   TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec);
96
97   // Body : Apply Fillets
98   BRepFilletAPI_MakeFillet mkFillet(myBody);
99   TopExp_Explorer anEdgeExplorer(myBody, TopAbs_EDGE);
100   while(anEdgeExplorer.More()){
101     TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExplorer.Current());
102     //Add edge to fillet algorithm
103     mkFillet.Add(myThickness / 12., anEdge);
104     anEdgeExplorer.Next();
105   }
106
107   myBody = mkFillet.Shape();
108
109   // Body : Add the Neck        
110   gp_Pnt neckLocation(0, 0, myHeight);
111   gp_Dir neckAxis = gp::DZ();
112   gp_Ax2 neckAx2(neckLocation, neckAxis);
113
114   Standard_Real myNeckRadius = myThickness / 4.;
115   Standard_Real myNeckHeight = myHeight / 10.;
116
117   BRepPrimAPI_MakeCylinder MKCylinder(neckAx2, myNeckRadius, myNeckHeight);
118   TopoDS_Shape myNeck = MKCylinder.Shape();
119
120   myBody = BRepAlgoAPI_Fuse(myBody, myNeck);
121
122   // Body : Create a Hollowed Solid
123   TopoDS_Face   faceToRemove;
124   Standard_Real zMax = -1;
125
126   for(TopExp_Explorer aFaceExplorer(myBody, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()){
127     TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current());
128     // Check if <aFace> is the top face of the bottle\92s neck 
129     Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace);
130     if(aSurface->DynamicType() == STANDARD_TYPE(Geom_Plane)){
131       Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface);
132       gp_Pnt aPnt = aPlane->Location();
133       Standard_Real aZ   = aPnt.Z();
134       if(aZ > zMax){
135         zMax = aZ;
136         faceToRemove = aFace;
137       }
138     }
139   }
140
141   TopTools_ListOfShape facesToRemove;
142   facesToRemove.Append(faceToRemove);
143   myBody = BRepOffsetAPI_MakeThickSolid(myBody, facesToRemove, -myThickness / 50, 1.e-3);
144   // Threading : Create Surfaces
145   Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99);
146   Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05);
147
148   // Threading : Define 2D Curves
149   gp_Pnt2d aPnt(2. * M_PI, myNeckHeight / 2.);
150   gp_Dir2d aDir(2. * M_PI, myNeckHeight / 4.);
151   gp_Ax2d anAx2d(aPnt, aDir);
152
153   Standard_Real aMajor = 2. * M_PI;
154   Standard_Real aMinor = myNeckHeight / 10;
155
156   Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor);
157   Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor / 4);
158   Handle(Geom2d_TrimmedCurve) anArc1 = new Geom2d_TrimmedCurve(anEllipse1, 0, M_PI);
159   Handle(Geom2d_TrimmedCurve) anArc2 = new Geom2d_TrimmedCurve(anEllipse2, 0, M_PI);
160   gp_Pnt2d anEllipsePnt1 = anEllipse1->Value(0);
161   gp_Pnt2d anEllipsePnt2 = anEllipse1->Value(M_PI);
162
163   Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2);
164   // Threading : Build Edges and Wires
165   TopoDS_Edge anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1);
166   TopoDS_Edge anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment, aCyl1);
167   TopoDS_Edge anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2);
168   TopoDS_Edge anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment, aCyl2);
169   TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1, anEdge2OnSurf1);
170   TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2, anEdge2OnSurf2);
171   BRepLib::BuildCurves3d(threadingWire1);
172   BRepLib::BuildCurves3d(threadingWire2);
173
174   // Create Threading 
175   BRepOffsetAPI_ThruSections aTool(Standard_True);
176   aTool.AddWire(threadingWire1);
177   aTool.AddWire(threadingWire2);
178   aTool.CheckCompatibility(Standard_False);
179
180   TopoDS_Shape myThreading = aTool.Shape();
181
182   // Building the Resulting Compound 
183   TopoDS_Compound aRes;
184   BRep_Builder aBuilder;
185   aBuilder.MakeCompound (aRes);
186   aBuilder.Add (aRes, myBody);
187   aBuilder.Add (aRes, myThreading);
188
189   return aRes;
190 }
191