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