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 //=================================================================================================
39 GeomAlgoAPI_Ellipsoid::GeomAlgoAPI_Ellipsoid(const double theAx,
42 const double theZCut1,
43 const double theZCut2)
52 //=================================================================================================
53 bool GeomAlgoAPI_Ellipsoid::check()
55 if (myAx < Precision::Confusion()) {
56 myError = "Ellipsoid builder :: ax is negative or null.";
58 } else if (myBy < Precision::Confusion()) {
59 myError = "Ellipsoid builder :: by is negative or null.";
61 } else if (myCz < Precision::Confusion()) {
62 myError = "Ellipsoid builder :: cz is negative or null.";
64 } else if (myZCut1 < 0.) {
65 myError = "Ellipsoid builder :: zcut1 is negative.";
67 } else if (myZCut2 < 0.) {
68 myError = "Ellipsoid builder :: zcut2 is negative.";
70 } else if (myZCut1 < Precision::Confusion() && myZCut2 < Precision::Confusion()) {
71 myError = "Ellipsoid builder :: zcut1 and zcut2 are null.";
78 //=================================================================================================
79 void GeomAlgoAPI_Ellipsoid::build()
81 myCreatedFaces.clear();
83 BRepOffsetAPI_Sewing aSewer;
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);
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)
96 aRefAx2 = gp_Ax2(anOrigin, aDirY, aDirX);
97 anElips = gp_Elips(aRefAx2, myAx / 2., myCz / 2.);
99 aRefAx2 = gp_Ax2(anOrigin, aDirY, aDirZ);
100 anElips = gp_Elips(aRefAx2, myCz / 2., myAx / 2.);
103 double aLowPositionFactor = sqrt(1. - (myZCut1 * myZCut1 * 4. / (myCz * myCz))) / 2.;
104 double aHighPositionFactor = sqrt(1. - (myZCut2 * myZCut2 * 4. / (myCz * myCz))) / 2.;
106 double aXEndTop = myAx * aHighPositionFactor;
107 double aXEndBottom = myAx * aLowPositionFactor;
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();
116 // Perform a revolution based on the section to build a simple version of the outer face
118 BRepPrimAPI_MakeRevol aRevolBuilder(anOuterEdge, aZAxis, 2. * M_PI, Standard_True);
119 if (!aRevolBuilder.IsDone()) {
120 myError = "Ellipsoid builder :: section revolution did not succeed";
125 gp_Mat rot (1., 0., 0.,
129 aGTrsf.SetVectorialPart(rot);
131 BRepBuilderAPI_GTransform aScaleBuilder(aRevolBuilder.Shape(), aGTrsf, true);
132 if (!aScaleBuilder.IsDone()) {
133 myError = "Ellipsoid builder :: scale did not succeed";
137 TopoDS_Face anOuterFace = TopoDS::Face(aScaleBuilder.Shape());
138 aSewer.Add(TopoDS::Face(anOuterFace.Reversed()));
140 // Build the high and low ellipse if needed
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);
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);
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);
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);
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()));
176 if ((myCz / 2. - myZCut2) > Precision::Confusion()) {
177 TopoDS_Face aTopFace;
178 BRepBuilderAPI_MakeEdge aTopEdgeMk(aHighElips);
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()));
189 if ((myCz / 2. - myZCut2) > Precision::Confusion() ||
190 (myCz / 2. - myZCut1) > Precision::Confusion()) {
191 aShell = TopoDS::Shell(aSewer.SewedShape());
193 TopoDS_Builder aBuilder;
194 aBuilder.MakeShell(aShell);
195 aBuilder.Add(aShell, aSewer.SewedShape());
198 BRepBuilderAPI_MakeSolid *anEllipsoidMk = new BRepBuilderAPI_MakeSolid(aShell);
199 anEllipsoidMk->Build();
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);
207 // Test on the shapes
208 if (!(aResultShape).get() || aResultShape->isNull()) {
209 myError = "Ellipsoid builder :: resulting shape is null.";
213 setImpl(anEllipsoidMk);
214 setBuilderType(OCCT_BRepBuilderAPI_MakeShape);