Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Convert / Convert_CompBezierCurvesToBSplineCurve.cxx
CommitLineData
7fd59977 1// File: Convert_CompBezierCurvesToBSplineCurve.cxx
2// Created: Wed Oct 20 14:55:08 1993
3// Author: Bruno DUMORTIER
4// <dub@topsn3>
5// modified 25/06/1996 PMN : Ajout d'une tolerance Angulaire dans le
6// constructeur pour le test de continuite G1 (1 Radians c'etait trop
7// cf BUG PRO4481)
8
9#include <Convert_CompBezierCurvesToBSplineCurve.ixx>
10
11#include <Precision.hxx>
12#include <BSplCLib.hxx>
13#include <PLib.hxx>
14#include <gp_Pnt.hxx>
15#include <gp.hxx>
16#include <gp_Vec.hxx>
17#include <TColgp_HArray1OfPnt.hxx>
18
19
20//=======================================================================
21//function : Convert_CompBezierCurvesToBSplineCurve
22//purpose :
23//=======================================================================
24
25
26Convert_CompBezierCurvesToBSplineCurve::
27Convert_CompBezierCurvesToBSplineCurve(
28 const Standard_Real AngularTolerance) :
29 myAngular(AngularTolerance),
30 myDone(Standard_False)
31{
32}
33
34
35//=======================================================================
36//function : AddCurve
37//purpose :
38//=======================================================================
39
40void Convert_CompBezierCurvesToBSplineCurve::AddCurve
41 (const TColgp_Array1OfPnt& Poles)
42{
43 if ( !mySequence.IsEmpty()) {
44 gp_Pnt P1,P2;
45 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
46 P2 = Poles(Poles.Lower());
47
48 // NYI
49 if ( !P1.IsEqual(P2,Precision::Confusion()))
50 cout << "Convert_CompBezierCurvesToBSplineCurve::Addcurve" << endl;;
51 }
52 myDone = Standard_False;
53 Handle(TColgp_HArray1OfPnt) HPoles =
54 new TColgp_HArray1OfPnt(Poles.Lower(),Poles.Upper());
55 HPoles->ChangeArray1() = Poles;
56 mySequence.Append(HPoles);
57}
58
59
60//=======================================================================
61//function : Degree
62//purpose :
63//=======================================================================
64
65Standard_Integer Convert_CompBezierCurvesToBSplineCurve::Degree() const
66{
67 return myDegree;
68}
69
70
71//=======================================================================
72//function : NbPoles
73//purpose :
74//=======================================================================
75
76Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbPoles() const
77{
78 return CurvePoles.Length();
79}
80
81
82//=======================================================================
83//function : Poles
84//purpose :
85//=======================================================================
86
87void Convert_CompBezierCurvesToBSplineCurve::Poles
88 (TColgp_Array1OfPnt& Poles) const
89{
90 Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
91 Standard_Integer k = 1;
92 for (i = Lower; i <= Upper; i++) {
93 Poles(i) = CurvePoles(k++);
94 }
95}
96
97
98//=======================================================================
99//function : NbKnots
100//purpose :
101//=======================================================================
102
103Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbKnots() const
104{
105 return CurveKnots.Length();
106}
107
108
109//=======================================================================
110//function : KnotsAndMults
111//purpose :
112//=======================================================================
113
114void Convert_CompBezierCurvesToBSplineCurve::KnotsAndMults
115 (TColStd_Array1OfReal& Knots,
116 TColStd_Array1OfInteger& Mults ) const
117{
118 Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
119 Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
120 Standard_Integer k = 1;
121 for (i = LowerK; i <= UpperK; i++) {
122 Knots(i) = CurveKnots(k++);
123 }
124 k = 1;
125 for (i = LowerM; i <= UpperM; i++) {
126 Mults(i) = KnotsMultiplicities(k++);
127 }
128}
129
130
131
132//=======================================================================
133//function : Perform
134//purpose :
135//=======================================================================
136
137void Convert_CompBezierCurvesToBSplineCurve::Perform()
138{
139 myDone = Standard_True;
140 CurvePoles.Clear();
141 CurveKnots.Clear();
142 KnotsMultiplicities.Clear();
143 Standard_Integer LowerI = 1;
144 Standard_Integer UpperI = mySequence.Length();
145 Standard_Integer NbrCurv = UpperI-LowerI+1;
146// Standard_Integer NbKnotsSpl = NbrCurv + 1 ;
147 TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
148
149 Standard_Integer i;
150 myDegree = 0;
151 for ( i = 1; i <= mySequence.Length(); i++) {
152 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
153 }
154
155 Standard_Real D1, D2, Lambda, Det=0;
156 gp_Pnt P1, P2, P3;
157 Standard_Integer Deg, Inc, MaxDegree = myDegree;
158 TColgp_Array1OfPnt Points(1, myDegree+1);
159
160 for (i = LowerI ; i <= UpperI ; i++) {
161 // 1- Elever la courbe de Bezier au degre maximum.
162 Deg = mySequence(i)->Length()-1;
163 Inc = myDegree - Deg;
164 if ( Inc > 0) {
165 BSplCLib::IncreaseDegree(myDegree,
166 mySequence(i)->Array1(), PLib::NoWeights(),
167 Points, PLib::NoWeights());
168 }
169 else {
170 Points = mySequence(i)->Array1();
171 }
172
173 // 2- Traiter le noeud de jonction entre 2 courbes de Bezier.
174 if (i == LowerI) {
175 // Traitement du noeud initial de la BSpline.
176 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
177 CurvePoles.Append(Points(j));
178 }
179 CurveKnVals(1) = 1.; // Pour amorcer la serie.
180 KnotsMultiplicities.Append(MaxDegree+1);
181 Det = 1.;
182 }
183
184
185 if (i != LowerI) {
186 P2 = Points(1);
187 P3 = Points(2);
188 gp_Vec V1(P1, P2), V2(P2, P3);
189 D1 = P1.SquareDistance(P2);
190 D2 = P3.SquareDistance(P2);
191 Lambda = Sqrt(D2/D1);
192// cout << "D1, D2, Lambda : " << D1 << " " << D2 << " " << Lambda << endl;
193
194 // Traitement de la tangence entre la Bezier et sa precedente.
195 // Ceci permet d''assurer au moins une continuite C1 si
196 // les tangentes sont coherentes.
197
198 if (V1.Magnitude() > gp::Resolution() &&
199 V2.Magnitude() > gp::Resolution() &&
200 V1.IsParallel(V2, myAngular )) {
201 if(CurveKnVals(i-1) * Lambda > 10. * Epsilon(Det)) {
202 KnotsMultiplicities.Append(MaxDegree-1);
203 CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
204 Det += CurveKnVals(i);
205 }
206 else {
207 CurvePoles.Append(Points(1));
208 KnotsMultiplicities.Append(MaxDegree);
209 CurveKnVals(i) = 1.0 ;
210 Det += CurveKnVals(i) ;
211 }
212 }
213 else {
214 CurvePoles.Append(Points(1));
215 KnotsMultiplicities.Append(MaxDegree);
216 CurveKnVals(i) = 1.0 ;
217 Det += CurveKnVals(i) ;
218 }
219
220 // Stocker les poles.
221 for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
222 CurvePoles.Append(Points(j));
223 }
224
225 }
226
227
228 if (i == UpperI) {
229 // Traitement du noeud terminal de la BSpline.
230 CurvePoles.Append(Points(MaxDegree+1));
231 KnotsMultiplicities.Append(MaxDegree+1);
232 }
233 P1 = Points(MaxDegree);
234 }
235
236 // Corriger les valeurs nodales pour les faire varier dans [0.,1.].
237 CurveKnots.Append(0.0);
238// cout << "Convert : Det = " << Det << endl;
239 for (i = 2 ; i <= NbrCurv ; i++) {
240 CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
241 }
242 CurveKnots.Append(1.0);
243}
244
245