0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / BndLib / BndLib_Add3dCurve.cxx
1 // Copyright (c) 1996-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <BndLib_Add3dCurve.ixx>
16 #include <GeomAbs_CurveType.hxx>
17 #include <BndLib.hxx>
18 #include <TColgp_Array1OfPnt.hxx>
19 #include <gp_Pnt.hxx>
20 #include <Geom_BezierCurve.hxx>
21 #include <Geom_BSplineCurve.hxx>
22 #include <gp_Lin.hxx>
23 #include <gp_Circ.hxx>
24 #include <gp_Elips.hxx>
25 #include <gp_Parab.hxx>
26 #include <gp_Hypr.hxx>
27 #include <Precision.hxx>
28 #include <TColStd_Array1OfReal.hxx>
29 #include <TColStd_Array1OfInteger.hxx>
30
31 #include <ElCLib.hxx>
32
33 #include <gp_Pnt.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35
36 //=======================================================================
37 //function : Add
38 //purpose  : 
39 //=======================================================================
40
41 void BndLib_Add3dCurve::Add( const Adaptor3d_Curve& C,
42                            const Standard_Real Tol,
43                                  Bnd_Box&      B )
44 {
45   BndLib_Add3dCurve::Add(C,
46                          C.FirstParameter(),
47                          C.LastParameter (),
48                          Tol,B);
49 }
50
51 //OCC566(apo)->
52 static Standard_Real FillBox(Bnd_Box& B, const Adaptor3d_Curve& C, 
53                              const Standard_Real first, const Standard_Real last, 
54                              const Standard_Integer N)
55 {
56   gp_Pnt P1, P2, P3;
57   C.D0(first,P1);  B.Add(P1);
58   Standard_Real p = first, dp = last-first, tol= 0.;
59   if(Abs(dp) > Precision::PConfusion()){
60     Standard_Integer i;
61     dp /= 2*N; 
62     for(i = 1; i <= N; i++){
63       p += dp;  C.D0(p,P2);  B.Add(P2);
64       p += dp;  C.D0(p,P3);  B.Add(P3);
65       gp_Pnt Pc((P1.XYZ()+P3.XYZ())/2.0);
66       tol = Max(tol,Pc.Distance(P2));
67       P1 = P3;
68     }
69   }else{
70     C.D0(first,P1);  B.Add(P1);
71     C.D0(last,P3);  B.Add(P3);
72     tol = 0.;
73   }
74   return tol;
75 }
76 //<-OCC566(apo)
77 //=======================================================================
78 //function : Add
79 //purpose  : 
80 //=======================================================================
81
82 void BndLib_Add3dCurve::Add( const Adaptor3d_Curve& C,
83                            const Standard_Real U1,
84                            const Standard_Real U2,
85                            const Standard_Real Tol,
86                                  Bnd_Box&      B )
87 {
88   static Standard_Real weakness = 1.5;  //OCC566(apo)
89   Standard_Real tol = 0.0;
90   switch (C.GetType()) {
91
92   case GeomAbs_Line: 
93     {
94       BndLib::Add(C.Line(),U1,U2,Tol,B);
95       break;
96     }
97   case GeomAbs_Circle: 
98     {
99       BndLib::Add(C.Circle(),U1,U2,Tol,B);
100       break;
101     }
102   case GeomAbs_Ellipse: 
103     {
104       BndLib::Add(C.Ellipse(),U1,U2,Tol,B);
105       break;
106     }
107   case GeomAbs_Hyperbola: 
108     {
109       BndLib::Add(C.Hyperbola(),U1,U2,Tol,B);
110       break;
111     }
112   case GeomAbs_Parabola: 
113     {
114       BndLib::Add(C.Parabola(),U1,U2,Tol,B);
115       break;
116     }
117   case GeomAbs_BezierCurve: 
118     {
119       Handle(Geom_BezierCurve) Bz = C.Bezier();
120       //OCC566(apo)->
121       Standard_Integer N = Bz->Degree();
122       GeomAdaptor_Curve GACurve(Bz);
123       Bnd_Box B1;
124       tol = FillBox(B1,GACurve,U1,U2,N);
125       B1.Enlarge(weakness*tol);
126       Standard_Real x, y, z, X, Y, Z;
127       B1.Get(x, y, z, X, Y, Z);
128       B.Update(x, y, z, X, Y, Z);
129       B.Enlarge(Tol);
130       //<-OCC566(apo)
131       break;
132     }
133   case GeomAbs_BSplineCurve: 
134     {
135       Handle(Geom_BSplineCurve) Bs = C.BSpline();
136       if(Abs(Bs->FirstParameter() - U1) > Precision::Parametric(Tol)||
137          Abs(Bs->LastParameter()  - U2) > Precision::Parametric(Tol)) {
138
139         Handle(Geom_Geometry) G = Bs->Copy();
140         Handle(Geom_BSplineCurve)& Bsaux = Handle(Geom_BSplineCurve)::DownCast (G);
141         Standard_Real u1 = U1, u2 = U2;
142         //// modified by jgv, 24.10.01 for BUC61031 ////
143         if (Bsaux->IsPeriodic())
144           ElCLib::AdjustPeriodic( Bsaux->FirstParameter(), Bsaux->LastParameter(), Precision::PConfusion(), u1, u2 );
145         else {
146           ////////////////////////////////////////////////
147           //  modified by NIZHNY-EAP Fri Dec  3 14:29:14 1999 ___BEGIN___
148           // To avoid exeption in Segment
149           if(Bsaux->FirstParameter() > U1) u1 = Bsaux->FirstParameter();
150           if(Bsaux->LastParameter()  < U2 ) u2  = Bsaux->LastParameter();
151           //  modified by NIZHNY-EAP Fri Dec  3 14:29:18 1999 ___END___
152         }
153         Bsaux->Segment(u1, u2);
154         Bs = Bsaux;
155       }
156       //OCC566(apo)->
157       Bnd_Box B1;
158       Standard_Integer k, k1 = Bs->FirstUKnotIndex(), k2 = Bs->LastUKnotIndex(),
159                        N = Bs->Degree(), NbKnots = Bs->NbKnots();
160       TColStd_Array1OfReal Knots(1,NbKnots);
161       Bs->Knots(Knots);
162       GeomAdaptor_Curve GACurve(Bs);
163       Standard_Real first = Knots(k1), last;
164       for(k = k1 + 1; k <= k2; k++){
165         last = Knots(k); 
166         tol = Max(FillBox(B1,GACurve,first,last,N), tol);
167         first = last;
168       }
169       if (!B1.IsVoid())
170       {
171         B1.Enlarge(weakness*tol);
172         Standard_Real x, y, z, X, Y, Z;
173         B1.Get(x, y, z, X, Y, Z);
174         B.Update(x, y, z, X, Y, Z);
175         B.Enlarge(Tol);
176       }
177       //<-OCC566(apo)
178       break;
179     }
180   default:
181     {
182       Bnd_Box B1;
183       static Standard_Integer N = 33;
184       tol = FillBox(B1,C,U1,U2,N);
185       B1.Enlarge(weakness*tol);
186       Standard_Real x, y, z, X, Y, Z;
187       B1.Get(x, y, z, X, Y, Z);
188       B.Update(x, y, z, X, Y, Z);
189       B.Enlarge(Tol);
190     }
191   }
192 }