0024023: Revamp the OCCT Handle -- general
[occt.git] / src / Geom2dGcc / Geom2dGcc_Circ2dTanOnRad.cxx
1 // Created on: 1992-10-21
2 // Created by: Remi GILET
3 // Copyright (c) 1992-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 #include <Geom2dGcc_Circ2dTanOnRad.ixx>
18 #include <Geom2dAdaptor_Curve.hxx>
19 #include <GccAna_Circ2dTanOnRad.hxx>
20 #include <Geom2dGcc_Circ2dTanOnRadGeo.hxx>
21 #include <Geom2dGcc_QCurve.hxx>
22 #include <GccEnt_BadQualifier.hxx>
23 #include <Geom2d_Circle.hxx>
24 #include <Geom2d_Line.hxx>
25 #include <GccEnt_QualifiedCirc.hxx>
26 #include <GccEnt_QualifiedLin.hxx>
27 #include <StdFail_NotDone.hxx>
28 #include <Standard_NegativeValue.hxx>
29 #include <Standard_OutOfRange.hxx>
30
31 Geom2dGcc_Circ2dTanOnRad::
32    Geom2dGcc_Circ2dTanOnRad (const Geom2dGcc_QualifiedCurve& Qualified1 ,
33                              const Geom2dAdaptor_Curve&      OnCurve    ,
34                              const Standard_Real             Radius     ,
35                              const Standard_Real             Tolerance  ):
36   cirsol(1,8)   ,
37   qualifier1(1,8),
38   TheSame1(1,8) ,
39   pnttg1sol(1,8),
40   par1sol(1,8)  ,
41   pararg1(1,8)  ,
42   pntcen3(1,8)   ,
43   parcen3(1,8)  
44 {
45   if (Radius < 0.) {
46     Standard_NegativeValue::Raise();
47   }
48   else {
49     Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
50     GeomAbs_CurveType Type1 = C1.GetType();
51     GeomAbs_CurveType Type2 = OnCurve.GetType();
52     Handle(Geom2d_Curve) CC1 = C1.Curve();
53     Handle(Geom2d_Curve) Con = OnCurve.Curve();
54
55 //=============================================================================
56 //                            Appel a GccAna.                                 +
57 //=============================================================================
58
59     NbrSol = 0;
60     if ((Type1 == GeomAbs_Line || Type1 == GeomAbs_Circle) &&
61         (Type2 == GeomAbs_Line || Type2 == GeomAbs_Circle)) {
62       if (Type1 == GeomAbs_Circle) {
63         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
64         gp_Circ2d c1(CCC1->Circ2d());
65         GccEnt_QualifiedCirc Qc1=GccEnt_QualifiedCirc(c1,
66                                                       Qualified1.Qualifier());
67         if (Type2 == GeomAbs_Circle) {
68           Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
69           gp_Circ2d con(CCon->Circ2d());
70           GccAna_Circ2dTanOnRad Circ(Qc1,con,Radius,Tolerance);
71           WellDone = Circ.IsDone();
72           NbrSol = Circ.NbSolutions();
73           Results(Circ);
74         }
75         else {
76           Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
77           gp_Lin2d lon(LLon->Lin2d());
78           GccAna_Circ2dTanOnRad Circ(Qc1,lon,Radius,Tolerance);
79           WellDone = Circ.IsDone();
80           NbrSol = Circ.NbSolutions();
81           Results(Circ);
82         }
83       }
84       else {
85         Handle(Geom2d_Line) LL1 = Handle(Geom2d_Line)::DownCast(CC1);
86         gp_Lin2d l1(LL1->Lin2d());
87         GccEnt_QualifiedLin Ql1=GccEnt_QualifiedLin(l1,Qualified1.Qualifier());
88         if (Type2 == GeomAbs_Circle) {
89           Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
90           gp_Circ2d con(CCon->Circ2d());
91           GccAna_Circ2dTanOnRad Circ(Ql1,con,Radius,Tolerance);
92           WellDone = Circ.IsDone();
93           NbrSol = Circ.NbSolutions();
94           Results(Circ);
95         }
96         else {
97           Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
98           gp_Lin2d lon(LLon->Lin2d());
99           GccAna_Circ2dTanOnRad Circ(Ql1,lon,Radius,Tolerance);
100           WellDone = Circ.IsDone();
101           NbrSol = Circ.NbSolutions();
102           Results(Circ);
103         }
104       }
105     }
106
107 //=============================================================================
108 //                            Appel a GccGeo.                                 +
109 //=============================================================================
110
111     else {
112       if (Type1 == GeomAbs_Circle) {
113         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
114         gp_Circ2d c1(CCC1->Circ2d());
115         GccEnt_QualifiedCirc Qc1=GccEnt_QualifiedCirc(c1,
116                                                       Qualified1.Qualifier());
117         Geom2dGcc_Circ2dTanOnRadGeo CircGeo(Qc1,OnCurve,Radius,Tolerance);
118         WellDone = CircGeo.IsDone();
119         NbrSol = CircGeo.NbSolutions();
120         Results(CircGeo);
121       }
122       else if (Type1 == GeomAbs_Line) {
123         Handle(Geom2d_Line) LL1 = Handle(Geom2d_Line)::DownCast(CC1);
124         gp_Lin2d l1(LL1->Lin2d());
125         GccEnt_QualifiedLin Ql1=GccEnt_QualifiedLin(l1,Qualified1.Qualifier());
126         Geom2dGcc_Circ2dTanOnRadGeo CircGeo(Ql1,OnCurve,Radius,Tolerance);
127         WellDone = CircGeo.IsDone();
128         NbrSol = CircGeo.NbSolutions();
129         Results(CircGeo);
130       }
131       else {
132         Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
133         Geom2dGcc_Circ2dTanOnRadGeo CircGeo(Qc1,OnCurve,Radius,Tolerance);
134         WellDone = CircGeo.IsDone();
135         NbrSol = CircGeo.NbSolutions();
136         Results(CircGeo);
137       }
138     }
139   }
140 }
141
142 Geom2dGcc_Circ2dTanOnRad::
143    Geom2dGcc_Circ2dTanOnRad (const Handle(Geom2d_Point)&     Point1     ,
144                              const Geom2dAdaptor_Curve&     OnCurve    ,
145                              const Standard_Real             Radius     ,
146                              const Standard_Real             Tolerance  ):
147   cirsol(1,8)   ,
148   qualifier1(1,8),
149   TheSame1(1,8) ,
150   pnttg1sol(1,8),
151   par1sol(1,8)  ,
152   pararg1(1,8)  ,
153   pntcen3(1,8)   ,
154   parcen3(1,8)  
155 {
156   if (Radius < 0.) {
157     Standard_NegativeValue::Raise();
158   }
159   else {
160     gp_Pnt2d point1(Point1->Pnt2d());
161     GeomAbs_CurveType Type2 = OnCurve.GetType();
162     Handle(Geom2d_Curve) Con = OnCurve.Curve();
163
164 //=============================================================================
165 //                            Appel a GccAna.                                 +
166 //=============================================================================
167
168     NbrSol = 0;
169     if (Type2 == GeomAbs_Line || Type2 == GeomAbs_Circle) {
170       if (Type2 == GeomAbs_Circle) {
171         Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
172         gp_Circ2d con(CCon->Circ2d());
173         GccAna_Circ2dTanOnRad Circ(point1,con,Radius,Tolerance);
174         WellDone = Circ.IsDone();
175         NbrSol = Circ.NbSolutions();
176         Results(Circ);
177       }
178       else {
179         Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
180         gp_Lin2d lon(LLon->Lin2d());
181         GccAna_Circ2dTanOnRad Circ(point1,lon,Radius,Tolerance);
182         WellDone = Circ.IsDone();
183         NbrSol = Circ.NbSolutions();
184         Results(Circ);
185       }
186     }
187
188 //=============================================================================
189 //                            Appel a GccGeo.                                 +
190 //=============================================================================
191
192     else {
193       Geom2dGcc_Circ2dTanOnRadGeo CircGeo(point1,OnCurve,Radius,Tolerance);
194       WellDone = CircGeo.IsDone();
195       NbrSol = CircGeo.NbSolutions();
196       Results(CircGeo);
197     }
198   }
199 }
200
201 void Geom2dGcc_Circ2dTanOnRad::Results(const GccAna_Circ2dTanOnRad& Circ)
202 {
203   for (Standard_Integer j = 1; j <= NbrSol; j++) {
204     cirsol(j)   = Circ.ThisSolution(j);
205     if (Circ.IsTheSame1(j)) { TheSame1(j) = 1; }
206     else {TheSame1(j) = 0; }
207     Circ.Tangency1(j,par1sol(j),pararg1(j),pnttg1sol(j));
208     Circ.CenterOn3(j,parcen3(j),pntcen3(j));
209     Circ.WhichQualifier(j,qualifier1(j));
210   }
211 }
212
213 void Geom2dGcc_Circ2dTanOnRad::Results(const Geom2dGcc_Circ2dTanOnRadGeo& Circ)
214 {
215   for (Standard_Integer j = 1; j <= NbrSol; j++) {
216     cirsol(j)   = Circ.ThisSolution(j);
217     if (Circ.IsTheSame1(j)) { TheSame1(j) = 1; }
218     else {TheSame1(j) = 0; }
219     Circ.Tangency1(j,par1sol(j),pararg1(j),pnttg1sol(j));
220     Circ.CenterOn3(j,parcen3(j),pntcen3(j));
221     Circ.WhichQualifier(j,qualifier1(j));
222   }
223 }
224
225 Standard_Boolean Geom2dGcc_Circ2dTanOnRad::
226    IsDone () const { return WellDone; }
227
228 Standard_Integer Geom2dGcc_Circ2dTanOnRad::
229   NbSolutions () const 
230
231   return NbrSol;
232 }
233
234 gp_Circ2d Geom2dGcc_Circ2dTanOnRad::
235   ThisSolution (const Standard_Integer Index) const 
236 {
237   if (!WellDone) { StdFail_NotDone::Raise(); }
238   if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
239   return cirsol(Index);
240 }
241
242 void Geom2dGcc_Circ2dTanOnRad::
243   WhichQualifier (const Standard_Integer Index,
244                         GccEnt_Position& Qualif1) const
245 {
246   if (!WellDone) { StdFail_NotDone::Raise(); }
247   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
248   else { Qualif1 = qualifier1(Index); }
249 }
250
251 void Geom2dGcc_Circ2dTanOnRad::
252   Tangency1 (const Standard_Integer Index,
253                    Standard_Real&   ParSol,
254                    Standard_Real&   ParArg,
255                    gp_Pnt2d&        PntSol) const
256 {
257   if (!WellDone) { StdFail_NotDone::Raise(); }
258   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
259   else {
260     if (TheSame1(Index) == 0) {
261       ParSol = par1sol(Index);
262       ParArg = pararg1(Index);
263       PntSol = pnttg1sol(Index);
264     }
265     else { StdFail_NotDone::Raise(); }
266   }
267 }
268
269 void Geom2dGcc_Circ2dTanOnRad::
270    CenterOn3 (const Standard_Integer Index,
271               Standard_Real& ParArg,
272               gp_Pnt2d& PntSol) const
273 {
274   if (!WellDone) { StdFail_NotDone::Raise(); }
275   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
276   else {
277     ParArg = parcen3(Index);
278     PntSol = pntcen3(Index);
279   }
280 }
281
282 Standard_Boolean Geom2dGcc_Circ2dTanOnRad::
283    IsTheSame1 (const Standard_Integer Index) const
284 {
285   if (!WellDone) { StdFail_NotDone::Raise(); }
286   if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
287   if (TheSame1(Index) == 0) { return Standard_False; }
288   return Standard_True; 
289 }
290
291