Salome HOME
Add the GDML primitive "Cone Segment".
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ConeSegment.cpp
1 // Copyright (C) 2014-2016 CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_ConeSegment.cpp
4 // Created:     24 Nov 2016
5 // Author:      Clarisse Genrault (CEA)
6
7 #include <GeomAlgoAPI_ConeSegment.h>
8
9 #include <gp_Dir.hxx>
10 #include <gp_Ax1.hxx>
11 #include <gp_Pnt.hxx>
12 #include <TopoDS_Edge.hxx>
13
14 #include <BRepPrimAPI_MakeRevol.hxx>
15 #include <BRepBuilderAPI_MakeEdge.hxx>
16 #include <BRepBuilderAPI_MakeWire.hxx>
17 #include <BRepBuilderAPI_MakeFace.hxx>
18 #include <Precision.hxx>
19
20 #include <math.h>
21
22 //=================================================================================================
23 GeomAlgoAPI_ConeSegment::GeomAlgoAPI_ConeSegment()
24 {
25 }
26
27 //=================================================================================================
28
29 GeomAlgoAPI_ConeSegment::GeomAlgoAPI_ConeSegment(const double theRMin1,
30                                                  const double theRMax1,
31                                                  const double theRMin2,
32                                                  const double theRMax2,
33                                                  const double theZ,
34                                                  const double theStartPhi,
35                                                  const double theDeltaPhi)
36 {
37   myRMin1 = theRMin1;
38   myRMax1 = theRMax1;
39   myRMin2 = theRMin2;
40   myRMax2 = theRMax2;
41   myZ = theZ;
42   myStartPhi = theStartPhi;
43   myDeltaPhi = theDeltaPhi;
44 }
45
46 //=================================================================================================
47 bool GeomAlgoAPI_ConeSegment::check()
48 {
49   if (myRMin1 < 0.)
50   {
51     myError = "Cone Segment builder :: rmin1 is negative.";
52     return false;
53   }
54   if (myRMin2 < 0.)
55   {
56     myError = "Cone Segment builder :: rmin2 is negative.";
57     return false;
58   }
59   if ((myRMax1-myRMin1) < Precision::Confusion())
60   {
61     myError = "Cone Segment builder :: rmin1 is larger than rmax1.";
62     return false;
63   }
64   if ((myRMax2-myRMin2) < Precision::Confusion())
65   {
66     myError = "Cone Segment builder :: rmin2 is larger than rmax2.";
67     return false;
68   }
69   if (myZ < Precision::Confusion())
70   {
71     myError = "Cone Segment builder :: z is negative or null.";
72     return false;
73   }
74   if (myDeltaPhi < Precision::Angular() * 180./M_PI)
75   {
76     myError = "Cone Segment builder :: deltaphi is negative or null.";
77     return false;
78   }
79   if (myDeltaPhi > 360)
80   {
81     myError = "Cone Segment builder :: deltaphi is larger than 360 degree.";
82     return false;
83   }
84   return true;
85 }
86
87 //=================================================================================================
88 void GeomAlgoAPI_ConeSegment::build()
89 {
90   myCreatedFaces.clear();
91
92   const double aStartPhiRad = myStartPhi * M_PI/180.;
93   BRepBuilderAPI_MakeWire aWireBuilder;
94
95   // Define the section from the 4 vertices
96   gp_Pnt aPointOuterBase(myRMax1 * cos(aStartPhiRad), myRMax1 * sin(aStartPhiRad), -myZ/2.);
97   gp_Pnt aPointInnerBase(myRMin1 * cos(aStartPhiRad), myRMin1 * sin(aStartPhiRad), -myZ/2.);
98   gp_Pnt aPointOuterTop(myRMax2 * cos(aStartPhiRad), myRMax2 * sin(aStartPhiRad), myZ/2.);
99   gp_Pnt aPointInnerTop(myRMin2 * cos(aStartPhiRad), myRMin2 * sin(aStartPhiRad), myZ/2.);
100
101   if ((myRMax1 - myRMin1) >= Precision::Confusion()){
102     BRepBuilderAPI_MakeEdge anEdgeBuilderBase(aPointOuterBase, aPointInnerBase);
103     anEdgeBuilderBase.Build();
104     aWireBuilder.Add(anEdgeBuilderBase.Edge());
105   }
106
107   BRepBuilderAPI_MakeEdge anEdgeBuilderOuter(aPointOuterBase, aPointOuterTop);
108   anEdgeBuilderOuter.Build();
109   aWireBuilder.Add(anEdgeBuilderOuter.Edge());
110   if ((myRMax2 - myRMin2) >= Precision::Confusion()){
111     BRepBuilderAPI_MakeEdge anEdgeBuilderTop(aPointOuterTop, aPointInnerTop);
112     anEdgeBuilderTop.Build();
113     aWireBuilder.Add(anEdgeBuilderTop.Edge());
114   }
115
116   BRepBuilderAPI_MakeEdge anEdgeBuilderInner(aPointInnerTop, aPointInnerBase);
117   anEdgeBuilderInner.Build();
118   aWireBuilder.Add(anEdgeBuilderInner.Edge());
119
120   aWireBuilder.Build();
121   BRepBuilderAPI_MakeFace aFaceBuilder(aWireBuilder.Wire());
122   aFaceBuilder.Build();
123
124   if (!aFaceBuilder.IsDone()){
125     myError = "Cone Segment builder :: section is not valid";
126     return;
127   }
128
129   // Perform a revolution based on the section to build the solid
130   gp_Dir aZDir(0., 0., 1.);
131   gp_Pnt anOrigin(0., 0., 0.);
132   gp_Ax1 aZAxis(anOrigin, aZDir);
133   BRepPrimAPI_MakeRevol* aRevolBuilder =
134     new BRepPrimAPI_MakeRevol(aFaceBuilder.Face(), aZAxis, myDeltaPhi * M_PI/180., Standard_True);
135   if(!aRevolBuilder) {
136     return;
137     myError = "Cone Segment builder :: section revolution did not succeed";
138   }
139   if(!aRevolBuilder->IsDone()) {
140     myError = "Cone Segment builder :: section revolution did not succeed";
141     return;
142   }
143
144   setImpl(aRevolBuilder);
145   setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
146
147   std::shared_ptr<GeomAPI_Shape> aResultShape =
148     std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
149   aResultShape->setImpl(new TopoDS_Shape(aRevolBuilder->Shape()));
150
151   // Test on the shapes
152   if (!(aResultShape).get() || aResultShape->isNull()) {
153     myError = "Cone Segment builder  :: resulting shape is null.";
154     return;
155   }
156
157   setShape(aResultShape);
158   setDone(true);
159 }