1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <GeomAlgoAPI_Ellipsoid.h>
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>
35 #include <TopoDS_Edge.hxx>
37 //=================================================================================================
38 GeomAlgoAPI_Ellipsoid::GeomAlgoAPI_Ellipsoid()
42 //=================================================================================================
44 GeomAlgoAPI_Ellipsoid::GeomAlgoAPI_Ellipsoid(const double theAx,
47 const double theZCut1,
48 const double theZCut2)
57 //=================================================================================================
58 bool GeomAlgoAPI_Ellipsoid::check()
60 if (myAx < Precision::Confusion()) {
61 myError = "Ellipsoid builder :: ax is negative or null.";
63 } else if (myBy < Precision::Confusion()) {
64 myError = "Ellipsoid builder :: by is negative or null.";
66 } else if (myCz < Precision::Confusion()) {
67 myError = "Ellipsoid builder :: cz is negative or null.";
69 } else if (myZCut1 < 0.) {
70 myError = "Ellipsoid builder :: zcut1 is negative.";
72 } else if (myZCut2 < 0.) {
73 myError = "Ellipsoid builder :: zcut2 is negative.";
75 } else if (myZCut1 < Precision::Confusion() && myZCut2 < Precision::Confusion()) {
76 myError = "Ellipsoid builder :: zcut1 and zcut2 are null.";
83 //=================================================================================================
84 void GeomAlgoAPI_Ellipsoid::build()
86 myCreatedFaces.clear();
88 BRepOffsetAPI_Sewing aSewer;
92 gp_Pnt anOrigin(0., 0., 0.);
93 gp_Dir aDirX(1., 0., 0.);
94 gp_Dir aDirY(0., 1., 0.);
95 gp_Dir aDirZ(0., 0., 1.);
96 gp_Ax1 aZAxis(anOrigin, aDirZ);
98 // Calculate the parameters needed to make the edges and the faces
99 // gp_Elips needs the second parameter to be greater than the third (major axis)
101 aRefAx2 = gp_Ax2(anOrigin, aDirY, aDirX);
102 anElips = gp_Elips(aRefAx2, myAx / 2., myCz / 2.);
104 aRefAx2 = gp_Ax2(anOrigin, aDirY, aDirZ);
105 anElips = gp_Elips(aRefAx2, myCz / 2., myAx / 2.);
108 double aLowPositionFactor = sqrt(1. - (myZCut1 * myZCut1 * 4. / (myCz * myCz))) / 2.;
109 double aHighPositionFactor = sqrt(1. - (myZCut2 * myZCut2 * 4. / (myCz * myCz))) / 2.;
111 double aXEndTop = myAx * aHighPositionFactor;
112 double aXEndBottom = myAx * aLowPositionFactor;
114 // Build the XZ ellipse
115 gp_Pnt anEndPoint1(aXEndTop, 0., myZCut2);
116 gp_Pnt anEndPoint2(aXEndBottom, 0., -myZCut1);
117 BRepBuilderAPI_MakeEdge anElipsBuilder(anElips, anEndPoint1, anEndPoint2);
118 anElipsBuilder.Build();
119 TopoDS_Edge anOuterEdge = anElipsBuilder.Edge();
121 // Perform a revolution based on the section to build a simple version of the outer face
123 BRepPrimAPI_MakeRevol aRevolBuilder(anOuterEdge, aZAxis, 2. * M_PI, Standard_True);
124 if (!aRevolBuilder.IsDone()) {
125 myError = "Ellipsoid builder :: section revolution did not succeed";
130 gp_Mat rot (1., 0., 0.,
134 aGTrsf.SetVectorialPart(rot);
136 BRepBuilderAPI_GTransform aScaleBuilder(aRevolBuilder.Shape(), aGTrsf, true);
137 if (!aScaleBuilder.IsDone()) {
138 myError = "Ellipsoid builder :: scale did not succeed";
142 TopoDS_Face anOuterFace = TopoDS::Face(aScaleBuilder.Shape());
143 aSewer.Add(TopoDS::Face(anOuterFace.Reversed()));
145 // Build the high and low ellipse if needed
151 if ((myCz / 2. - myZCut1) > Precision::Confusion()) {
152 aLowAx2 = gp_Ax2(gp_Pnt(0., 0., -myZCut1), aDirZ, aDirX);
153 aLowElips = gp_Elips(aLowAx2, aLowPositionFactor * myAx, aLowPositionFactor * myBy);
155 if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
156 aHighAx2 = gp_Ax2(gp_Pnt(0., 0., myZCut2), aDirZ, aDirX);
157 aHighElips = gp_Elips(aHighAx2, aHighPositionFactor * myAx, aHighPositionFactor * myBy);
160 if ((myCz / 2. - myZCut1) > Precision::Confusion()) {
161 aLowAx2 = gp_Ax2(gp_Pnt(0., 0., -myZCut1), aDirZ, aDirY);
162 aLowElips = gp_Elips(aLowAx2, aLowPositionFactor * myBy, aLowPositionFactor * myAx);
164 if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
165 aHighAx2 = gp_Ax2(gp_Pnt(0., 0., myZCut2), aDirZ, aDirY);
166 aHighElips = gp_Elips(aHighAx2, aHighPositionFactor * myBy, aHighPositionFactor * myAx);
170 // Make higher and lower elliptical faces if needed
171 if ((myCz / 2. - myZCut1) > Precision::Confusion()) {
172 TopoDS_Face aBottomFace;
173 BRepBuilderAPI_MakeEdge aBottomEdgeMk(aLowElips);
174 aBottomEdgeMk.Build();
175 BRepBuilderAPI_MakeWire aBottomWireMk;
176 aBottomWireMk.Add(aBottomEdgeMk.Edge());
177 BRepBuilderAPI_MakeFace aBottomFaceMk(aBottomWireMk.Wire());
178 aBottomFace = aBottomFaceMk.Face();
179 aSewer.Add(TopoDS::Face(aBottomFace.Reversed()));
181 if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
182 TopoDS_Face aTopFace;
183 BRepBuilderAPI_MakeEdge aTopEdgeMk(aHighElips);
185 BRepBuilderAPI_MakeWire aTopWireMk;
186 aTopWireMk.Add(aTopEdgeMk.Edge());
187 BRepBuilderAPI_MakeFace aTopFaceMk(aTopWireMk.Wire());
188 aTopFace = aTopFaceMk.Face();
189 aSewer.Add(TopoDS::Face(aTopFace.Reversed()));
194 if ((myCz / 2. - myZCut2) > Precision::Confusion() ||
195 (myCz / 2. - myZCut1) > Precision::Confusion()) {
196 aShell = TopoDS::Shell(aSewer.SewedShape());
198 TopoDS_Builder aBuilder;
199 aBuilder.MakeShell(aShell);
200 aBuilder.Add(aShell, aSewer.SewedShape());
203 BRepBuilderAPI_MakeSolid *anEllipsoidMk = new BRepBuilderAPI_MakeSolid(aShell);
204 anEllipsoidMk->Build();
206 // Store and publish the results
207 std::shared_ptr<GeomAPI_Shape> aResultShape =
208 std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
209 aResultShape->setImpl(new TopoDS_Shape(anEllipsoidMk->Solid()));
210 setShape(aResultShape);
212 // Test on the shapes
213 if (!(aResultShape).get() || aResultShape->isNull()) {
214 myError = "Ellipsoid builder :: resulting shape is null.";
218 setImpl(anEllipsoidMk);
219 setBuilderType(OCCT_BRepBuilderAPI_MakeShape);