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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Convert_CompBezierCurvesToBSplineCurve.ixx>
19 #include <Precision.hxx>
20 #include <BSplCLib.hxx>
25 #include <TColgp_HArray1OfPnt.hxx>
28 //=======================================================================
29 //function : Convert_CompBezierCurvesToBSplineCurve
31 //=======================================================================
34 Convert_CompBezierCurvesToBSplineCurve::
35 Convert_CompBezierCurvesToBSplineCurve(
36 const Standard_Real AngularTolerance) :
37 myAngular(AngularTolerance),
38 myDone(Standard_False)
43 //=======================================================================
46 //=======================================================================
48 void Convert_CompBezierCurvesToBSplineCurve::AddCurve
49 (const TColgp_Array1OfPnt& Poles)
51 if ( !mySequence.IsEmpty()) {
53 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
54 P2 = Poles(Poles.Lower());
57 if ( !P1.IsEqual(P2,Precision::Confusion()))
58 cout << "Convert_CompBezierCurvesToBSplineCurve::Addcurve" << endl;;
60 myDone = Standard_False;
61 Handle(TColgp_HArray1OfPnt) HPoles =
62 new TColgp_HArray1OfPnt(Poles.Lower(),Poles.Upper());
63 HPoles->ChangeArray1() = Poles;
64 mySequence.Append(HPoles);
68 //=======================================================================
71 //=======================================================================
73 Standard_Integer Convert_CompBezierCurvesToBSplineCurve::Degree() const
79 //=======================================================================
82 //=======================================================================
84 Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbPoles() const
86 return CurvePoles.Length();
90 //=======================================================================
93 //=======================================================================
95 void Convert_CompBezierCurvesToBSplineCurve::Poles
96 (TColgp_Array1OfPnt& Poles) const
98 Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
99 Standard_Integer k = 1;
100 for (i = Lower; i <= Upper; i++) {
101 Poles(i) = CurvePoles(k++);
106 //=======================================================================
109 //=======================================================================
111 Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbKnots() const
113 return CurveKnots.Length();
117 //=======================================================================
118 //function : KnotsAndMults
120 //=======================================================================
122 void Convert_CompBezierCurvesToBSplineCurve::KnotsAndMults
123 (TColStd_Array1OfReal& Knots,
124 TColStd_Array1OfInteger& Mults ) const
126 Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
127 Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
128 Standard_Integer k = 1;
129 for (i = LowerK; i <= UpperK; i++) {
130 Knots(i) = CurveKnots(k++);
133 for (i = LowerM; i <= UpperM; i++) {
134 Mults(i) = KnotsMultiplicities(k++);
140 //=======================================================================
143 //=======================================================================
145 void Convert_CompBezierCurvesToBSplineCurve::Perform()
147 myDone = Standard_True;
150 KnotsMultiplicities.Clear();
151 Standard_Integer LowerI = 1;
152 Standard_Integer UpperI = mySequence.Length();
153 Standard_Integer NbrCurv = UpperI-LowerI+1;
154 // Standard_Integer NbKnotsSpl = NbrCurv + 1 ;
155 TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
159 for ( i = 1; i <= mySequence.Length(); i++) {
160 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
165 Standard_Integer Deg, Inc, MaxDegree = myDegree;
166 TColgp_Array1OfPnt Points(1, myDegree+1);
168 for (i = LowerI ; i <= UpperI ; i++) {
169 // 1- Raise the Bezier curve to the maximum degree.
170 Deg = mySequence(i)->Length()-1;
171 Inc = myDegree - Deg;
173 BSplCLib::IncreaseDegree(myDegree,
174 mySequence(i)->Array1(), PLib::NoWeights(),
175 Points, PLib::NoWeights());
178 Points = mySequence(i)->Array1();
181 // 2- Process the node of junction between 2 Bezier curves.
183 // Processing of the initial node of the BSpline.
184 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
185 CurvePoles.Append(Points(j));
187 CurveKnVals(1) = 1.; // To begin the series.
188 KnotsMultiplicities.Append(MaxDegree+1);
196 gp_Vec V1(P1, P2), V2(P2, P3);
198 // Processing of the tangency between Bezier and the previous.
199 // This allows to guarantee at least a C1 continuity if the tangents are
202 Standard_Real D1 = V1.SquareMagnitude();
203 Standard_Real D2 = V2.SquareMagnitude();
204 if (D1 > gp::Resolution() && D2 > gp::Resolution() && V1.IsParallel(V2, myAngular )) {
205 Standard_Real Lambda = Sqrt(D2/D1);
206 if(CurveKnVals(i-1) * Lambda > 10. * Epsilon(Det)) {
207 KnotsMultiplicities.Append(MaxDegree-1);
208 CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
209 Det += CurveKnVals(i);
212 CurvePoles.Append(Points(1));
213 KnotsMultiplicities.Append(MaxDegree);
214 CurveKnVals(i) = 1.0 ;
215 Det += CurveKnVals(i) ;
219 CurvePoles.Append(Points(1));
220 KnotsMultiplicities.Append(MaxDegree);
221 CurveKnVals(i) = 1.0 ;
222 Det += CurveKnVals(i) ;
226 for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
227 CurvePoles.Append(Points(j));
234 // Processing of the end node of the BSpline.
235 CurvePoles.Append(Points(MaxDegree+1));
236 KnotsMultiplicities.Append(MaxDegree+1);
238 P1 = Points(MaxDegree);
241 // Correct nodal values to make them variable within [0.,1.].
242 CurveKnots.Append(0.0);
243 // cout << "Convert : Det = " << Det << endl;
244 for (i = 2 ; i <= NbrCurv ; i++) {
245 CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
247 CurveKnots.Append(1.0);