Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-06-04 |
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 | // 20/02/97 : PMN -> Positionement local sur BSpline (PRO6902) |
18 | // 10/07/97 : PMN -> Pas de calcul de resolution dans Nb(Intervals) (PRO9248) | |
19 | // 20/10/97 : JPI -> traitement des offset curves | |
20 | ||
21 | #define No_Standard_RangeError | |
22 | #define No_Standard_OutOfRange | |
23 | ||
42cf5bc1 | 24 | |
7fd59977 | 25 | #include <Adaptor2d_HCurve2d.hxx> |
26 | #include <BSplCLib.hxx> | |
94f71cad | 27 | #include <BSplCLib_Cache.hxx> |
7fd59977 | 28 | #include <Geom2d_BezierCurve.hxx> |
29 | #include <Geom2d_BSplineCurve.hxx> | |
42cf5bc1 | 30 | #include <Geom2d_Circle.hxx> |
31 | #include <Geom2d_Curve.hxx> | |
7fd59977 | 32 | #include <Geom2d_Ellipse.hxx> |
7fd59977 | 33 | #include <Geom2d_Hyperbola.hxx> |
42cf5bc1 | 34 | #include <Geom2d_Line.hxx> |
35 | #include <Geom2d_OffsetCurve.hxx> | |
36 | #include <Geom2d_Parabola.hxx> | |
37 | #include <Geom2d_TrimmedCurve.hxx> | |
94f71cad | 38 | #include <Geom2d_UndefinedDerivative.hxx> |
42cf5bc1 | 39 | #include <Geom2d_UndefinedValue.hxx> |
40 | #include <Geom2dAdaptor_Curve.hxx> | |
41 | #include <Geom2dAdaptor_HCurve.hxx> | |
d660a72a | 42 | #include <Geom2dEvaluator_OffsetCurve.hxx> |
42cf5bc1 | 43 | #include <GeomAbs_Shape.hxx> |
44 | #include <gp.hxx> | |
45 | #include <gp_Circ2d.hxx> | |
46 | #include <gp_Elips2d.hxx> | |
47 | #include <gp_Hypr2d.hxx> | |
48 | #include <gp_Lin2d.hxx> | |
49 | #include <gp_Parab2d.hxx> | |
50 | #include <gp_Pnt2d.hxx> | |
51 | #include <gp_Vec2d.hxx> | |
52 | #include <Precision.hxx> | |
53 | #include <Standard_ConstructionError.hxx> | |
54 | #include <Standard_DomainError.hxx> | |
7fd59977 | 55 | #include <Standard_NoSuchObject.hxx> |
56 | #include <Standard_NotImplemented.hxx> | |
42cf5bc1 | 57 | #include <Standard_NullObject.hxx> |
58 | #include <Standard_OutOfRange.hxx> | |
59 | #include <TColgp_Array1OfPnt2d.hxx> | |
60 | #include <TColStd_Array1OfInteger.hxx> | |
61 | #include <TColStd_Array1OfReal.hxx> | |
62 | #include <TColStd_HArray1OfInteger.hxx> | |
7fd59977 | 63 | |
42cf5bc1 | 64 | //#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx> |
c8b5b3d8 | 65 | static const Standard_Real PosTol = Precision::PConfusion() / 2; |
7fd59977 | 66 | |
94f71cad | 67 | |
7fd59977 | 68 | //======================================================================= |
69 | //function : LocalContinuity | |
70 | //purpose : Computes the Continuity of a BSplineCurve | |
71 | // between the parameters U1 and U2 | |
72 | // The continuity is C(d-m) | |
73 | // with d = degree, | |
74 | // m = max multiplicity of the Knots between U1 and U2 | |
75 | //======================================================================= | |
76 | ||
77 | GeomAbs_Shape Geom2dAdaptor_Curve::LocalContinuity(const Standard_Real U1, | |
3b25c0e8 IC |
78 | const Standard_Real U2) const |
79 | { | |
7fd59977 | 80 | Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," "); |
3b25c0e8 | 81 | Standard_Integer Nb = myBSplineCurve->NbKnots(); |
7fd59977 | 82 | Standard_Integer Index1 = 0; |
83 | Standard_Integer Index2 = 0; | |
84 | Standard_Real newFirst, newLast; | |
85 | TColStd_Array1OfReal TK(1,Nb); | |
86 | TColStd_Array1OfInteger TM(1,Nb); | |
3b25c0e8 IC |
87 | myBSplineCurve->Knots(TK); |
88 | myBSplineCurve->Multiplicities(TM); | |
89 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(), | |
7fd59977 | 90 | 1,Nb,Index1,newFirst); |
3b25c0e8 | 91 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(), |
7fd59977 | 92 | 1,Nb,Index2,newLast); |
93 | if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) { | |
94 | if (Index1 < Nb)Index1++; | |
95 | } | |
96 | if ( Abs(newLast-TK(Index2))<Precision::PConfusion()) | |
97 | Index2--; | |
98 | Standard_Integer MultMax; | |
99 | // attention aux courbes peridiques. | |
3b25c0e8 | 100 | if ( myBSplineCurve->IsPeriodic() && Index1 == Nb ) |
7fd59977 | 101 | Index1 = 1; |
102 | ||
103 | if ( Index2 - Index1 <= 0) { | |
104 | MultMax = 100; // CN entre 2 Noeuds consecutifs | |
105 | } | |
106 | else { | |
107 | MultMax = TM(Index1+1); | |
108 | for(Standard_Integer i = Index1+1;i<=Index2;i++) { | |
109 | if ( TM(i)>MultMax) MultMax=TM(i); | |
110 | } | |
3b25c0e8 | 111 | MultMax = myBSplineCurve->Degree() - MultMax; |
7fd59977 | 112 | } |
113 | if ( MultMax <= 0) { | |
114 | return GeomAbs_C0; | |
115 | } | |
116 | else if ( MultMax == 1) { | |
117 | return GeomAbs_C1; | |
118 | } | |
119 | else if ( MultMax == 2) { | |
120 | return GeomAbs_C2; | |
121 | } | |
122 | else if ( MultMax == 3) { | |
123 | return GeomAbs_C3; | |
124 | } | |
125 | else { | |
126 | return GeomAbs_CN; | |
127 | } | |
3b25c0e8 | 128 | } |
7fd59977 | 129 | |
130 | ||
131 | //======================================================================= | |
132 | //function : Geom2dAdaptor_Curve | |
133 | //purpose : | |
134 | //======================================================================= | |
135 | ||
136 | Geom2dAdaptor_Curve::Geom2dAdaptor_Curve() | |
cbff1e55 | 137 | : myTypeCurve(GeomAbs_OtherCurve), |
138 | myFirst (0.0), | |
139 | myLast (0.0) | |
7fd59977 | 140 | { |
141 | } | |
142 | ||
143 | //======================================================================= | |
144 | //function : Geom2dAdaptor_Curve | |
145 | //purpose : | |
146 | //======================================================================= | |
147 | ||
cbff1e55 | 148 | Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv) |
149 | : myTypeCurve(GeomAbs_OtherCurve), | |
150 | myFirst (0.0), | |
151 | myLast (0.0) | |
041bfce9 | 152 | { |
cbff1e55 | 153 | Load(theCrv); |
7fd59977 | 154 | } |
155 | ||
156 | //======================================================================= | |
157 | //function : Geom2dAdaptor_Curve | |
158 | //purpose : | |
159 | //======================================================================= | |
160 | ||
cbff1e55 | 161 | Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv, |
162 | const Standard_Real theUFirst, | |
163 | const Standard_Real theULast) | |
164 | : myTypeCurve(GeomAbs_OtherCurve), | |
165 | myFirst (theUFirst), | |
166 | myLast (theULast) | |
041bfce9 | 167 | { |
cbff1e55 | 168 | Load(theCrv, theUFirst, theULast); |
7fd59977 | 169 | } |
170 | ||
7fd59977 | 171 | |
172 | //======================================================================= | |
173 | //function : Load | |
174 | //purpose : | |
175 | //======================================================================= | |
176 | ||
041bfce9 | 177 | void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C, |
178 | const Standard_Real UFirst, | |
179 | const Standard_Real ULast) | |
180 | { | |
7fd59977 | 181 | myFirst = UFirst; |
182 | myLast = ULast; | |
183 | ||
184 | if ( myCurve != C) { | |
185 | myCurve = C; | |
3b25c0e8 IC |
186 | myCurveCache.Nullify(); |
187 | myNestedEvaluator.Nullify(); | |
188 | myBSplineCurve.Nullify(); | |
7fd59977 | 189 | |
190 | Handle(Standard_Type) TheType = C->DynamicType(); | |
191 | if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) { | |
c5f3a425 | 192 | Load(Handle(Geom2d_TrimmedCurve)::DownCast (C)->BasisCurve(), |
7fd59977 | 193 | UFirst,ULast); |
194 | } | |
195 | else if ( TheType == STANDARD_TYPE(Geom2d_Circle)) { | |
196 | myTypeCurve = GeomAbs_Circle; | |
197 | } | |
198 | else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) { | |
199 | myTypeCurve = GeomAbs_Line; | |
200 | } | |
201 | else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) { | |
202 | myTypeCurve = GeomAbs_Ellipse; | |
203 | } | |
204 | else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) { | |
205 | myTypeCurve = GeomAbs_Parabola; | |
206 | } | |
207 | else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) { | |
208 | myTypeCurve = GeomAbs_Hyperbola; | |
209 | } | |
210 | else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) { | |
211 | myTypeCurve = GeomAbs_BezierCurve; | |
c8b5b3d8 | 212 | // Create cache for Bezier |
213 | Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve); | |
214 | Standard_Integer aDeg = aBezier->Degree(); | |
215 | TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); | |
216 | myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots, | |
217 | aBezier->Poles(), aBezier->Weights()); | |
7fd59977 | 218 | } |
219 | else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) { | |
220 | myTypeCurve = GeomAbs_BSplineCurve; | |
94f71cad | 221 | // Create cache for B-spline |
c8b5b3d8 | 222 | Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(myCurve); |
3b25c0e8 | 223 | myBSplineCurve = aBspl; |
c8b5b3d8 | 224 | myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(), |
225 | aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights()); | |
94f71cad | 226 | } |
227 | else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve)) | |
228 | { | |
1aec3320 | 229 | myTypeCurve = GeomAbs_OffsetCurve; |
d660a72a | 230 | Handle(Geom2d_OffsetCurve) anOffsetCurve = Handle(Geom2d_OffsetCurve)::DownCast(myCurve); |
94f71cad | 231 | // Create nested adaptor for base curve |
d660a72a | 232 | Handle(Geom2d_Curve) aBaseCurve = anOffsetCurve->BasisCurve(); |
233 | Handle(Geom2dAdaptor_HCurve) aBaseAdaptor = new Geom2dAdaptor_HCurve(aBaseCurve); | |
234 | myNestedEvaluator = new Geom2dEvaluator_OffsetCurve(aBaseAdaptor, anOffsetCurve->Offset()); | |
7fd59977 | 235 | } |
236 | else { | |
237 | myTypeCurve = GeomAbs_OtherCurve; | |
238 | } | |
239 | } | |
f3a1c0cb | 240 | else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same |
241 | RebuildCache(myFirst); | |
7fd59977 | 242 | } |
243 | ||
244 | // -- | |
245 | // -- Global methods - Apply to the whole curve. | |
246 | // -- | |
247 | ||
248 | //======================================================================= | |
249 | //function : Continuity | |
250 | //purpose : | |
251 | //======================================================================= | |
252 | ||
253 | GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const | |
254 | { | |
255 | if (myTypeCurve == GeomAbs_BSplineCurve) { | |
256 | return LocalContinuity(myFirst, myLast); | |
257 | } | |
1aec3320 | 258 | else if (myTypeCurve == GeomAbs_OffsetCurve){ |
7fd59977 | 259 | GeomAbs_Shape S = |
c5f3a425 | 260 | Handle(Geom2d_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity(); |
7fd59977 | 261 | switch(S){ |
262 | case GeomAbs_CN: return GeomAbs_CN; | |
263 | case GeomAbs_C3: return GeomAbs_C2; | |
264 | case GeomAbs_C2: return GeomAbs_C1; | |
265 | case GeomAbs_C1: return GeomAbs_C0; | |
3d58dc49 | 266 | case GeomAbs_G1: return GeomAbs_G1; |
267 | case GeomAbs_G2: return GeomAbs_G2; | |
268 | ||
7fd59977 | 269 | default: |
270 | Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity"); | |
271 | } | |
272 | } | |
273 | ||
274 | else if (myTypeCurve == GeomAbs_OtherCurve) { | |
275 | Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity"); | |
276 | } | |
277 | else { | |
278 | return GeomAbs_CN; | |
279 | } | |
280 | ||
281 | // portage WNT | |
282 | return GeomAbs_CN; | |
283 | } | |
284 | ||
285 | //======================================================================= | |
286 | //function : NbIntervals | |
287 | //purpose : | |
288 | //======================================================================= | |
289 | ||
290 | Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const | |
291 | { | |
292 | Standard_Integer myNbIntervals = 1; | |
293 | Standard_Integer NbSplit; | |
294 | if (myTypeCurve == GeomAbs_BSplineCurve) { | |
3b25c0e8 IC |
295 | Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex(); |
296 | Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex(); | |
7fd59977 | 297 | TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1); |
298 | if ( S > Continuity()) { | |
299 | Standard_Integer Cont; | |
300 | switch ( S) { | |
301 | case GeomAbs_G1: | |
302 | case GeomAbs_G2: | |
303 | Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals"); | |
304 | break; | |
305 | case GeomAbs_C0: | |
306 | myNbIntervals = 1; | |
307 | break; | |
308 | case GeomAbs_C1: | |
309 | case GeomAbs_C2: | |
310 | case GeomAbs_C3: | |
311 | case GeomAbs_CN: | |
312 | { | |
313 | if ( S == GeomAbs_C1) Cont = 1; | |
314 | else if ( S == GeomAbs_C2) Cont = 2; | |
315 | else if ( S == GeomAbs_C3) Cont = 3; | |
3b25c0e8 IC |
316 | else Cont = myBSplineCurve->Degree(); |
317 | Standard_Integer Degree = myBSplineCurve->Degree(); | |
318 | Standard_Integer NbKnots = myBSplineCurve->NbKnots(); | |
7fd59977 | 319 | TColStd_Array1OfInteger Mults (1, NbKnots); |
3b25c0e8 | 320 | myBSplineCurve->Multiplicities (Mults); |
7fd59977 | 321 | NbSplit = 1; |
322 | Standard_Integer Index = FirstIndex; | |
323 | Inter (NbSplit) = Index; | |
324 | Index++; | |
325 | NbSplit++; | |
326 | while (Index < LastIndex) | |
327 | { | |
328 | if (Degree - Mults (Index) < Cont) | |
329 | { | |
330 | Inter (NbSplit) = Index; | |
331 | NbSplit++; | |
332 | } | |
333 | Index++; | |
334 | } | |
335 | Inter (NbSplit) = Index; | |
336 | ||
337 | Standard_Integer NbInt = NbSplit-1; | |
338 | ||
3b25c0e8 | 339 | Standard_Integer Nb = myBSplineCurve->NbKnots(); |
7fd59977 | 340 | Standard_Integer Index1 = 0; |
341 | Standard_Integer Index2 = 0; | |
342 | Standard_Real newFirst, newLast; | |
343 | TColStd_Array1OfReal TK(1,Nb); | |
344 | TColStd_Array1OfInteger TM(1,Nb); | |
3b25c0e8 IC |
345 | myBSplineCurve->Knots(TK); |
346 | myBSplineCurve->Multiplicities(TM); | |
347 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst, | |
348 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 349 | 1,Nb,Index1,newFirst); |
3b25c0e8 IC |
350 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast, |
351 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 352 | 1,Nb,Index2,newLast); |
353 | ||
354 | // On decale eventuellement les indices | |
355 | // On utilise une "petite" tolerance, la resolution ne doit | |
356 | // servir que pour les tres longue courbes....(PRO9248) | |
357 | Standard_Real Eps = Min(Resolution(Precision::Confusion()), | |
358 | Precision::PConfusion()); | |
359 | if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++; | |
360 | if ( newLast-TK(Index2)> Eps) Index2++; | |
361 | ||
362 | myNbIntervals = 1; | |
363 | for ( Standard_Integer i=1; i<=NbInt; i++) | |
364 | if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++; | |
365 | } | |
366 | break; | |
367 | } | |
368 | } | |
369 | } | |
1aec3320 | 370 | else if (myTypeCurve == GeomAbs_OffsetCurve){ |
7fd59977 | 371 | GeomAbs_Shape BaseS=GeomAbs_C0; |
372 | switch(S){ | |
373 | case GeomAbs_G1: | |
374 | case GeomAbs_G2: | |
375 | Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals"); | |
376 | break; | |
377 | case GeomAbs_C0: BaseS = GeomAbs_C1; break; | |
378 | case GeomAbs_C1: BaseS = GeomAbs_C2; break; | |
379 | case GeomAbs_C2: BaseS = GeomAbs_C3; break; | |
380 | default: BaseS = GeomAbs_CN; | |
381 | } | |
d660a72a | 382 | Geom2dAdaptor_Curve anAdaptor( Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve() ); |
383 | myNbIntervals = anAdaptor.NbIntervals(BaseS); | |
7fd59977 | 384 | } |
385 | ||
386 | return myNbIntervals; | |
387 | } | |
388 | ||
389 | //======================================================================= | |
390 | //function : Intervals | |
391 | //purpose : | |
392 | //======================================================================= | |
393 | ||
394 | void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T, | |
395 | const GeomAbs_Shape S ) const | |
396 | { | |
397 | Standard_Integer myNbIntervals = 1; | |
398 | Standard_Integer NbSplit; | |
399 | if (myTypeCurve == GeomAbs_BSplineCurve) { | |
3b25c0e8 IC |
400 | Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex(); |
401 | Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex(); | |
7fd59977 | 402 | TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1); |
403 | if ( S > Continuity()) { | |
404 | Standard_Integer Cont; | |
405 | switch ( S) { | |
406 | case GeomAbs_G1: | |
407 | case GeomAbs_G2: | |
408 | Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals"); | |
409 | break; | |
410 | case GeomAbs_C0: | |
411 | myNbIntervals = 1; | |
412 | break; | |
413 | case GeomAbs_C1: | |
414 | case GeomAbs_C2: | |
415 | case GeomAbs_C3: | |
416 | case GeomAbs_CN: | |
417 | { | |
418 | if ( S == GeomAbs_C1) Cont = 1; | |
419 | else if ( S == GeomAbs_C2) Cont = 2; | |
420 | else if ( S == GeomAbs_C3) Cont = 3; | |
3b25c0e8 IC |
421 | else Cont = myBSplineCurve->Degree(); |
422 | Standard_Integer Degree = myBSplineCurve->Degree(); | |
423 | Standard_Integer NbKnots = myBSplineCurve->NbKnots(); | |
7fd59977 | 424 | TColStd_Array1OfInteger Mults (1, NbKnots); |
3b25c0e8 | 425 | myBSplineCurve->Multiplicities (Mults); |
7fd59977 | 426 | NbSplit = 1; |
427 | Standard_Integer Index = FirstIndex; | |
428 | Inter (NbSplit) = Index; | |
429 | Index++; | |
430 | NbSplit++; | |
431 | while (Index < LastIndex) | |
432 | { | |
433 | if (Degree - Mults (Index) < Cont) | |
434 | { | |
435 | Inter (NbSplit) = Index; | |
436 | NbSplit++; | |
437 | } | |
438 | Index++; | |
439 | } | |
440 | Inter (NbSplit) = Index; | |
441 | Standard_Integer NbInt = NbSplit-1; | |
442 | ||
3b25c0e8 | 443 | Standard_Integer Nb = myBSplineCurve->NbKnots(); |
7fd59977 | 444 | Standard_Integer Index1 = 0; |
445 | Standard_Integer Index2 = 0; | |
446 | Standard_Real newFirst, newLast; | |
447 | TColStd_Array1OfReal TK(1,Nb); | |
448 | TColStd_Array1OfInteger TM(1,Nb); | |
3b25c0e8 IC |
449 | myBSplineCurve->Knots(TK); |
450 | myBSplineCurve->Multiplicities(TM); | |
451 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst, | |
452 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 453 | 1,Nb,Index1,newFirst); |
3b25c0e8 IC |
454 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast, |
455 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 456 | 1,Nb,Index2,newLast); |
457 | ||
458 | ||
459 | // On decale eventuellement les indices | |
460 | // On utilise une "petite" tolerance, la resolution ne doit | |
461 | // servir que pour les tres longue courbes....(PRO9248) | |
462 | Standard_Real Eps = Min(Resolution(Precision::Confusion()), | |
463 | Precision::PConfusion()); | |
464 | if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++; | |
465 | if ( newLast-TK(Index2)> Eps) Index2++; | |
466 | ||
467 | Inter( 1) = Index1; | |
468 | myNbIntervals = 1; | |
469 | for ( Standard_Integer i=1; i<=NbInt; i++) { | |
470 | if (Inter(i) > Index1 && Inter(i)<Index2 ) { | |
471 | myNbIntervals++; | |
472 | Inter(myNbIntervals) = Inter(i); | |
473 | } | |
474 | } | |
475 | Inter(myNbIntervals+1) = Index2; | |
476 | ||
477 | Standard_Integer ii = T.Lower() - 1; | |
478 | for (Standard_Integer I=1;I<=myNbIntervals+1;I++) { | |
479 | T(ii + I) = TK(Inter(I)); | |
480 | } | |
481 | } | |
482 | break; | |
483 | } | |
484 | } | |
485 | } | |
1aec3320 | 486 | else if (myTypeCurve == GeomAbs_OffsetCurve){ |
7fd59977 | 487 | GeomAbs_Shape BaseS=GeomAbs_C0; |
488 | switch(S){ | |
489 | case GeomAbs_G1: | |
490 | case GeomAbs_G2: | |
491 | Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals"); | |
492 | break; | |
493 | case GeomAbs_C0: BaseS = GeomAbs_C1; break; | |
494 | case GeomAbs_C1: BaseS = GeomAbs_C2; break; | |
495 | case GeomAbs_C2: BaseS = GeomAbs_C3; break; | |
496 | default: BaseS = GeomAbs_CN; | |
497 | } | |
d660a72a | 498 | |
499 | Geom2dAdaptor_Curve anAdaptor( Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve() ); | |
500 | myNbIntervals = anAdaptor.NbIntervals(BaseS); | |
501 | anAdaptor.Intervals(T, BaseS); | |
7fd59977 | 502 | } |
503 | ||
504 | T( T.Lower() ) = myFirst; | |
505 | T( T.Lower() + myNbIntervals ) = myLast; | |
506 | } | |
507 | ||
508 | //======================================================================= | |
509 | //function : Trim | |
510 | //purpose : | |
511 | //======================================================================= | |
512 | ||
513 | Handle(Adaptor2d_HCurve2d) Geom2dAdaptor_Curve::Trim | |
514 | (const Standard_Real First, | |
515 | const Standard_Real Last, | |
516 | // const Standard_Real Tol) const | |
517 | const Standard_Real ) const | |
518 | { | |
519 | Handle(Geom2dAdaptor_HCurve) HE = new Geom2dAdaptor_HCurve(myCurve,First,Last); | |
520 | return HE; | |
521 | } | |
522 | ||
523 | ||
524 | //======================================================================= | |
525 | //function : IsClosed | |
526 | //purpose : | |
527 | //======================================================================= | |
528 | ||
529 | Standard_Boolean Geom2dAdaptor_Curve::IsClosed() const | |
530 | { | |
531 | if (!Precision::IsPositiveInfinite(myLast) && | |
532 | !Precision::IsNegativeInfinite(myFirst)) { | |
533 | gp_Pnt2d Pd = Value(myFirst); | |
534 | gp_Pnt2d Pf = Value(myLast); | |
535 | return ( Pd.Distance(Pf) <= Precision::Confusion()); | |
536 | } | |
537 | else | |
538 | return Standard_False; | |
539 | } | |
540 | ||
541 | //======================================================================= | |
542 | //function : IsPeriodic | |
543 | //purpose : | |
544 | //======================================================================= | |
545 | ||
546 | Standard_Boolean Geom2dAdaptor_Curve::IsPeriodic() const | |
547 | { | |
548 | if (myCurve->IsPeriodic()) | |
549 | return IsClosed(); | |
550 | else | |
551 | return Standard_False; | |
552 | } | |
553 | ||
554 | //======================================================================= | |
555 | //function : Period | |
556 | //purpose : | |
557 | //======================================================================= | |
558 | ||
559 | Standard_Real Geom2dAdaptor_Curve::Period() const | |
560 | { | |
561 | return myCurve->LastParameter() - myCurve->FirstParameter(); | |
562 | } | |
563 | ||
94f71cad | 564 | //======================================================================= |
565 | //function : RebuildCache | |
566 | //purpose : | |
567 | //======================================================================= | |
568 | void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const | |
569 | { | |
c8b5b3d8 | 570 | if (myTypeCurve == GeomAbs_BezierCurve) |
571 | { | |
572 | Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve); | |
573 | Standard_Integer aDeg = aBezier->Degree(); | |
574 | TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); | |
575 | myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots, | |
576 | aBezier->Poles(), aBezier->Weights()); | |
577 | } | |
578 | else if (myTypeCurve == GeomAbs_BSplineCurve) | |
579 | { | |
3b25c0e8 IC |
580 | myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(), |
581 | myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(), | |
582 | myBSplineCurve->Poles(), myBSplineCurve->Weights()); | |
c8b5b3d8 | 583 | } |
94f71cad | 584 | } |
585 | ||
7fd59977 | 586 | //======================================================================= |
d660a72a | 587 | //function : IsBoundary |
7fd59977 | 588 | //purpose : |
589 | //======================================================================= | |
d660a72a | 590 | Standard_Boolean Geom2dAdaptor_Curve::IsBoundary(const Standard_Real theU, |
591 | Standard_Integer& theSpanStart, | |
592 | Standard_Integer& theSpanFinish) const | |
7fd59977 | 593 | { |
3b25c0e8 | 594 | if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast)) |
94f71cad | 595 | { |
94f71cad | 596 | if (theU == myFirst) |
597 | { | |
3b25c0e8 | 598 | myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish); |
d660a72a | 599 | if (theSpanStart < 1) |
600 | theSpanStart = 1; | |
601 | if (theSpanStart >= theSpanFinish) | |
602 | theSpanFinish = theSpanStart + 1; | |
7fd59977 | 603 | } |
d660a72a | 604 | else if (theU == myLast) |
94f71cad | 605 | { |
3b25c0e8 IC |
606 | myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish); |
607 | if (theSpanFinish > myBSplineCurve->NbKnots()) | |
608 | theSpanFinish = myBSplineCurve->NbKnots(); | |
d660a72a | 609 | if (theSpanStart >= theSpanFinish) |
610 | theSpanStart = theSpanFinish - 1; | |
7fd59977 | 611 | } |
d660a72a | 612 | return Standard_True; |
7fd59977 | 613 | } |
d660a72a | 614 | return Standard_False; |
94f71cad | 615 | } |
616 | ||
617 | //======================================================================= | |
d660a72a | 618 | //function : Value |
619 | //purpose : | |
94f71cad | 620 | //======================================================================= |
d660a72a | 621 | |
622 | gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const | |
94f71cad | 623 | { |
d660a72a | 624 | gp_Pnt2d aRes; |
625 | D0(U, aRes); | |
626 | return aRes; | |
7fd59977 | 627 | } |
628 | ||
629 | //======================================================================= | |
630 | //function : D0 | |
631 | //purpose : | |
632 | //======================================================================= | |
633 | ||
634 | void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const | |
635 | { | |
d660a72a | 636 | switch (myTypeCurve) |
94f71cad | 637 | { |
d660a72a | 638 | case GeomAbs_BezierCurve: |
639 | case GeomAbs_BSplineCurve: | |
640 | { | |
641 | Standard_Integer aStart = 0, aFinish = 0; | |
642 | if (IsBoundary(U, aStart, aFinish)) | |
643 | { | |
3b25c0e8 | 644 | myBSplineCurve->LocalD0(U, aStart, aFinish, P); |
7fd59977 | 645 | } |
d660a72a | 646 | else if (!myCurveCache.IsNull()) // use cached data |
647 | { | |
648 | if (!myCurveCache->IsCacheValid(U)) | |
649 | RebuildCache(U); | |
650 | myCurveCache->D0(U, P); | |
7fd59977 | 651 | } |
d660a72a | 652 | else |
653 | myCurve->D0(U, P); | |
654 | break; | |
94f71cad | 655 | } |
94f71cad | 656 | |
d660a72a | 657 | case GeomAbs_OffsetCurve: |
658 | myNestedEvaluator->D0(U, P); | |
659 | break; | |
660 | ||
661 | default: | |
662 | myCurve->D0(U, P); | |
663 | } | |
7fd59977 | 664 | } |
665 | ||
666 | //======================================================================= | |
667 | //function : D1 | |
668 | //purpose : | |
669 | //======================================================================= | |
670 | ||
94f71cad | 671 | void Geom2dAdaptor_Curve::D1(const Standard_Real U, |
672 | gp_Pnt2d& P, gp_Vec2d& V) const | |
673 | { | |
d660a72a | 674 | switch (myTypeCurve) |
94f71cad | 675 | { |
d660a72a | 676 | case GeomAbs_BezierCurve: |
677 | case GeomAbs_BSplineCurve: | |
678 | { | |
679 | Standard_Integer aStart = 0, aFinish = 0; | |
680 | if (IsBoundary(U, aStart, aFinish)) | |
681 | { | |
3b25c0e8 | 682 | myBSplineCurve->LocalD1(U, aStart, aFinish, P, V); |
7fd59977 | 683 | } |
d660a72a | 684 | else if (!myCurveCache.IsNull()) // use cached data |
685 | { | |
686 | if (!myCurveCache->IsCacheValid(U)) | |
687 | RebuildCache(U); | |
688 | myCurveCache->D1(U, P, V); | |
7fd59977 | 689 | } |
d660a72a | 690 | else |
691 | myCurve->D1(U, P, V); | |
692 | break; | |
94f71cad | 693 | } |
94f71cad | 694 | |
d660a72a | 695 | case GeomAbs_OffsetCurve: |
696 | myNestedEvaluator->D1(U, P, V); | |
697 | break; | |
94f71cad | 698 | |
d660a72a | 699 | default: |
700 | myCurve->D1(U, P, V); | |
701 | } | |
7fd59977 | 702 | } |
703 | ||
704 | //======================================================================= | |
705 | //function : D2 | |
706 | //purpose : | |
707 | //======================================================================= | |
708 | ||
709 | void Geom2dAdaptor_Curve::D2(const Standard_Real U, | |
94f71cad | 710 | gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const |
7fd59977 | 711 | { |
d660a72a | 712 | switch (myTypeCurve) |
94f71cad | 713 | { |
d660a72a | 714 | case GeomAbs_BezierCurve: |
715 | case GeomAbs_BSplineCurve: | |
716 | { | |
717 | Standard_Integer aStart = 0, aFinish = 0; | |
718 | if (IsBoundary(U, aStart, aFinish)) | |
719 | { | |
3b25c0e8 | 720 | myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2); |
7fd59977 | 721 | } |
d660a72a | 722 | else if (!myCurveCache.IsNull()) // use cached data |
723 | { | |
724 | if (!myCurveCache->IsCacheValid(U)) | |
725 | RebuildCache(U); | |
726 | myCurveCache->D2(U, P, V1, V2); | |
7fd59977 | 727 | } |
d660a72a | 728 | else |
729 | myCurve->D2(U, P, V1, V2); | |
730 | break; | |
7fd59977 | 731 | } |
94f71cad | 732 | |
d660a72a | 733 | case GeomAbs_OffsetCurve: |
734 | myNestedEvaluator->D2(U, P, V1, V2); | |
735 | break; | |
94f71cad | 736 | |
d660a72a | 737 | default: |
738 | myCurve->D2(U, P, V1, V2); | |
739 | } | |
7fd59977 | 740 | } |
741 | ||
742 | //======================================================================= | |
743 | //function : D3 | |
744 | //purpose : | |
745 | //======================================================================= | |
746 | ||
747 | void Geom2dAdaptor_Curve::D3(const Standard_Real U, | |
94f71cad | 748 | gp_Pnt2d& P, gp_Vec2d& V1, |
749 | gp_Vec2d& V2, gp_Vec2d& V3) const | |
7fd59977 | 750 | { |
d660a72a | 751 | switch (myTypeCurve) |
94f71cad | 752 | { |
d660a72a | 753 | case GeomAbs_BezierCurve: |
754 | case GeomAbs_BSplineCurve: | |
755 | { | |
756 | Standard_Integer aStart = 0, aFinish = 0; | |
757 | if (IsBoundary(U, aStart, aFinish)) | |
758 | { | |
3b25c0e8 | 759 | myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3); |
7fd59977 | 760 | } |
d660a72a | 761 | else if (!myCurveCache.IsNull()) // use cached data |
762 | { | |
763 | if (!myCurveCache->IsCacheValid(U)) | |
764 | RebuildCache(U); | |
765 | myCurveCache->D3(U, P, V1, V2, V3); | |
7fd59977 | 766 | } |
d660a72a | 767 | else |
768 | myCurve->D3(U, P, V1, V2, V3); | |
769 | break; | |
7fd59977 | 770 | } |
94f71cad | 771 | |
d660a72a | 772 | case GeomAbs_OffsetCurve: |
773 | myNestedEvaluator->D3(U, P, V1, V2, V3); | |
774 | break; | |
94f71cad | 775 | |
d660a72a | 776 | default: |
777 | myCurve->D3(U, P, V1, V2, V3); | |
778 | } | |
7fd59977 | 779 | } |
780 | ||
781 | //======================================================================= | |
782 | //function : DN | |
783 | //purpose : | |
784 | //======================================================================= | |
785 | ||
786 | gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U, | |
94f71cad | 787 | const Standard_Integer N) const |
7fd59977 | 788 | { |
d660a72a | 789 | switch (myTypeCurve) |
94f71cad | 790 | { |
d660a72a | 791 | case GeomAbs_BezierCurve: |
792 | case GeomAbs_BSplineCurve: | |
793 | { | |
794 | Standard_Integer aStart = 0, aFinish = 0; | |
795 | if (IsBoundary(U, aStart, aFinish)) | |
796 | { | |
3b25c0e8 | 797 | myBSplineCurve->LocalDN(U, aStart, aFinish, N); |
7fd59977 | 798 | } |
d660a72a | 799 | else |
800 | return myCurve->DN(U, N); | |
801 | break; | |
7fd59977 | 802 | } |
94f71cad | 803 | |
d660a72a | 804 | case GeomAbs_OffsetCurve: |
805 | return myNestedEvaluator->DN(U, N); | |
94f71cad | 806 | break; |
d660a72a | 807 | |
808 | default: // to eliminate gcc warning | |
94f71cad | 809 | break; |
94f71cad | 810 | } |
d660a72a | 811 | return myCurve->DN(U, N); |
7fd59977 | 812 | } |
813 | ||
814 | //======================================================================= | |
815 | //function : Resolution | |
816 | //purpose : | |
817 | //======================================================================= | |
818 | ||
819 | Standard_Real Geom2dAdaptor_Curve::Resolution(const Standard_Real Ruv) const { | |
820 | switch ( myTypeCurve) { | |
821 | case GeomAbs_Line : | |
822 | return Ruv; | |
823 | case GeomAbs_Circle: { | |
c5f3a425 | 824 | Standard_Real R = Handle(Geom2d_Circle)::DownCast (myCurve)->Circ2d().Radius(); |
7fd59977 | 825 | if ( R > Ruv/2.) |
826 | return 2*ASin(Ruv/(2*R)); | |
827 | else | |
c6541a0c | 828 | return 2*M_PI; |
7fd59977 | 829 | } |
830 | case GeomAbs_Ellipse: { | |
c5f3a425 | 831 | return Ruv / Handle(Geom2d_Ellipse)::DownCast (myCurve)->MajorRadius(); |
7fd59977 | 832 | } |
833 | case GeomAbs_BezierCurve: { | |
834 | Standard_Real res; | |
c5f3a425 | 835 | Handle(Geom2d_BezierCurve)::DownCast (myCurve)->Resolution(Ruv,res); |
7fd59977 | 836 | return res; |
837 | } | |
838 | case GeomAbs_BSplineCurve: { | |
839 | Standard_Real res; | |
c5f3a425 | 840 | Handle(Geom2d_BSplineCurve)::DownCast (myCurve)->Resolution(Ruv,res); |
7fd59977 | 841 | return res; |
842 | } | |
843 | default: | |
844 | return Precision::Parametric(Ruv); | |
845 | } | |
846 | } | |
847 | ||
848 | ||
849 | // -- | |
850 | // -- The following methods must be called when GetType returned | |
851 | // -- the corresponding type. | |
852 | // -- | |
853 | ||
854 | //======================================================================= | |
855 | //function : Line | |
856 | //purpose : | |
857 | //======================================================================= | |
858 | ||
859 | gp_Lin2d Geom2dAdaptor_Curve::Line() const | |
860 | { | |
861 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, ""); | |
c5f3a425 | 862 | return Handle(Geom2d_Line)::DownCast (myCurve)->Lin2d(); |
7fd59977 | 863 | } |
864 | ||
865 | //======================================================================= | |
866 | //function : Circle | |
867 | //purpose : | |
868 | //======================================================================= | |
869 | ||
870 | gp_Circ2d Geom2dAdaptor_Curve::Circle() const | |
871 | { | |
872 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, ""); | |
c5f3a425 | 873 | return Handle(Geom2d_Circle)::DownCast (myCurve)->Circ2d(); |
7fd59977 | 874 | } |
875 | ||
876 | //======================================================================= | |
877 | //function : Ellipse | |
878 | //purpose : | |
879 | //======================================================================= | |
880 | ||
881 | gp_Elips2d Geom2dAdaptor_Curve::Ellipse() const | |
882 | { | |
883 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, ""); | |
c5f3a425 | 884 | return Handle(Geom2d_Ellipse)::DownCast (myCurve)->Elips2d(); |
7fd59977 | 885 | } |
886 | ||
887 | //======================================================================= | |
888 | //function : Hyperbola | |
889 | //purpose : | |
890 | //======================================================================= | |
891 | ||
892 | gp_Hypr2d Geom2dAdaptor_Curve::Hyperbola() const | |
893 | { | |
894 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, ""); | |
c5f3a425 | 895 | return Handle(Geom2d_Hyperbola)::DownCast (myCurve)->Hypr2d(); |
7fd59977 | 896 | } |
897 | ||
898 | //======================================================================= | |
899 | //function : Parabola | |
900 | //purpose : | |
901 | //======================================================================= | |
902 | ||
903 | gp_Parab2d Geom2dAdaptor_Curve::Parabola() const | |
904 | { | |
905 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, ""); | |
c5f3a425 | 906 | return Handle(Geom2d_Parabola)::DownCast (myCurve)->Parab2d(); |
7fd59977 | 907 | } |
908 | ||
909 | //======================================================================= | |
910 | //function : Degree | |
911 | //purpose : | |
912 | //======================================================================= | |
913 | ||
914 | Standard_Integer Geom2dAdaptor_Curve::Degree() const | |
915 | { | |
916 | if (myTypeCurve == GeomAbs_BezierCurve) | |
c5f3a425 | 917 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->Degree(); |
7fd59977 | 918 | else if (myTypeCurve == GeomAbs_BSplineCurve) |
3b25c0e8 | 919 | return myBSplineCurve->Degree(); |
7fd59977 | 920 | else |
921 | Standard_NoSuchObject::Raise(); | |
922 | // portage WNT | |
923 | return 0; | |
924 | } | |
925 | ||
926 | //======================================================================= | |
927 | //function : IsRational | |
928 | //purpose : | |
929 | //======================================================================= | |
930 | ||
931 | Standard_Boolean Geom2dAdaptor_Curve::IsRational() const { | |
932 | switch( myTypeCurve) { | |
933 | case GeomAbs_BSplineCurve: | |
3b25c0e8 | 934 | return myBSplineCurve->IsRational(); |
7fd59977 | 935 | case GeomAbs_BezierCurve: |
c5f3a425 | 936 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->IsRational(); |
7fd59977 | 937 | default: |
938 | return Standard_False; | |
939 | } | |
940 | } | |
941 | ||
942 | //======================================================================= | |
943 | //function : NbPoles | |
944 | //purpose : | |
945 | //======================================================================= | |
946 | ||
947 | Standard_Integer Geom2dAdaptor_Curve::NbPoles() const | |
948 | { | |
949 | if (myTypeCurve == GeomAbs_BezierCurve) | |
c5f3a425 | 950 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->NbPoles(); |
7fd59977 | 951 | else if (myTypeCurve == GeomAbs_BSplineCurve) |
3b25c0e8 | 952 | return myBSplineCurve->NbPoles(); |
7fd59977 | 953 | else |
954 | Standard_NoSuchObject::Raise(); | |
955 | // portage WNT | |
956 | return 0; | |
957 | } | |
958 | ||
959 | //======================================================================= | |
960 | //function : NbKnots | |
961 | //purpose : | |
962 | //======================================================================= | |
963 | ||
3b25c0e8 IC |
964 | Standard_Integer Geom2dAdaptor_Curve::NbKnots() const |
965 | { | |
7fd59977 | 966 | if ( myTypeCurve != GeomAbs_BSplineCurve) |
967 | Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::NbKnots"); | |
3b25c0e8 | 968 | return myBSplineCurve->NbKnots(); |
7fd59977 | 969 | } |
970 | ||
971 | //======================================================================= | |
972 | //function : Bezier | |
973 | //purpose : | |
974 | //======================================================================= | |
975 | ||
976 | Handle(Geom2d_BezierCurve) Geom2dAdaptor_Curve::Bezier() const | |
977 | { | |
c5f3a425 | 978 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve); |
7fd59977 | 979 | } |
980 | ||
981 | //======================================================================= | |
982 | //function : BSpline | |
983 | //purpose : | |
984 | //======================================================================= | |
985 | ||
986 | Handle(Geom2d_BSplineCurve) Geom2dAdaptor_Curve::BSpline() const | |
987 | { | |
3b25c0e8 | 988 | return myBSplineCurve; |
7fd59977 | 989 | } |
990 | ||
a874a4a0 | 991 | static Standard_Integer nbPoints(const Handle(Geom2d_Curve)& theCurve) |
992 | { | |
993 | ||
5ae6e53d | 994 | Standard_Integer nbs = 20; |
a874a4a0 | 995 | |
996 | if(theCurve->IsKind(STANDARD_TYPE( Geom2d_Line)) ) | |
997 | nbs = 2; | |
998 | else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BezierCurve))) | |
999 | { | |
c5f3a425 | 1000 | nbs = 3 + Handle(Geom2d_BezierCurve)::DownCast (theCurve)->NbPoles(); |
a874a4a0 | 1001 | } |
1002 | else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BSplineCurve))) { | |
c5f3a425 | 1003 | nbs = Handle(Geom2d_BSplineCurve)::DownCast (theCurve)->NbKnots(); |
1004 | nbs*= Handle(Geom2d_BSplineCurve)::DownCast (theCurve)->Degree(); | |
a874a4a0 | 1005 | if(nbs < 2.0) nbs=2; |
1006 | } | |
1007 | else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) | |
1008 | { | |
c5f3a425 | 1009 | Handle(Geom2d_Curve) aCurve = Handle(Geom2d_OffsetCurve)::DownCast (theCurve)->BasisCurve(); |
a874a4a0 | 1010 | return Max(nbs, nbPoints(aCurve)); |
1011 | } | |
1012 | ||
1013 | else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) | |
1014 | { | |
c5f3a425 | 1015 | Handle(Geom2d_Curve) aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (theCurve)->BasisCurve(); |
a874a4a0 | 1016 | return Max(nbs, nbPoints(aCurve)); |
1017 | } | |
1018 | if(nbs>300) | |
1019 | nbs = 300; | |
1020 | return nbs; | |
3b25c0e8 | 1021 | |
a874a4a0 | 1022 | } |
1023 | ||
1024 | Standard_Integer Geom2dAdaptor_Curve::NbSamples() const | |
1025 | { | |
1026 | return nbPoints(myCurve); | |
1027 | } |