0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / HLRBRep / HLRBRep.cxx
1 // Created on: 1992-08-27
2 // Created by: Christophe MARION
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 <HLRBRep.ixx>
18 #include <BRepLib_MakeEdge2d.hxx>
19 #include <Geom2d_BezierCurve.hxx>
20 #include <Geom2d_BSplineCurve.hxx>
21 #include <Geom_BSplineCurve.hxx>
22 #include <Geom_TrimmedCurve.hxx>
23 #include <TColStd_Array1OfInteger.hxx>
24 #include <TColStd_Array1OfReal.hxx>
25 #include <TColgp_Array1OfPnt2d.hxx>
26 #include <BRep_Tool.hxx>
27 #include <TopoDS.hxx>
28 #include <TopExp.hxx>
29 #include <BRepLib_MakeVertex.hxx>
30 #include <BRep_Builder.hxx>
31
32
33 //=======================================================================
34 //function : MakeEdge
35 //purpose  : 
36 //=======================================================================
37
38 TopoDS_Edge HLRBRep::MakeEdge (const HLRBRep_Curve& ec,
39                                const Standard_Real U1,
40                                const Standard_Real U2)
41 {
42   TopoDS_Edge Edg;
43   const Standard_Real sta = ec.Parameter2d(U1);
44   const Standard_Real end = ec.Parameter2d(U2);
45
46   switch (ec.GetType())
47   {
48   case GeomAbs_Line:
49     Edg = BRepLib_MakeEdge2d(ec.Line(),sta,end);
50     break;
51     
52   case GeomAbs_Circle:
53     Edg = BRepLib_MakeEdge2d(ec.Circle(),sta,end);
54     break;
55     
56   case GeomAbs_Ellipse:
57     Edg = BRepLib_MakeEdge2d(ec.Ellipse(),sta,end);
58     break;
59     
60   case GeomAbs_Hyperbola:
61     Edg = BRepLib_MakeEdge2d(ec.Hyperbola(),sta,end);
62     break;
63     
64   case GeomAbs_Parabola:
65     Edg = BRepLib_MakeEdge2d(ec.Parabola(),sta,end);
66     break;
67     
68   case GeomAbs_BezierCurve: {
69     TColgp_Array1OfPnt2d Poles(1,ec.NbPoles());
70     Handle(Geom2d_BezierCurve) ec2d;
71     if (ec.IsRational()) {
72       TColStd_Array1OfReal Weights(1,ec.NbPoles());
73       ec.PolesAndWeights(Poles,Weights);
74       ec2d = new Geom2d_BezierCurve(Poles,Weights);
75     }
76     else {
77       ec.Poles(Poles);
78       ec2d = new Geom2d_BezierCurve(Poles);
79     }
80     BRepLib_MakeEdge2d mke2d(ec2d,sta,end);
81     if (mke2d.IsDone())
82       Edg = mke2d.Edge();
83     break;
84   }
85     
86   case GeomAbs_BSplineCurve: {
87     Handle(Geom2d_BSplineCurve) ec2d;
88     GeomAdaptor_Curve GAcurve = ec.GetCurve().Curve();
89     TopoDS_Edge anEdge = ec.GetCurve().Edge();
90     Standard_Real fpar, lpar;
91     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
92     if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
93       aCurve = (Handle(Geom_TrimmedCurve)::DownCast(aCurve))->BasisCurve();
94     Handle(Geom_BSplineCurve) BSplCurve (Handle(Geom_BSplineCurve)::DownCast(aCurve));
95     Handle(Geom_BSplineCurve) theCurve = Handle(Geom_BSplineCurve)::DownCast(BSplCurve->Copy());
96     if (theCurve->IsPeriodic() && !GAcurve.IsClosed())
97     {
98       theCurve->Segment(sta, end);
99       TColgp_Array1OfPnt2d    Poles(1, theCurve->NbPoles());
100       TColStd_Array1OfReal    knots(1, theCurve->NbKnots());
101       TColStd_Array1OfInteger mults(1, theCurve->NbKnots());
102       //-- ec.KnotsAndMultiplicities(knots,mults);
103       theCurve->Knots(knots);
104       theCurve->Multiplicities(mults);
105       if (theCurve->IsRational()) {
106         TColStd_Array1OfReal Weights(1, theCurve->NbPoles());
107         ec.PolesAndWeights(theCurve, Poles, Weights);
108         ec2d = new Geom2d_BSplineCurve(Poles, Weights, knots, mults,
109                                        theCurve->Degree(), theCurve->IsPeriodic());
110       }
111       else {
112         ec.Poles(theCurve, Poles);
113         ec2d = new Geom2d_BSplineCurve(Poles, knots, mults,
114                                        theCurve->Degree(), theCurve->IsPeriodic());
115       }
116     }
117     else
118     {
119       TColgp_Array1OfPnt2d    Poles(1,ec.NbPoles());
120       TColStd_Array1OfReal    knots(1,ec.NbKnots());
121       TColStd_Array1OfInteger mults(1,ec.NbKnots());
122       //-- ec.KnotsAndMultiplicities(knots,mults);
123       ec.Knots(knots);
124       ec.Multiplicities(mults);
125       if (ec.IsRational()) {
126         TColStd_Array1OfReal Weights(1,ec.NbPoles());
127         ec.PolesAndWeights(Poles,Weights);
128         ec2d = new Geom2d_BSplineCurve(Poles,Weights,knots,mults,ec.Degree(),ec.IsPeriodic());
129       }
130       else {
131         ec.Poles(Poles);
132         ec2d = new Geom2d_BSplineCurve(Poles,knots,mults,ec.Degree(),ec.IsPeriodic());
133       }
134     }
135     BRepLib_MakeEdge2d mke2d(ec2d, sta, end);
136     if (mke2d.IsDone())
137       Edg = mke2d.Edge();
138     break;
139   }
140   default: {
141     const Standard_Integer nbPnt = 15;
142     TColgp_Array1OfPnt2d    Poles(1,nbPnt);
143     TColStd_Array1OfReal    knots(1,nbPnt);
144     TColStd_Array1OfInteger mults(1,nbPnt);
145     mults.Init(1);
146     mults(1    ) = 2;
147     mults(nbPnt) = 2;
148     const Standard_Real step = (U2-U1)/(nbPnt-1);
149     Standard_Real par3d = U1;
150     for (Standard_Integer i = 1; i < nbPnt; i++) {
151       Poles(i) = ec.Value(par3d);
152       knots(i) = par3d;
153       par3d += step;
154     }
155     Poles(nbPnt) = ec.Value(U2);
156     knots(nbPnt) = U2;
157     
158     Handle(Geom2d_BSplineCurve) ec2d = new Geom2d_BSplineCurve(Poles,knots,mults,1);
159     BRepLib_MakeEdge2d mke2d(ec2d,sta,end);
160     if (mke2d.IsDone())
161       Edg = mke2d.Edge();
162   }
163   }
164   return Edg;
165 }
166
167 //=======================================================================
168 //function : MakeEdge3d
169 //purpose  : 
170 //=======================================================================
171
172 TopoDS_Edge HLRBRep::MakeEdge3d(const HLRBRep_Curve& ec,
173                                 const Standard_Real U1,
174                                 const Standard_Real U2)
175 {
176   TopoDS_Edge Edg;
177   //const Standard_Real sta = ec.Parameter2d(U1);
178   //const Standard_Real end = ec.Parameter2d(U2);
179
180   TopoDS_Edge anEdge = ec.GetCurve().Edge();
181   Standard_Real fpar, lpar;
182   //BRep_Tool::Range(anEdge, fpar, lpar);
183   //Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
184   BRepAdaptor_Curve BAcurve(anEdge);
185   fpar = BAcurve.FirstParameter();
186   lpar = BAcurve.LastParameter();
187   
188   Edg = TopoDS::Edge(anEdge.EmptyCopied());
189   Edg.Orientation(TopAbs_FORWARD);
190   BRep_Builder BB;
191   BB.Range(Edg, U1, U2);
192
193   //Share vertices if possible
194   TopoDS_Vertex V1, V2, V1new, V2new;
195   TopExp::Vertices(anEdge, V1, V2);
196
197   Standard_Real Tol = Precision::PConfusion();
198   if (Abs(fpar - U1) <= Tol)
199     V1new = V1;
200   else
201   {
202     gp_Pnt aPnt = BAcurve.Value(U1);
203     V1new = BRepLib_MakeVertex(aPnt);
204   }
205   if (Abs(lpar - U2) <= Tol)
206     V2new = V2;
207   else
208   {
209     gp_Pnt aPnt = BAcurve.Value(U2);
210     V2new = BRepLib_MakeVertex(aPnt);
211   }
212
213   V1new.Orientation(TopAbs_FORWARD);
214   V2new.Orientation(TopAbs_REVERSED);
215   BB.Add(Edg, V1new);
216   BB.Add(Edg, V2new);
217   return Edg;
218 }
219
220 //=======================================================================
221 //function : PolyHLRAngleAndDeflection
222 //purpose  : 
223 //=======================================================================
224
225 void 
226 HLRBRep::PolyHLRAngleAndDeflection (const Standard_Real InAngl,
227                                     Standard_Real& OutAngl,
228                                     Standard_Real& OutDefl)
229 {
230   static Standard_Real HAngMin =  1*M_PI/180;
231   static Standard_Real HAngLim =  5*M_PI/180;
232   static Standard_Real HAngMax = 35*M_PI/180;
233
234   OutAngl = InAngl;
235   if (OutAngl < HAngMin) OutAngl = HAngMin;
236   if (OutAngl > HAngMax) OutAngl = HAngMax;
237   OutAngl = HAngLim + sqrt((OutAngl - HAngMin) * (HAngMax - HAngLim) *
238                            (HAngMax - HAngLim) / (HAngMax - HAngMin));
239   OutDefl = OutAngl * OutAngl * 0.5;
240 }