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_CompBezierCurves2dToBSplineCurve2d.ixx>
19 #include <Precision.hxx>
20 #include <BSplCLib.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Vec2d.hxx>
25 #include <TColgp_HArray1OfPnt2d.hxx>
28 //=======================================================================
29 //function : Convert_CompBezierCurves2dToBSplineCurve2d
31 //=======================================================================
33 Convert_CompBezierCurves2dToBSplineCurve2d::
34 Convert_CompBezierCurves2dToBSplineCurve2d(
35 const Standard_Real AngularTolerance) :
36 myAngular(AngularTolerance),
37 myDone(Standard_False)
42 //=======================================================================
45 //=======================================================================
47 void Convert_CompBezierCurves2dToBSplineCurve2d::AddCurve
48 (const TColgp_Array1OfPnt2d& Poles)
50 if ( !mySequence.IsEmpty()) {
52 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
53 P2 = Poles(Poles.Lower());
55 // User defined tolerance NYI
56 // Standard_ConstructionError_Raise_if
57 // ( !P1.IsEqual(P2,Precision::Confusion()),
58 // "Convert_CompBezierCurves2dToBSplineCurve2d::Addcurve");
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);
69 //=======================================================================
72 //=======================================================================
74 Standard_Integer Convert_CompBezierCurves2dToBSplineCurve2d::Degree()
80 //=======================================================================
83 //=======================================================================
85 Standard_Integer Convert_CompBezierCurves2dToBSplineCurve2d::NbPoles()
87 return CurvePoles.Length();
91 //=======================================================================
94 //=======================================================================
96 void Convert_CompBezierCurves2dToBSplineCurve2d::Poles
97 (TColgp_Array1OfPnt2d& Poles) const
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++);
107 //=======================================================================
110 //=======================================================================
112 Standard_Integer Convert_CompBezierCurves2dToBSplineCurve2d::NbKnots()
114 return CurveKnots.Length();
118 //=======================================================================
119 //function : KnotsAndMults
121 //=======================================================================
123 void Convert_CompBezierCurves2dToBSplineCurve2d::KnotsAndMults
124 (TColStd_Array1OfReal& Knots,
125 TColStd_Array1OfInteger& Mults ) const
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++);
134 for (i = LowerM; i <= UpperM; i++) {
135 Mults(i) = KnotsMultiplicities(k++);
143 //=======================================================================
146 //=======================================================================
148 void Convert_CompBezierCurves2dToBSplineCurve2d::Perform()
150 myDone = Standard_True;
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);
162 for ( i = 1; i <= mySequence.Length(); i++) {
163 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
166 Standard_Real D1, D2, Lambda, Det=0;
168 Standard_Integer Deg, Inc, MaxDegree = myDegree;
169 TColgp_Array1OfPnt2d Points(1, myDegree+1);
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;
176 BSplCLib::IncreaseDegree(myDegree,
177 mySequence(i)->Array1(), PLib::NoWeights(),
178 Points, PLib::NoWeights());
181 Points = mySequence(i)->Array1();
184 // 2- Process the node of junction between Bezier curves.
186 // Processing of initial node of the BSpline.
187 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
188 CurvePoles.Append(Points(j));
190 CurveKnVals(1) = 1.; // To begin the series.
191 KnotsMultiplicities.Append(MaxDegree+1);
199 gp_Vec2d V1(P1, P2), V2(P2, P3);
200 D1 = P1.SquareDistance(P2);
201 D2 = P3.SquareDistance(P2);
202 Lambda = Sqrt(D2/D1);
205 // Processing of the tangency between the Bezier and the previous.
206 // This allows guaranteeing at least continuity C1 if the tangents are coherent.
209 // Test of angle at myAngular
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);
220 CurveKnVals(i) = 1.0e0 ;
221 Det += CurveKnVals(i) ;
222 CurvePoles.Append(Points(1));
223 KnotsMultiplicities.Append(MaxDegree);
227 for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
228 CurvePoles.Append(Points(j));
235 // Process end node of the BSpline.
236 CurvePoles.Append(Points(MaxDegree+1));
237 KnotsMultiplicities.Append(MaxDegree+1);
239 P1 = Points(MaxDegree);
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));
247 CurveKnots.Append(1.0);