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