0022873: Minor correction in ShapeConstruct_ProjectCurveOnSurface.cxx
[occt.git] / src / ShapeConstruct / ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cxx
CommitLineData
7fd59977 1// File: ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.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//rln 20.06.99 work-around
9
10#include <ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.ixx>
11
12#include <Precision.hxx>
13#include <BSplCLib.hxx>
14#include <PLib.hxx>
15#include <gp_Pnt2d.hxx>
16#include <gp_Vec2d.hxx>
17#include <gp.hxx>
18#include <TColgp_HArray1OfPnt2d.hxx>
19
20
21//=======================================================================
22//function : ShapeConstruct_CompBezierCurves2dToBSplineCurve2d
23//purpose :
24//=======================================================================
25
26ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::
27ShapeConstruct_CompBezierCurves2dToBSplineCurve2d(
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 ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::AddCurve
41 (const TColgp_Array1OfPnt2d& Poles)
42{
43 if ( !mySequence.IsEmpty()) {
44 gp_Pnt2d P1,P2;
45 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
46 P2 = Poles(Poles.Lower());
47
48// User defined tolerance NYI
49// Standard_ConstructionError_Raise_if
50// ( !P1.IsEqual(P2,Precision::Confusion()),
51// "ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Addcurve");
52
53 }
54 myDone = Standard_False;
55 Handle(TColgp_HArray1OfPnt2d) HPoles =
56 new TColgp_HArray1OfPnt2d(Poles.Lower(),Poles.Upper());
57 HPoles->ChangeArray1() = Poles;
58 mySequence.Append(HPoles);
59}
60
61
62//=======================================================================
63//function : Degree
64//purpose :
65//=======================================================================
66
67Standard_Integer ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Degree()
68const {
69 return myDegree;
70}
71
72
73//=======================================================================
74//function : NbPoles
75//purpose :
76//=======================================================================
77
78Standard_Integer ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::NbPoles()
79const {
80 return CurvePoles.Length();
81}
82
83
84//=======================================================================
85//function : Poles
86//purpose :
87//=======================================================================
88
89void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Poles
90 (TColgp_Array1OfPnt2d& Poles) const
91{
92 Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
93 Standard_Integer k = 1;
94 for (i = Lower; i <= Upper; i++) {
95 Poles(i) = CurvePoles(k++);
96 }
97}
98
99
100//=======================================================================
101//function : NbKnots
102//purpose :
103//=======================================================================
104
105Standard_Integer ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::NbKnots()
106const {
107 return CurveKnots.Length();
108}
109
110
111//=======================================================================
112//function : KnotsAndMults
113//purpose :
114//=======================================================================
115
116void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::KnotsAndMults
117 (TColStd_Array1OfReal& Knots,
118 TColStd_Array1OfInteger& Mults ) const
119{
120 Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
121 Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
122 Standard_Integer k = 1;
123 for (i = LowerK; i <= UpperK; i++) {
124 Knots(i) = CurveKnots(k++);
125 }
126 k = 1;
127 for (i = LowerM; i <= UpperM; i++) {
128 Mults(i) = KnotsMultiplicities(k++);
129 }
130}
131
132
133
134
135
136//=======================================================================
137//function : Perform
138//purpose :
139//=======================================================================
140
141void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Perform()
142{
143 myDone = Standard_True;
144 CurvePoles.Clear();
145 CurveKnots.Clear();
146 KnotsMultiplicities.Clear();
147 Standard_Integer LowerI = 1;
148 Standard_Integer UpperI = mySequence.Length();
149 Standard_Integer NbrCurv = UpperI-LowerI+1;
150 TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
151
152 Standard_Integer i;
153 myDegree = 0;
154 for ( i = 1; i <= mySequence.Length(); i++) {
155 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
156 }
157
158 Standard_Real D1, D2, Lambda, Det=0.;
159 gp_Pnt2d P1, P2, P3;
160 Standard_Integer Deg, Inc, MaxDegree = myDegree;
161 TColgp_Array1OfPnt2d Points(1, myDegree+1);
162
163 for (i = LowerI ; i <= UpperI ; i++) {
164 // 1- Elever la courbe de Bezier au degre maximum.
165 Deg = mySequence(i)->Length()-1;
166 Inc = myDegree - Deg;
167 if ( Inc > 0) {
168 BSplCLib::IncreaseDegree(myDegree,
169 mySequence(i)->Array1(), PLib::NoWeights(),
170 Points, PLib::NoWeights());
171 }
172 else {
173 Points = mySequence(i)->Array1();
174 }
175
176 // 2- Traiter le noeud de jonction entre 2 courbes de Bezier.
177 if (i == LowerI) {
178 // Traitement du noeud initial de la BSpline.
179 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
180 CurvePoles.Append(Points(j));
181 }
182 CurveKnVals(1) = 1.; // Pour amorcer la serie.
183 KnotsMultiplicities.Append(MaxDegree+1);
184 Det = 1.;
185 }
186
187
188 if (i != LowerI) {
189 P2 = Points(1);
190 P3 = Points(2);
191 gp_Vec2d V1(P1, P2), V2(P2, P3);
192 D1 = P1.SquareDistance(P2);
193 D2 = P3.SquareDistance(P2);
194 Lambda = Sqrt(D2/D1);
195
196
197 // Traitement de la tangence entre la Bezier et sa precedente.
198 // Ceci permet d''assurer au moins une continuite C1 si
199 // les tangentes sont coherentes.
200
201
202 // Test de l'angle a myAngular
203
204 if (V1.Magnitude() > gp::Resolution() &&
205 V2.Magnitude() > gp::Resolution() &&
206 V1.IsParallel(V2, myAngular) &&
207 MaxDegree > 1) {//rln 20.06.99 work-around
208 KnotsMultiplicities.Append(MaxDegree-1);
209 CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
210 Det += CurveKnVals(i);
211
212 }
213 else {
214 CurveKnVals(i) = 1.0e0 ;
215 Det += CurveKnVals(i) ;
216 CurvePoles.Append(Points(1));
217 KnotsMultiplicities.Append(MaxDegree);
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 for (i = 2 ; i <= NbrCurv ; i++) {
239 CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
240 }
241 CurveKnots.Append(1.0);
242}
243
244