]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp
Salome HOME
Added MultiRotation feature (parametric API).
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Rotation.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Rotation.cpp
4 // Created:     12 May 2015
5 // Author:      Dmitry Bobylev
6
7 #include "GeomAlgoAPI_Rotation.h"
8
9 #include <GeomAPI_XYZ.h>
10
11 #include <BRepBuilderAPI_Transform.hxx>
12
13 #include <gp_Ax1.hxx>
14 #include <gp_Dir.hxx>
15 #include <gp_Vec.hxx>
16
17 #include <Precision.hxx>
18
19 //=================================================================================================
20 GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
21                                            std::shared_ptr<GeomAPI_Ax1>   theAxis,
22                                            double                         theAngle)
23 {
24   myMethodType = BY_ANGLE;
25   mySourceShape = theSourceShape;
26   myAxis = theAxis;
27   myAngle = theAngle;
28 }
29
30
31 //=================================================================================================
32 GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
33                                            std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
34                                            std::shared_ptr<GeomAPI_Pnt>   theStartPoint,
35                                            std::shared_ptr<GeomAPI_Pnt>   theEndPoint)
36 {
37   myMethodType = BY_POINTS;
38   mySourceShape = theSourceShape;
39   myCenterPoint = theCenterPoint;
40   myStartPoint = theStartPoint;
41   myEndPoint = theEndPoint;
42 }
43
44 //=================================================================================================
45 bool GeomAlgoAPI_Rotation::check()
46 {
47   switch (myMethodType) {
48     case BY_ANGLE: {
49       if (!myAxis) {
50         myError = "Rotation builder :: axis is not valid.";
51         return false;
52       }
53       if (!mySourceShape) {
54         myError = "Rotation builder :: source shape is not valid.";
55         return false;
56       }
57       return true;
58     }
59     case BY_POINTS: {
60       if (!myCenterPoint) {
61         myError = "Rotation builder :: center point is not valid.";
62         return false;
63       }
64       if (!myStartPoint) {
65         myError = "Rotation builder :: start point is not valid.";
66         return false;
67       }
68       if (!myEndPoint) {
69         myError = "Rotation builder :: end point is not valid.";
70         return false;
71       }
72       if (!mySourceShape) {
73         myError = "Rotation builder :: source shape is not valid.";
74         return false;
75       }
76       if(myCenterPoint->distance(myStartPoint) < Precision::Confusion()) {
77         myError = "Rotation builder :: center point and start point coincide.";
78         return false;
79       }
80       if(myCenterPoint->distance(myEndPoint) < Precision::Confusion()) {
81         myError = "Rotation builder :: center point and end point coincide.";
82         return false;
83       }
84       if(myStartPoint->distance(myEndPoint) < Precision::Confusion()) {
85         myError = "Rotation builder :: start point and end point coincide.";
86         return false;
87       }
88       std::shared_ptr<GeomAPI_XYZ> aCenterPointXYZ = myCenterPoint->xyz();
89       std::shared_ptr<GeomAPI_XYZ> aStartPointXYZ = myStartPoint->xyz();
90       std::shared_ptr<GeomAPI_XYZ> aEndPointXYZ = myEndPoint->xyz();
91       std::shared_ptr<GeomAPI_XYZ> vectCenterPointStartPoint =
92         aStartPointXYZ->decreased(aCenterPointXYZ);
93       std::shared_ptr<GeomAPI_XYZ> vectCenterPointEndPoint =
94         aEndPointXYZ->decreased(aCenterPointXYZ);
95       std::shared_ptr<GeomAPI_XYZ> crossProduct =
96         vectCenterPointStartPoint->cross(vectCenterPointEndPoint);
97       std::shared_ptr<GeomAPI_Pnt> aOriginPnt =
98         std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(0.,0.,0.));
99       std::shared_ptr<GeomAPI_XYZ> aOriginXYZ = aOriginPnt->xyz();
100
101       if (crossProduct->distance(aOriginXYZ) < Precision::Confusion()) {
102         myError = "Rotation builder :: center point, start point and end point are on a line.";
103         return false;
104       }
105       return true;
106     }
107     default: {
108       myError = "Rotation builder :: method not implemented.";
109       return false;
110     }
111   }
112 }
113
114 //=================================================================================================
115 void GeomAlgoAPI_Rotation::build()
116 {
117   gp_Trsf* aTrsf = new gp_Trsf();
118
119   switch (myMethodType) {
120     case BY_ANGLE: {
121       const gp_Ax1& anAxis = myAxis->impl<gp_Ax1>();
122       aTrsf->SetRotation(anAxis, myAngle/180.0*M_PI);
123       break;
124     }
125     case BY_POINTS: {
126       const gp_Pnt& aCenterPoint = myCenterPoint->impl<gp_Pnt>();
127       const gp_Pnt& aStartPoint = myStartPoint->impl<gp_Pnt>();
128       const gp_Pnt& aEndPoint = myEndPoint->impl<gp_Pnt>();
129       gp_Vec aVec1(aCenterPoint, aStartPoint);
130       gp_Vec aVec2(aCenterPoint, aEndPoint);
131       gp_Dir aDir(aVec1^aVec2);
132       gp_Ax1 anAxis(aCenterPoint, aDir);
133       double anAngle = aVec1.Angle(aVec2);
134       if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI;
135       aTrsf->SetRotation(anAxis, anAngle);
136       break;
137     }
138     default: {
139       myError = "Rotation builder :: method not supported";
140       return;
141     }
142   }
143
144   const TopoDS_Shape& aSourceShape = mySourceShape->impl<TopoDS_Shape>();
145
146   if(aSourceShape.IsNull()) {
147     myError = "Rotation builder :: source shape does not contain any actual shape.";
148     return;
149   }
150
151   // Transform the shape while copying it.
152   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true);
153   if(!aBuilder) {
154     myError = "Rotation builder :: transform initialization failed.";
155     return;
156   }
157
158   setImpl(aBuilder);
159   setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
160
161   if(!aBuilder->IsDone()) {
162     myError = "Rotation builder :: algorithm failed.";
163     return;
164   }
165
166   TopoDS_Shape aResult = aBuilder->Shape();
167
168   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
169   aShape->setImpl(new TopoDS_Shape(aResult));
170   setShape(aShape);
171   setDone(true);
172 }