Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-10-20 |
2 | // Created by: Bruno DUMORTIER | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
6 | // The content of this file is subject to the Open CASCADE Technology Public | |
7 | // License Version 6.5 (the "License"). You may not use the content of this file | |
8 | // except in compliance with the License. Please obtain a copy of the License | |
9 | // at http://www.opencascade.org and read it completely before using this file. | |
10 | // | |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
13 | // | |
14 | // The Original Code and all software distributed under the License is | |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
16 | // Initial Developer hereby disclaims all such warranties, including without | |
17 | // limitation, any warranties of merchantability, fitness for a particular | |
18 | // purpose or non-infringement. Please see the License for the specific terms | |
19 | // and conditions governing the rights and limitations under the License. | |
20 | ||
0d969553 | 21 | |
7fd59977 | 22 | |
23 | #include <Convert_CompBezierCurvesToBSplineCurve.ixx> | |
24 | ||
25 | #include <Precision.hxx> | |
26 | #include <BSplCLib.hxx> | |
27 | #include <PLib.hxx> | |
28 | #include <gp_Pnt.hxx> | |
29 | #include <gp.hxx> | |
30 | #include <gp_Vec.hxx> | |
31 | #include <TColgp_HArray1OfPnt.hxx> | |
32 | ||
33 | ||
34 | //======================================================================= | |
35 | //function : Convert_CompBezierCurvesToBSplineCurve | |
36 | //purpose : | |
37 | //======================================================================= | |
38 | ||
39 | ||
40 | Convert_CompBezierCurvesToBSplineCurve:: | |
41 | Convert_CompBezierCurvesToBSplineCurve( | |
42 | const Standard_Real AngularTolerance) : | |
43 | myAngular(AngularTolerance), | |
44 | myDone(Standard_False) | |
45 | { | |
46 | } | |
47 | ||
48 | ||
49 | //======================================================================= | |
50 | //function : AddCurve | |
51 | //purpose : | |
52 | //======================================================================= | |
53 | ||
54 | void Convert_CompBezierCurvesToBSplineCurve::AddCurve | |
55 | (const TColgp_Array1OfPnt& Poles) | |
56 | { | |
57 | if ( !mySequence.IsEmpty()) { | |
58 | gp_Pnt P1,P2; | |
59 | P1 = mySequence.Last()->Value(mySequence.Last()->Upper()); | |
60 | P2 = Poles(Poles.Lower()); | |
61 | ||
62 | // NYI | |
63 | if ( !P1.IsEqual(P2,Precision::Confusion())) | |
64 | cout << "Convert_CompBezierCurvesToBSplineCurve::Addcurve" << endl;; | |
65 | } | |
66 | myDone = Standard_False; | |
67 | Handle(TColgp_HArray1OfPnt) HPoles = | |
68 | new TColgp_HArray1OfPnt(Poles.Lower(),Poles.Upper()); | |
69 | HPoles->ChangeArray1() = Poles; | |
70 | mySequence.Append(HPoles); | |
71 | } | |
72 | ||
73 | ||
74 | //======================================================================= | |
75 | //function : Degree | |
76 | //purpose : | |
77 | //======================================================================= | |
78 | ||
79 | Standard_Integer Convert_CompBezierCurvesToBSplineCurve::Degree() const | |
80 | { | |
81 | return myDegree; | |
82 | } | |
83 | ||
84 | ||
85 | //======================================================================= | |
86 | //function : NbPoles | |
87 | //purpose : | |
88 | //======================================================================= | |
89 | ||
90 | Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbPoles() const | |
91 | { | |
92 | return CurvePoles.Length(); | |
93 | } | |
94 | ||
95 | ||
96 | //======================================================================= | |
97 | //function : Poles | |
98 | //purpose : | |
99 | //======================================================================= | |
100 | ||
101 | void Convert_CompBezierCurvesToBSplineCurve::Poles | |
102 | (TColgp_Array1OfPnt& Poles) const | |
103 | { | |
104 | Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper(); | |
105 | Standard_Integer k = 1; | |
106 | for (i = Lower; i <= Upper; i++) { | |
107 | Poles(i) = CurvePoles(k++); | |
108 | } | |
109 | } | |
110 | ||
111 | ||
112 | //======================================================================= | |
113 | //function : NbKnots | |
114 | //purpose : | |
115 | //======================================================================= | |
116 | ||
117 | Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbKnots() const | |
118 | { | |
119 | return CurveKnots.Length(); | |
120 | } | |
121 | ||
122 | ||
123 | //======================================================================= | |
124 | //function : KnotsAndMults | |
125 | //purpose : | |
126 | //======================================================================= | |
127 | ||
128 | void Convert_CompBezierCurvesToBSplineCurve::KnotsAndMults | |
129 | (TColStd_Array1OfReal& Knots, | |
130 | TColStd_Array1OfInteger& Mults ) const | |
131 | { | |
132 | Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper(); | |
133 | Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper(); | |
134 | Standard_Integer k = 1; | |
135 | for (i = LowerK; i <= UpperK; i++) { | |
136 | Knots(i) = CurveKnots(k++); | |
137 | } | |
138 | k = 1; | |
139 | for (i = LowerM; i <= UpperM; i++) { | |
140 | Mults(i) = KnotsMultiplicities(k++); | |
141 | } | |
142 | } | |
143 | ||
144 | ||
145 | ||
146 | //======================================================================= | |
147 | //function : Perform | |
148 | //purpose : | |
149 | //======================================================================= | |
150 | ||
151 | void Convert_CompBezierCurvesToBSplineCurve::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 | // Standard_Integer NbKnotsSpl = NbrCurv + 1 ; | |
161 | TColStd_Array1OfReal CurveKnVals (1,NbrCurv); | |
162 | ||
163 | Standard_Integer i; | |
164 | myDegree = 0; | |
165 | for ( i = 1; i <= mySequence.Length(); i++) { | |
166 | myDegree = Max( myDegree, (mySequence(i))->Length() -1); | |
167 | } | |
168 | ||
169 | Standard_Real D1, D2, Lambda, Det=0; | |
170 | gp_Pnt P1, P2, P3; | |
171 | Standard_Integer Deg, Inc, MaxDegree = myDegree; | |
172 | TColgp_Array1OfPnt Points(1, myDegree+1); | |
173 | ||
174 | for (i = LowerI ; i <= UpperI ; i++) { | |
0d969553 | 175 | // 1- Raise the Bezier curve to the maximum degree. |
7fd59977 | 176 | Deg = mySequence(i)->Length()-1; |
177 | Inc = myDegree - Deg; | |
178 | if ( Inc > 0) { | |
179 | BSplCLib::IncreaseDegree(myDegree, | |
180 | mySequence(i)->Array1(), PLib::NoWeights(), | |
181 | Points, PLib::NoWeights()); | |
182 | } | |
183 | else { | |
184 | Points = mySequence(i)->Array1(); | |
185 | } | |
186 | ||
0d969553 | 187 | // 2- Process the node of junction between 2 Bezier curves. |
7fd59977 | 188 | if (i == LowerI) { |
0d969553 | 189 | // Processing of the initial node of the BSpline. |
7fd59977 | 190 | for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) { |
191 | CurvePoles.Append(Points(j)); | |
192 | } | |
0d969553 | 193 | CurveKnVals(1) = 1.; // To begin the series. |
7fd59977 | 194 | KnotsMultiplicities.Append(MaxDegree+1); |
195 | Det = 1.; | |
196 | } | |
197 | ||
198 | ||
199 | if (i != LowerI) { | |
200 | P2 = Points(1); | |
201 | P3 = Points(2); | |
202 | gp_Vec V1(P1, P2), V2(P2, P3); | |
203 | D1 = P1.SquareDistance(P2); | |
204 | D2 = P3.SquareDistance(P2); | |
205 | Lambda = Sqrt(D2/D1); | |
206 | // cout << "D1, D2, Lambda : " << D1 << " " << D2 << " " << Lambda << endl; | |
207 | ||
0d969553 Y |
208 | // Processing of the tangency between Bezier and the previous. |
209 | // This allows to guarantee at least a C1 continuity if the tangents are | |
210 | // coherent. | |
7fd59977 | 211 | |
212 | if (V1.Magnitude() > gp::Resolution() && | |
213 | V2.Magnitude() > gp::Resolution() && | |
214 | V1.IsParallel(V2, myAngular )) { | |
215 | if(CurveKnVals(i-1) * Lambda > 10. * Epsilon(Det)) { | |
216 | KnotsMultiplicities.Append(MaxDegree-1); | |
217 | CurveKnVals(i) = CurveKnVals(i-1) * Lambda; | |
218 | Det += CurveKnVals(i); | |
219 | } | |
220 | else { | |
221 | CurvePoles.Append(Points(1)); | |
222 | KnotsMultiplicities.Append(MaxDegree); | |
223 | CurveKnVals(i) = 1.0 ; | |
224 | Det += CurveKnVals(i) ; | |
225 | } | |
226 | } | |
227 | else { | |
228 | CurvePoles.Append(Points(1)); | |
229 | KnotsMultiplicities.Append(MaxDegree); | |
230 | CurveKnVals(i) = 1.0 ; | |
231 | Det += CurveKnVals(i) ; | |
232 | } | |
233 | ||
0d969553 | 234 | // Store the poles. |
7fd59977 | 235 | for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) { |
236 | CurvePoles.Append(Points(j)); | |
237 | } | |
238 | ||
239 | } | |
240 | ||
241 | ||
242 | if (i == UpperI) { | |
0d969553 | 243 | // Processing of the end node of the BSpline. |
7fd59977 | 244 | CurvePoles.Append(Points(MaxDegree+1)); |
245 | KnotsMultiplicities.Append(MaxDegree+1); | |
246 | } | |
247 | P1 = Points(MaxDegree); | |
248 | } | |
249 | ||
0d969553 | 250 | // Correct nodal values to make them variable within [0.,1.]. |
7fd59977 | 251 | CurveKnots.Append(0.0); |
252 | // cout << "Convert : Det = " << Det << endl; | |
253 | for (i = 2 ; i <= NbrCurv ; i++) { | |
254 | CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det)); | |
255 | } | |
256 | CurveKnots.Append(1.0); | |
257 | } | |
258 | ||
259 |