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. |
b311480e |
16 | |
7fd59977 |
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 | |
7fd59977 |
22 | #include <BSplCLib.hxx> |
7fd59977 |
23 | #include <gp.hxx> |
42cf5bc1 |
24 | #include <gp_Pnt.hxx> |
7fd59977 |
25 | #include <gp_Vec.hxx> |
42cf5bc1 |
26 | #include <PLib.hxx> |
27 | #include <Precision.hxx> |
28 | #include <ShapeConstruct_CompBezierCurvesToBSplineCurve.hxx> |
29 | #include <Standard_ConstructionError.hxx> |
7fd59977 |
30 | #include <TColgp_HArray1OfPnt.hxx> |
31 | |
7fd59977 |
32 | //======================================================================= |
33 | //function : ShapeConstruct_CompBezierCurvesToBSplineCurve |
34 | //purpose : |
35 | //======================================================================= |
7fd59977 |
36 | ShapeConstruct_CompBezierCurvesToBSplineCurve:: |
37 | ShapeConstruct_CompBezierCurvesToBSplineCurve( |
38 | const Standard_Real AngularTolerance) : |
39 | myAngular(AngularTolerance), |
40 | myDone(Standard_False) |
41 | |
42 | { |
43 | } |
44 | |
45 | |
46 | //======================================================================= |
47 | //function : AddCurve |
48 | //purpose : |
49 | //======================================================================= |
50 | |
51 | void ShapeConstruct_CompBezierCurvesToBSplineCurve::AddCurve |
52 | (const TColgp_Array1OfPnt& Poles) |
53 | { |
54 | if ( !mySequence.IsEmpty()) { |
55 | gp_Pnt P1,P2; |
56 | P1 = mySequence.Last()->Value(mySequence.Last()->Upper()); |
57 | P2 = Poles(Poles.Lower()); |
58 | |
59 | // NYI |
60 | // Standard_ConstructionError_Raise_if |
61 | // ( !P1.IsEqual(P2,Precision::Confusion()), |
62 | // "ShapeConstruct_CompBezierCurvesToBSplineCurve::Addcurve"); |
63 | } |
64 | myDone = Standard_False; |
65 | Handle(TColgp_HArray1OfPnt) HPoles = |
66 | new TColgp_HArray1OfPnt(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_CompBezierCurvesToBSplineCurve::Degree() const |
78 | { |
79 | return myDegree; |
80 | } |
81 | |
82 | |
83 | //======================================================================= |
84 | //function : NbPoles |
85 | //purpose : |
86 | //======================================================================= |
87 | |
88 | Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::NbPoles() const |
89 | { |
90 | return CurvePoles.Length(); |
91 | } |
92 | |
93 | |
94 | //======================================================================= |
95 | //function : Poles |
96 | //purpose : |
97 | //======================================================================= |
98 | |
99 | void ShapeConstruct_CompBezierCurvesToBSplineCurve::Poles |
100 | (TColgp_Array1OfPnt& 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_CompBezierCurvesToBSplineCurve::NbKnots() const |
116 | { |
117 | return CurveKnots.Length(); |
118 | } |
119 | |
120 | |
121 | //======================================================================= |
122 | //function : KnotsAndMults |
123 | //purpose : |
124 | //======================================================================= |
125 | |
126 | void ShapeConstruct_CompBezierCurvesToBSplineCurve::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 | //function : Perform |
146 | //purpose : |
147 | //======================================================================= |
148 | |
149 | void ShapeConstruct_CompBezierCurvesToBSplineCurve::Perform() |
150 | { |
151 | myDone = Standard_True; |
152 | CurvePoles.Clear(); |
153 | CurveKnots.Clear(); |
154 | KnotsMultiplicities.Clear(); |
155 | Standard_Integer LowerI = 1; |
156 | Standard_Integer UpperI = mySequence.Length(); |
157 | Standard_Integer NbrCurv = UpperI-LowerI+1; |
158 | |
159 | TColStd_Array1OfReal CurveKnVals (1,NbrCurv); |
160 | |
161 | Standard_Integer i; |
162 | myDegree = 0; |
163 | for ( i = 1; i <= mySequence.Length(); i++) { |
164 | myDegree = Max( myDegree, (mySequence(i))->Length() -1); |
165 | } |
166 | |
167 | Standard_Real D1, D2, Lambda, Det=0.; |
168 | gp_Pnt P1, P2, P3; |
169 | Standard_Integer Deg, Inc, MaxDegree = myDegree; |
170 | TColgp_Array1OfPnt Points(1, myDegree+1); |
171 | |
172 | for (i = LowerI ; i <= UpperI ; i++) { |
173 | // 1- Elever la courbe de Bezier au degre maximum. |
174 | Deg = mySequence(i)->Length()-1; |
175 | Inc = myDegree - Deg; |
176 | if ( Inc > 0) { |
177 | BSplCLib::IncreaseDegree(myDegree, |
0e14656b |
178 | mySequence(i)->Array1(), BSplCLib::NoWeights(), |
179 | Points, BSplCLib::NoWeights()); |
7fd59977 |
180 | } |
181 | else { |
182 | Points = mySequence(i)->Array1(); |
183 | } |
184 | |
185 | // 2- Traiter le noeud de jonction entre 2 courbes de Bezier. |
186 | if (i == LowerI) { |
187 | // Traitement du noeud initial de la BSpline. |
188 | for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) { |
189 | CurvePoles.Append(Points(j)); |
190 | } |
191 | CurveKnVals(1) = 1.; // Pour amorcer la serie. |
192 | KnotsMultiplicities.Append(MaxDegree+1); |
193 | Det = 1.; |
194 | } |
195 | |
196 | |
197 | if (i != LowerI) { |
198 | P2 = Points(1); |
199 | P3 = Points(2); |
200 | gp_Vec V1(P1, P2), V2(P2, P3); |
201 | D1 = P1.SquareDistance(P2); |
202 | D2 = P3.SquareDistance(P2); |
203 | Lambda = Sqrt(D2/D1); |
204 | |
205 | |
206 | // Traitement de la tangence entre la Bezier et sa precedente. |
207 | // Ceci permet d''assurer au moins une continuite C1 si |
208 | // les tangentes sont coherentes. |
209 | |
210 | if (V1.Magnitude() > gp::Resolution() && |
211 | V2.Magnitude() > gp::Resolution() && |
212 | V1.IsParallel(V2, myAngular ) && |
213 | MaxDegree > 1) {//rln 20.06.99 work-around |
214 | KnotsMultiplicities.Append(MaxDegree-1); |
215 | CurveKnVals(i) = CurveKnVals(i-1) * Lambda; |
216 | Det += CurveKnVals(i); |
217 | |
218 | } |
219 | else { |
220 | CurvePoles.Append(Points(1)); |
221 | KnotsMultiplicities.Append(MaxDegree); |
222 | CurveKnVals(i) = 1.0e0 ; |
223 | Det += CurveKnVals(i) ; |
224 | } |
225 | |
226 | // Stocker les poles. |
227 | for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) { |
228 | CurvePoles.Append(Points(j)); |
229 | } |
230 | |
231 | } |
232 | |
233 | |
234 | if (i == UpperI) { |
235 | // Traitement du noeud terminal de la BSpline. |
236 | CurvePoles.Append(Points(MaxDegree+1)); |
237 | KnotsMultiplicities.Append(MaxDegree+1); |
238 | } |
239 | P1 = Points(MaxDegree); |
240 | } |
241 | |
242 | // Corriger les valeurs nodales pour les faire varier dans [0.,1.]. |
243 | CurveKnots.Append(0.0); |
244 | for (i = 2 ; i <= NbrCurv ; i++) { |
245 | CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det)); |
246 | } |
247 | CurveKnots.Append(1.0); |
248 | } |
249 | |
250 | |