0027677: Incorrect CUT of a solid by semi-infinite solid
[occt.git] / src / ProjLib / ProjLib_Cylinder.cxx
1 // Created on: 1993-08-24
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <gp_Ax3.hxx>
19 #include <gp_Circ.hxx>
20 #include <gp_Cylinder.hxx>
21 #include <gp_Elips.hxx>
22 #include <gp_Hypr.hxx>
23 #include <gp_Lin.hxx>
24 #include <gp_Parab.hxx>
25 #include <gp_Pln.hxx>
26 #include <gp_Trsf.hxx>
27 #include <gp_Vec.hxx>
28 #include <gp_Vec2d.hxx>
29 #include <Precision.hxx>
30 #include <ProjLib_Cylinder.hxx>
31 #include <Standard_NoSuchObject.hxx>
32 #include <Standard_NotImplemented.hxx>
33
34 //=======================================================================
35 //function : ProjLib_Cylinder
36 //purpose  : 
37 //=======================================================================
38 ProjLib_Cylinder::ProjLib_Cylinder()
39 {
40 }
41
42
43 //=======================================================================
44 //function : ProjLib_Cylinder
45 //purpose  : 
46 //=======================================================================
47
48 ProjLib_Cylinder::ProjLib_Cylinder(const gp_Cylinder& Cyl)
49 {
50   Init(Cyl);
51 }
52
53
54 //=======================================================================
55 //function : ProjLib_Cylinder
56 //purpose  : 
57 //=======================================================================
58
59 ProjLib_Cylinder::ProjLib_Cylinder(const gp_Cylinder& Cyl, const gp_Lin& L)
60 {
61   Init(Cyl);
62   Project(L);
63 }
64
65
66 //=======================================================================
67 //function : ProjLib_Cylinder
68 //purpose  : 
69 //=======================================================================
70
71 ProjLib_Cylinder::ProjLib_Cylinder(const gp_Cylinder& Cyl, const gp_Circ& C)
72 {
73   Init(Cyl);
74   Project(C);
75 }
76
77
78 //=======================================================================
79 //function : ProjLib_Cylinder
80 //purpose  : 
81 //=======================================================================
82
83 ProjLib_Cylinder::ProjLib_Cylinder(const gp_Cylinder& Cyl, const gp_Elips& E)
84 {
85   Init(Cyl);
86   Project(E);
87 }
88
89
90 //=======================================================================
91 //function : Init
92 //purpose  : 
93 //=======================================================================
94
95 void  ProjLib_Cylinder::Init(const gp_Cylinder& Cyl)
96 {
97   myType = GeomAbs_OtherCurve;
98   myCylinder = Cyl;
99   myIsPeriodic = Standard_False;
100   isDone = Standard_False;
101 }
102
103
104 //=======================================================================
105 //function : EvalPnt2d / EvalDir2d
106 //purpose  : returns the Projected Pnt / Dir in the parametrization range
107 //           of myPlane.
108 //=======================================================================
109
110 static gp_Pnt2d EvalPnt2d( const gp_Pnt& P, const gp_Cylinder& Cy )
111 {
112   gp_Vec OP( Cy.Location(),P);
113   Standard_Real X = OP.Dot(gp_Vec(Cy.Position().XDirection()));
114   Standard_Real Y = OP.Dot(gp_Vec(Cy.Position().YDirection()));
115   Standard_Real Z = OP.Dot(gp_Vec(Cy.Position().Direction()));
116   Standard_Real U ;
117
118   if ( Abs(X) > Precision::PConfusion() ||
119        Abs(Y) > Precision::PConfusion() ) {
120     U = ATan2(Y,X);
121   }
122   else {
123     U = 0.;
124   }
125   return gp_Pnt2d( U, Z);
126 }
127
128
129
130 //=======================================================================
131 //function : Project
132 //purpose  : 
133 //=======================================================================
134
135 void  ProjLib_Cylinder::Project(const gp_Lin& L)
136 {
137   // Check the line is parallel to the axis of cylinder.
138   // In other cases, the projection is wrong.
139   if (L.Direction().XYZ().CrossSquareMagnitude(myCylinder.Position().Direction().XYZ()) >
140       Precision::Angular() * Precision::Angular())
141     return;
142
143   myType = GeomAbs_Line;
144
145   gp_Pnt2d P2d = EvalPnt2d(L.Location(),myCylinder);
146   if ( P2d.X() < 0.) {
147     P2d.SetX(P2d.X()+2*M_PI);
148   }
149   Standard_Real Signe 
150     = L.Direction().Dot(myCylinder.Position().Direction());
151   Signe = (Signe > 0.) ? 1. : -1.;
152   gp_Dir2d D2d(0., Signe);
153   
154   myLin = gp_Lin2d( P2d, D2d);
155   isDone = Standard_True;
156 }
157
158
159 //=======================================================================
160 //function : Project
161 //purpose  : 
162 //=======================================================================
163
164 void  ProjLib_Cylinder::Project(const gp_Circ& C)
165 {
166   // Check the circle's normal is parallel to the axis of cylinder.
167   // In other cases, the projection is wrong.
168   const gp_Ax3& aCylPos = myCylinder.Position();
169   const gp_Ax2& aCircPos = C.Position();
170   if (aCylPos.Direction().XYZ().CrossSquareMagnitude(aCircPos.Direction().XYZ()) >
171       Precision::Angular() * Precision::Angular())
172     return;
173
174   myType = GeomAbs_Line;
175
176   gp_Dir ZCyl = aCylPos.XDirection().Crossed(aCylPos.YDirection());
177
178   Standard_Real U = aCylPos.XDirection().AngleWithRef(aCircPos.XDirection(), ZCyl);
179
180   gp_Vec OP( myCylinder.Location(),C.Location());
181   Standard_Real V = OP.Dot(gp_Vec(aCylPos.Direction()));
182
183   gp_Pnt2d P2d1 (U, V);
184   gp_Dir2d D2d;
185   if ( ZCyl.Dot(aCircPos.Direction()) > 0.) 
186     D2d.SetCoord(1., 0.);
187   else
188     D2d.SetCoord(-1., 0.);
189
190   myLin = gp_Lin2d(P2d1, D2d);
191   isDone = Standard_True;
192 }
193
194
195 //=======================================================================
196 //function : Project
197 //purpose  : 
198 //=======================================================================
199
200 //void  ProjLib_Cylinder::Project(const gp_Elips& E)
201 void  ProjLib_Cylinder::Project(const gp_Elips& )
202 {
203   // Pour de vastes raisons de periodicite mal gerees,
204   // la projection d`une ellipse sur un cylindre sera passee aux approx.
205   
206   
207 }
208
209 void  ProjLib_Cylinder::Project(const gp_Parab& P)
210 {
211  ProjLib_Projector::Project(P);
212 }
213
214 void  ProjLib_Cylinder::Project(const gp_Hypr& H)
215 {
216  ProjLib_Projector::Project(H);
217 }
218