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