0024784: Move documentation in CDL files to proper location
[occt.git] / src / Convert / Convert_CompBezierCurves2dToBSplineCurve2d.cxx
1 // Created on: 1993-10-20
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 #include <Convert_CompBezierCurves2dToBSplineCurve2d.ixx>
18
19 #include <Precision.hxx>
20 #include <BSplCLib.hxx>
21 #include <PLib.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Vec2d.hxx>
24 #include <gp.hxx>
25 #include <TColgp_HArray1OfPnt2d.hxx>
26
27
28 //=======================================================================
29 //function : Convert_CompBezierCurves2dToBSplineCurve2d
30 //purpose  : 
31 //=======================================================================
32
33 Convert_CompBezierCurves2dToBSplineCurve2d::
34 Convert_CompBezierCurves2dToBSplineCurve2d(
35                   const Standard_Real AngularTolerance) :
36                   myAngular(AngularTolerance),
37                   myDone(Standard_False)
38 {
39 }
40
41
42 //=======================================================================
43 //function : AddCurve
44 //purpose  : 
45 //=======================================================================
46
47 void  Convert_CompBezierCurves2dToBSplineCurve2d::AddCurve
48   (const TColgp_Array1OfPnt2d& Poles)
49 {
50   if ( !mySequence.IsEmpty()) {
51     gp_Pnt2d P1,P2;
52     P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
53     P2 = Poles(Poles.Lower());
54
55 // User defined tolerance NYI
56 //    Standard_ConstructionError_Raise_if
57 //      ( !P1.IsEqual(P2,Precision::Confusion()),
58 //       "Convert_CompBezierCurves2dToBSplineCurve2d::Addcurve");
59
60   }
61   myDone = Standard_False;
62   Handle(TColgp_HArray1OfPnt2d) HPoles = 
63     new TColgp_HArray1OfPnt2d(Poles.Lower(),Poles.Upper());
64   HPoles->ChangeArray1() = Poles;
65   mySequence.Append(HPoles);
66 }
67
68
69 //=======================================================================
70 //function : Degree
71 //purpose  : 
72 //=======================================================================
73
74 Standard_Integer  Convert_CompBezierCurves2dToBSplineCurve2d::Degree()
75 const {
76   return myDegree;
77 }
78
79
80 //=======================================================================
81 //function : NbPoles
82 //purpose  : 
83 //=======================================================================
84
85 Standard_Integer  Convert_CompBezierCurves2dToBSplineCurve2d::NbPoles()
86 const {
87   return CurvePoles.Length();
88 }
89
90
91 //=======================================================================
92 //function : Poles
93 //purpose  : 
94 //=======================================================================
95
96 void  Convert_CompBezierCurves2dToBSplineCurve2d::Poles
97   (TColgp_Array1OfPnt2d& Poles) const
98 {
99   Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
100   Standard_Integer k = 1;
101   for (i = Lower; i <= Upper; i++) {
102     Poles(i) = CurvePoles(k++);
103   }
104 }
105
106
107 //=======================================================================
108 //function : NbKnots
109 //purpose  : 
110 //=======================================================================
111
112 Standard_Integer  Convert_CompBezierCurves2dToBSplineCurve2d::NbKnots()
113 const {
114   return CurveKnots.Length();
115 }
116
117
118 //=======================================================================
119 //function : KnotsAndMults
120 //purpose  : 
121 //=======================================================================
122
123 void  Convert_CompBezierCurves2dToBSplineCurve2d::KnotsAndMults
124   (TColStd_Array1OfReal&    Knots, 
125    TColStd_Array1OfInteger& Mults ) const
126 {
127   Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
128   Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
129   Standard_Integer k = 1;
130   for (i = LowerK; i <= UpperK; i++) {
131     Knots(i) = CurveKnots(k++);
132   }
133   k = 1;
134   for (i = LowerM; i <= UpperM; i++) {
135     Mults(i) = KnotsMultiplicities(k++);
136   }
137 }
138
139
140
141
142
143 //=======================================================================
144 //function : Perform
145 //purpose  : 
146 //=======================================================================
147
148 void Convert_CompBezierCurves2dToBSplineCurve2d::Perform() 
149 {
150   myDone = Standard_True;
151   CurvePoles.Clear();
152   CurveKnots.Clear();
153   KnotsMultiplicities.Clear();
154   Standard_Integer LowerI     = 1;
155   Standard_Integer UpperI     = mySequence.Length();
156   Standard_Integer NbrCurv    = UpperI-LowerI+1;
157 //  Standard_Integer NbKnotsSpl = NbrCurv + 1 ;
158   TColStd_Array1OfReal     CurveKnVals         (1,NbrCurv);
159
160   Standard_Integer i;
161   myDegree = 0;
162   for ( i = 1; i <= mySequence.Length(); i++) {
163     myDegree = Max( myDegree, (mySequence(i))->Length() -1);
164   }
165
166   Standard_Real D1, D2, Lambda, Det=0;
167   gp_Pnt2d P1, P2, P3;
168   Standard_Integer Deg, Inc, MaxDegree = myDegree;
169   TColgp_Array1OfPnt2d Points(1, myDegree+1);
170
171   for (i = LowerI ; i <= UpperI ; i++) {
172     // 1- Rise Bezier curve to the maximum degree.
173     Deg = mySequence(i)->Length()-1;
174     Inc = myDegree - Deg;
175     if ( Inc > 0) {
176       BSplCLib::IncreaseDegree(myDegree, 
177                                mySequence(i)->Array1(), PLib::NoWeights(),
178                                Points, PLib::NoWeights());
179     }
180     else {
181       Points = mySequence(i)->Array1();
182     }
183
184     // 2- Process the node of junction between Bezier curves.
185     if (i == LowerI) {
186       // Processing of initial node of the BSpline.
187       for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
188         CurvePoles.Append(Points(j));
189       }
190       CurveKnVals(1)         = 1.; // To begin the series.
191       KnotsMultiplicities.Append(MaxDegree+1);
192       Det = 1.;
193     }
194
195
196     if (i != LowerI) {
197       P2 = Points(1);
198       P3 = Points(2);
199       gp_Vec2d V1(P1, P2), V2(P2, P3);
200       D1 = P1.SquareDistance(P2);
201       D2 = P3.SquareDistance(P2);
202       Lambda = Sqrt(D2/D1);
203
204
205       // Processing of the tangency between the Bezier and the previous.
206       // This allows guaranteeing at least continuity C1 if the tangents are coherent.
207       
208
209       // Test of angle at myAngular
210
211       if (V1.Magnitude() > gp::Resolution() &&
212           V2.Magnitude() > gp::Resolution() &&
213           V1.IsParallel(V2, myAngular )) {
214         KnotsMultiplicities.Append(MaxDegree-1);
215         CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
216         Det += CurveKnVals(i);
217
218       }
219       else {
220         CurveKnVals(i) = 1.0e0 ;
221         Det += CurveKnVals(i) ;
222         CurvePoles.Append(Points(1));
223         KnotsMultiplicities.Append(MaxDegree);
224       }
225
226       // Store poles.
227       for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
228         CurvePoles.Append(Points(j));
229       }
230
231     }
232
233
234     if (i == UpperI) {
235       // Process end node of the BSpline.
236       CurvePoles.Append(Points(MaxDegree+1));
237       KnotsMultiplicities.Append(MaxDegree+1);
238     }
239     P1 = Points(MaxDegree);
240   }
241
242   // Correct nodal values to make them variable within [0.,1.].
243   CurveKnots.Append(0.0);
244   for (i = 2 ; i <= NbrCurv ; i++) {
245     CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
246   }
247   CurveKnots.Append(1.0);
248 }
249
250