1 // File: Convert_CompBezierCurves2dToBSplineCurve2d.cxx
2 // Created: Wed Oct 20 14:55:08 1993
3 // Author: Bruno DUMORTIER
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
9 #include <Convert_CompBezierCurves2dToBSplineCurve2d.ixx>
11 #include <Precision.hxx>
12 #include <BSplCLib.hxx>
14 #include <gp_Pnt2d.hxx>
15 #include <gp_Vec2d.hxx>
17 #include <TColgp_HArray1OfPnt2d.hxx>
20 //=======================================================================
21 //function : Convert_CompBezierCurves2dToBSplineCurve2d
23 //=======================================================================
25 Convert_CompBezierCurves2dToBSplineCurve2d::
26 Convert_CompBezierCurves2dToBSplineCurve2d(
27 const Standard_Real AngularTolerance) :
28 myAngular(AngularTolerance),
29 myDone(Standard_False)
34 //=======================================================================
37 //=======================================================================
39 void Convert_CompBezierCurves2dToBSplineCurve2d::AddCurve
40 (const TColgp_Array1OfPnt2d& Poles)
42 if ( !mySequence.IsEmpty()) {
44 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
45 P2 = Poles(Poles.Lower());
47 // User defined tolerance NYI
48 // Standard_ConstructionError_Raise_if
49 // ( !P1.IsEqual(P2,Precision::Confusion()),
50 // "Convert_CompBezierCurves2dToBSplineCurve2d::Addcurve");
53 myDone = Standard_False;
54 Handle(TColgp_HArray1OfPnt2d) HPoles =
55 new TColgp_HArray1OfPnt2d(Poles.Lower(),Poles.Upper());
56 HPoles->ChangeArray1() = Poles;
57 mySequence.Append(HPoles);
61 //=======================================================================
64 //=======================================================================
66 Standard_Integer Convert_CompBezierCurves2dToBSplineCurve2d::Degree()
72 //=======================================================================
75 //=======================================================================
77 Standard_Integer Convert_CompBezierCurves2dToBSplineCurve2d::NbPoles()
79 return CurvePoles.Length();
83 //=======================================================================
86 //=======================================================================
88 void Convert_CompBezierCurves2dToBSplineCurve2d::Poles
89 (TColgp_Array1OfPnt2d& Poles) const
91 Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
92 Standard_Integer k = 1;
93 for (i = Lower; i <= Upper; i++) {
94 Poles(i) = CurvePoles(k++);
99 //=======================================================================
102 //=======================================================================
104 Standard_Integer Convert_CompBezierCurves2dToBSplineCurve2d::NbKnots()
106 return CurveKnots.Length();
110 //=======================================================================
111 //function : KnotsAndMults
113 //=======================================================================
115 void Convert_CompBezierCurves2dToBSplineCurve2d::KnotsAndMults
116 (TColStd_Array1OfReal& Knots,
117 TColStd_Array1OfInteger& Mults ) const
119 Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
120 Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
121 Standard_Integer k = 1;
122 for (i = LowerK; i <= UpperK; i++) {
123 Knots(i) = CurveKnots(k++);
126 for (i = LowerM; i <= UpperM; i++) {
127 Mults(i) = KnotsMultiplicities(k++);
135 //=======================================================================
138 //=======================================================================
140 void Convert_CompBezierCurves2dToBSplineCurve2d::Perform()
142 myDone = Standard_True;
145 KnotsMultiplicities.Clear();
146 Standard_Integer LowerI = 1;
147 Standard_Integer UpperI = mySequence.Length();
148 Standard_Integer NbrCurv = UpperI-LowerI+1;
149 // Standard_Integer NbKnotsSpl = NbrCurv + 1 ;
150 TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
154 for ( i = 1; i <= mySequence.Length(); i++) {
155 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
158 Standard_Real D1, D2, Lambda, Det=0;
160 Standard_Integer Deg, Inc, MaxDegree = myDegree;
161 TColgp_Array1OfPnt2d Points(1, myDegree+1);
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;
168 BSplCLib::IncreaseDegree(myDegree,
169 mySequence(i)->Array1(), PLib::NoWeights(),
170 Points, PLib::NoWeights());
173 Points = mySequence(i)->Array1();
176 // 2- Traiter le noeud de jonction entre 2 courbes de Bezier.
178 // Traitement du noeud initial de la BSpline.
179 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
180 CurvePoles.Append(Points(j));
182 CurveKnVals(1) = 1.; // Pour amorcer la serie.
183 KnotsMultiplicities.Append(MaxDegree+1);
191 gp_Vec2d V1(P1, P2), V2(P2, P3);
192 D1 = P1.SquareDistance(P2);
193 D2 = P3.SquareDistance(P2);
194 Lambda = Sqrt(D2/D1);
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.
202 // Test de l'angle a myAngular
204 if (V1.Magnitude() > gp::Resolution() &&
205 V2.Magnitude() > gp::Resolution() &&
206 V1.IsParallel(V2, myAngular )) {
207 KnotsMultiplicities.Append(MaxDegree-1);
208 CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
209 Det += CurveKnVals(i);
213 CurveKnVals(i) = 1.0e0 ;
214 Det += CurveKnVals(i) ;
215 CurvePoles.Append(Points(1));
216 KnotsMultiplicities.Append(MaxDegree);
219 // Stocker les poles.
220 for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
221 CurvePoles.Append(Points(j));
228 // Traitement du noeud terminal de la BSpline.
229 CurvePoles.Append(Points(MaxDegree+1));
230 KnotsMultiplicities.Append(MaxDegree+1);
232 P1 = Points(MaxDegree);
235 // Corriger les valeurs nodales pour les faire varier dans [0.,1.].
236 CurveKnots.Append(0.0);
237 for (i = 2 ; i <= NbrCurv ; i++) {
238 CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
240 CurveKnots.Append(1.0);