]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp
Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Rotation.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 email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include "GeomAlgoAPI_Rotation.h"
21
22 #include <GeomAPI_XYZ.h>
23
24 #include <BRepBuilderAPI_Transform.hxx>
25
26 #include <gp_Ax1.hxx>
27 #include <gp_Dir.hxx>
28 #include <gp_Vec.hxx>
29
30 #include <Precision.hxx>
31
32 //=================================================================================================
33 GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
34                                            std::shared_ptr<GeomAPI_Ax1>   theAxis,
35                                            double                         theAngle)
36 {
37   myMethodType = BY_ANGLE;
38   mySourceShape = theSourceShape;
39   myAxis = theAxis;
40   myAngle = theAngle;
41 }
42
43
44 //=================================================================================================
45 GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
46                                            std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
47                                            std::shared_ptr<GeomAPI_Pnt>   theStartPoint,
48                                            std::shared_ptr<GeomAPI_Pnt>   theEndPoint)
49 {
50   myMethodType = BY_POINTS;
51   mySourceShape = theSourceShape;
52   myCenterPoint = theCenterPoint;
53   myStartPoint = theStartPoint;
54   myEndPoint = theEndPoint;
55 }
56
57 //=================================================================================================
58 bool GeomAlgoAPI_Rotation::check()
59 {
60   switch (myMethodType) {
61     case BY_ANGLE: {
62       if (!myAxis) {
63         myError = "Rotation builder :: axis is not valid.";
64         return false;
65       }
66       if (!mySourceShape) {
67         myError = "Rotation builder :: source shape is not valid.";
68         return false;
69       }
70       if (myAngle < -360.) {
71         myError = "Rotation builder :: angle smaller than -360 degrees.";
72         return false;
73       }
74       if (myAngle > 360.) {
75         myError = "Rotation builder :: angle greater than 360 degrees.";
76         return false;
77       }
78       return true;
79     }
80     case BY_POINTS: {
81       if (!myCenterPoint) {
82         myError = "Rotation builder :: center point is not valid.";
83         return false;
84       }
85       if (!myStartPoint) {
86         myError = "Rotation builder :: start point is not valid.";
87         return false;
88       }
89       if (!myEndPoint) {
90         myError = "Rotation builder :: end point is not valid.";
91         return false;
92       }
93       if (!mySourceShape) {
94         myError = "Rotation builder :: source shape is not valid.";
95         return false;
96       }
97       if(myCenterPoint->distance(myStartPoint) < Precision::Confusion()) {
98         myError = "Rotation builder :: center point and start point coincide.";
99         return false;
100       }
101       if(myCenterPoint->distance(myEndPoint) < Precision::Confusion()) {
102         myError = "Rotation builder :: center point and end point coincide.";
103         return false;
104       }
105       if(myStartPoint->distance(myEndPoint) < Precision::Confusion()) {
106         myError = "Rotation builder :: start point and end point coincide.";
107         return false;
108       }
109       std::shared_ptr<GeomAPI_XYZ> aCenterPointXYZ = myCenterPoint->xyz();
110       std::shared_ptr<GeomAPI_XYZ> aStartPointXYZ = myStartPoint->xyz();
111       std::shared_ptr<GeomAPI_XYZ> aEndPointXYZ = myEndPoint->xyz();
112       std::shared_ptr<GeomAPI_XYZ> vectCenterPointStartPoint =
113         aStartPointXYZ->decreased(aCenterPointXYZ);
114       std::shared_ptr<GeomAPI_XYZ> vectCenterPointEndPoint =
115         aEndPointXYZ->decreased(aCenterPointXYZ);
116       std::shared_ptr<GeomAPI_XYZ> crossProduct =
117         vectCenterPointStartPoint->cross(vectCenterPointEndPoint);
118       std::shared_ptr<GeomAPI_Pnt> aOriginPnt =
119         std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(0.,0.,0.));
120       std::shared_ptr<GeomAPI_XYZ> aOriginXYZ = aOriginPnt->xyz();
121
122       if (crossProduct->distance(aOriginXYZ) < Precision::Confusion()) {
123         myError = "Rotation builder :: center point, start point and end point are on a line.";
124         return false;
125       }
126       return true;
127     }
128     default: {
129       myError = "Rotation builder :: method not implemented.";
130       return false;
131     }
132   }
133 }
134
135 //=================================================================================================
136 void GeomAlgoAPI_Rotation::build()
137 {
138   gp_Trsf* aTrsf = new gp_Trsf();
139
140   switch (myMethodType) {
141     case BY_ANGLE: {
142       const gp_Ax1& anAxis = myAxis->impl<gp_Ax1>();
143       aTrsf->SetRotation(anAxis, myAngle/180.0*M_PI);
144       break;
145     }
146     case BY_POINTS: {
147       const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
148       const gp_Pnt& aStartPoint = myStartPoint->impl<gp_Pnt>();
149       const gp_Pnt& aEndPoint = myEndPoint->impl<gp_Pnt>();
150       gp_Vec aVec1(aCenterPoint, aStartPoint);
151       gp_Vec aVec2(aCenterPoint, aEndPoint);
152       gp_Dir aDir(aVec1^aVec2);
153       gp_Ax1 anAxis(aCenterPoint, aDir);
154       double anAngle = aVec1.Angle(aVec2);
155       if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI;
156       aTrsf->SetRotation(anAxis, anAngle);
157       break;
158     }
159     default: {
160       myError = "Rotation builder :: method not supported";
161       return;
162     }
163   }
164
165   const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
166
167   if(aSourceShape.IsNull()) {
168     myError = "Rotation builder :: source shape does not contain any actual shape.";
169     return;
170   }
171
172   // Transform the shape while copying it.
173   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true);
174   if(!aBuilder) {
175     myError = "Rotation builder :: transform initialization failed.";
176     return;
177   }
178
179   setImpl(aBuilder);
180   setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
181
182   if(!aBuilder->IsDone()) {
183     myError = "Rotation builder :: algorithm failed.";
184     return;
185   }
186
187   TopoDS_Shape aResult = aBuilder->Shape();
188
189   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
190   aShape->setImpl(new TopoDS_Shape(aResult));
191   setShape(aShape);
192   setDone(true);
193 }