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