]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_Ellipsoid.cpp
Salome HOME
[Code coverage GeomAlgoAPI]: Remove default constructors of algorithms
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Ellipsoid.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <GeomAlgoAPI_Ellipsoid.h>
22
23 #include <gp_Ax2.hxx>
24 #include <gp_Elips.hxx>
25 #include <gp_GTrsf.hxx>
26 #include <BRepBuilderAPI_GTransform.hxx>
27 #include <BRepBuilderAPI_MakeEdge.hxx>
28 #include <BRepOffsetAPI_Sewing.hxx>
29 #include <BRepBuilderAPI_MakeFace.hxx>
30 #include <BRepBuilderAPI_MakeSolid.hxx>
31 #include <BRepBuilderAPI_MakeWire.hxx>
32 #include <BRepPrimAPI_MakeRevol.hxx>
33
34 #include <TopoDS.hxx>
35 #include <TopoDS_Edge.hxx>
36
37 //=================================================================================================
38
39 GeomAlgoAPI_Ellipsoid::GeomAlgoAPI_Ellipsoid(const double theAx,
40                                              const double theBy,
41                                              const double theCz,
42                                              const double theZCut1,
43                                              const double theZCut2)
44 {
45   myAx = theAx;
46   myBy = theBy;
47   myCz = theCz;
48   myZCut1 = theZCut1;
49   myZCut2 = theZCut2;
50 }
51
52 //=================================================================================================
53 bool GeomAlgoAPI_Ellipsoid::check()
54 {
55   if (myAx < Precision::Confusion()) {
56     myError = "Ellipsoid builder :: ax is negative or null.";
57     return false;
58   } else if (myBy < Precision::Confusion()) {
59     myError = "Ellipsoid builder :: by is negative or null.";
60     return false;
61   } else if (myCz < Precision::Confusion()) {
62     myError = "Ellipsoid builder :: cz is negative or null.";
63     return false;
64   } else if (myZCut1 < 0.) {
65     myError = "Ellipsoid builder :: zcut1 is negative.";
66     return false;
67   } else if (myZCut2 < 0.) {
68     myError = "Ellipsoid builder :: zcut2 is negative.";
69     return false;
70   } else if (myZCut1 < Precision::Confusion() && myZCut2 < Precision::Confusion()) {
71     myError = "Ellipsoid builder :: zcut1 and zcut2 are null.";
72     return false;
73   }
74
75   return true;
76 }
77
78 //=================================================================================================
79 void GeomAlgoAPI_Ellipsoid::build()
80 {
81   myCreatedFaces.clear();
82
83   BRepOffsetAPI_Sewing aSewer;
84   gp_Ax2 aRefAx2;
85   gp_Elips anElips;
86
87   gp_Pnt anOrigin(0., 0., 0.);
88   gp_Dir aDirX(1., 0., 0.);
89   gp_Dir aDirY(0., 1., 0.);
90   gp_Dir aDirZ(0., 0., 1.);
91   gp_Ax1 aZAxis(anOrigin, aDirZ);
92
93   // Calculate the parameters needed to make the edges and the faces
94   // gp_Elips needs the second parameter to be greater than the third (major axis)
95   if (myCz < myAx) {
96     aRefAx2 = gp_Ax2(anOrigin, aDirY, aDirX);
97     anElips = gp_Elips(aRefAx2, myAx / 2., myCz / 2.);
98   } else {
99     aRefAx2 = gp_Ax2(anOrigin, aDirY, aDirZ);
100     anElips = gp_Elips(aRefAx2, myCz / 2., myAx / 2.);
101   }
102
103   double aLowPositionFactor = sqrt(1. - (myZCut1 * myZCut1 * 4. / (myCz * myCz))) / 2.;
104   double aHighPositionFactor = sqrt(1. - (myZCut2 * myZCut2 * 4. / (myCz * myCz))) / 2.;
105
106   double aXEndTop = myAx * aHighPositionFactor;
107   double aXEndBottom = myAx *  aLowPositionFactor;
108
109   // Build the XZ ellipse
110   gp_Pnt anEndPoint1(aXEndTop, 0., myZCut2);
111   gp_Pnt anEndPoint2(aXEndBottom, 0., -myZCut1);
112   BRepBuilderAPI_MakeEdge anElipsBuilder(anElips, anEndPoint1, anEndPoint2);
113   anElipsBuilder.Build();
114   TopoDS_Edge anOuterEdge = anElipsBuilder.Edge();
115
116   // Perform a revolution based on the section to build a simple version of the outer face
117   // (isotropic in XY)
118   BRepPrimAPI_MakeRevol aRevolBuilder(anOuterEdge, aZAxis, 2. * M_PI, Standard_True);
119   if (!aRevolBuilder.IsDone()) {
120     myError = "Ellipsoid builder :: section revolution did not succeed";
121     return;
122   }
123
124   gp_GTrsf aGTrsf;
125   gp_Mat rot (1.,          0., 0.,
126               0., myBy / myAx, 0.,
127               0.,          0., 1.);
128
129   aGTrsf.SetVectorialPart(rot);
130
131   BRepBuilderAPI_GTransform aScaleBuilder(aRevolBuilder.Shape(), aGTrsf, true);
132   if (!aScaleBuilder.IsDone()) {
133     myError = "Ellipsoid builder :: scale did not succeed";
134     return;
135   }
136
137   TopoDS_Face anOuterFace = TopoDS::Face(aScaleBuilder.Shape());
138   aSewer.Add(TopoDS::Face(anOuterFace.Reversed()));
139
140   // Build the high and low ellipse if needed
141   gp_Ax2 aLowAx2;
142   gp_Ax2 aHighAx2;
143   gp_Elips aLowElips;
144   gp_Elips aHighElips;
145   if (myBy < myAx) {
146     if ((myCz / 2. - myZCut1) > Precision::Confusion()) {
147       aLowAx2 = gp_Ax2(gp_Pnt(0., 0., -myZCut1), aDirZ, aDirX);
148       aLowElips = gp_Elips(aLowAx2, aLowPositionFactor * myAx, aLowPositionFactor * myBy);
149     }
150     if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
151       aHighAx2 = gp_Ax2(gp_Pnt(0., 0., myZCut2), aDirZ, aDirX);
152       aHighElips = gp_Elips(aHighAx2, aHighPositionFactor * myAx, aHighPositionFactor * myBy);
153     }
154   } else {
155     if ((myCz / 2. - myZCut1) > Precision::Confusion()) {
156       aLowAx2 = gp_Ax2(gp_Pnt(0., 0., -myZCut1), aDirZ, aDirY);
157       aLowElips = gp_Elips(aLowAx2, aLowPositionFactor * myBy, aLowPositionFactor * myAx);
158     }
159     if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
160       aHighAx2 = gp_Ax2(gp_Pnt(0., 0., myZCut2), aDirZ, aDirY);
161       aHighElips = gp_Elips(aHighAx2, aHighPositionFactor * myBy, aHighPositionFactor * myAx);
162     }
163   }
164
165   // Make higher and lower elliptical faces if needed
166   if ((myCz / 2. - myZCut1) > Precision::Confusion()) {
167     TopoDS_Face aBottomFace;
168     BRepBuilderAPI_MakeEdge aBottomEdgeMk(aLowElips);
169     aBottomEdgeMk.Build();
170     BRepBuilderAPI_MakeWire aBottomWireMk;
171     aBottomWireMk.Add(aBottomEdgeMk.Edge());
172     BRepBuilderAPI_MakeFace aBottomFaceMk(aBottomWireMk.Wire());
173     aBottomFace = aBottomFaceMk.Face();
174     aSewer.Add(TopoDS::Face(aBottomFace.Reversed()));
175   }
176   if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
177     TopoDS_Face aTopFace;
178     BRepBuilderAPI_MakeEdge aTopEdgeMk(aHighElips);
179     aTopEdgeMk.Build();
180     BRepBuilderAPI_MakeWire aTopWireMk;
181     aTopWireMk.Add(aTopEdgeMk.Edge());
182     BRepBuilderAPI_MakeFace aTopFaceMk(aTopWireMk.Wire());
183     aTopFace = aTopFaceMk.Face();
184     aSewer.Add(TopoDS::Face(aTopFace.Reversed()));
185   }
186
187   TopoDS_Shell aShell;
188   aSewer.Perform();
189   if ((myCz / 2. - myZCut2) > Precision::Confusion() ||
190       (myCz / 2. - myZCut1) > Precision::Confusion()) {
191     aShell = TopoDS::Shell(aSewer.SewedShape());
192   } else {
193     TopoDS_Builder aBuilder;
194     aBuilder.MakeShell(aShell);
195     aBuilder.Add(aShell, aSewer.SewedShape());
196   }
197
198   BRepBuilderAPI_MakeSolid *anEllipsoidMk = new BRepBuilderAPI_MakeSolid(aShell);
199   anEllipsoidMk->Build();
200
201   // Store and publish the results
202   std::shared_ptr<GeomAPI_Shape> aResultShape =
203     std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
204   aResultShape->setImpl(new TopoDS_Shape(anEllipsoidMk->Solid()));
205   setShape(aResultShape);
206
207   // Test on the shapes
208   if (!(aResultShape).get() || aResultShape->isNull()) {
209     myError = "Ellipsoid builder  :: resulting shape is null.";
210     return;
211   }
212
213   setImpl(anEllipsoidMk);
214   setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
215
216   setDone(true);
217 }