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; | |
81093856 | 183 | myCurveCache.Nullify(); |
7fd59977 | 184 | |
185 | if ( myCurve != C) { | |
186 | myCurve = C; | |
3b25c0e8 IC |
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; | |
212 | } | |
213 | else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) { | |
214 | myTypeCurve = GeomAbs_BSplineCurve; | |
81093856 | 215 | myBSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(myCurve); |
94f71cad | 216 | } |
217 | else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve)) | |
218 | { | |
1aec3320 | 219 | myTypeCurve = GeomAbs_OffsetCurve; |
d660a72a | 220 | Handle(Geom2d_OffsetCurve) anOffsetCurve = Handle(Geom2d_OffsetCurve)::DownCast(myCurve); |
94f71cad | 221 | // Create nested adaptor for base curve |
d660a72a | 222 | Handle(Geom2d_Curve) aBaseCurve = anOffsetCurve->BasisCurve(); |
223 | Handle(Geom2dAdaptor_HCurve) aBaseAdaptor = new Geom2dAdaptor_HCurve(aBaseCurve); | |
224 | myNestedEvaluator = new Geom2dEvaluator_OffsetCurve(aBaseAdaptor, anOffsetCurve->Offset()); | |
7fd59977 | 225 | } |
226 | else { | |
227 | myTypeCurve = GeomAbs_OtherCurve; | |
228 | } | |
229 | } | |
230 | } | |
231 | ||
232 | // -- | |
233 | // -- Global methods - Apply to the whole curve. | |
234 | // -- | |
235 | ||
236 | //======================================================================= | |
237 | //function : Continuity | |
238 | //purpose : | |
239 | //======================================================================= | |
240 | ||
241 | GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const | |
242 | { | |
243 | if (myTypeCurve == GeomAbs_BSplineCurve) { | |
244 | return LocalContinuity(myFirst, myLast); | |
245 | } | |
1aec3320 | 246 | else if (myTypeCurve == GeomAbs_OffsetCurve){ |
7fd59977 | 247 | GeomAbs_Shape S = |
c5f3a425 | 248 | Handle(Geom2d_OffsetCurve)::DownCast (myCurve)->GetBasisCurveContinuity(); |
7fd59977 | 249 | switch(S){ |
250 | case GeomAbs_CN: return GeomAbs_CN; | |
251 | case GeomAbs_C3: return GeomAbs_C2; | |
252 | case GeomAbs_C2: return GeomAbs_C1; | |
253 | case GeomAbs_C1: return GeomAbs_C0; | |
3d58dc49 | 254 | case GeomAbs_G1: return GeomAbs_G1; |
255 | case GeomAbs_G2: return GeomAbs_G2; | |
256 | ||
7fd59977 | 257 | default: |
9775fa61 | 258 | throw Standard_NoSuchObject("Geom2dAdaptor_Curve::Continuity"); |
7fd59977 | 259 | } |
260 | } | |
261 | ||
262 | else if (myTypeCurve == GeomAbs_OtherCurve) { | |
9775fa61 | 263 | throw Standard_NoSuchObject("Geom2dAdaptor_Curve::Continuity"); |
7fd59977 | 264 | } |
265 | else { | |
266 | return GeomAbs_CN; | |
267 | } | |
7fd59977 | 268 | } |
269 | ||
270 | //======================================================================= | |
271 | //function : NbIntervals | |
272 | //purpose : | |
273 | //======================================================================= | |
274 | ||
275 | Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const | |
276 | { | |
277 | Standard_Integer myNbIntervals = 1; | |
278 | Standard_Integer NbSplit; | |
279 | if (myTypeCurve == GeomAbs_BSplineCurve) { | |
3b25c0e8 IC |
280 | Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex(); |
281 | Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex(); | |
7fd59977 | 282 | TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1); |
283 | if ( S > Continuity()) { | |
284 | Standard_Integer Cont; | |
285 | switch ( S) { | |
286 | case GeomAbs_G1: | |
287 | case GeomAbs_G2: | |
9775fa61 | 288 | throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals"); |
7fd59977 | 289 | break; |
290 | case GeomAbs_C0: | |
291 | myNbIntervals = 1; | |
292 | break; | |
293 | case GeomAbs_C1: | |
294 | case GeomAbs_C2: | |
295 | case GeomAbs_C3: | |
296 | case GeomAbs_CN: | |
297 | { | |
298 | if ( S == GeomAbs_C1) Cont = 1; | |
299 | else if ( S == GeomAbs_C2) Cont = 2; | |
300 | else if ( S == GeomAbs_C3) Cont = 3; | |
3b25c0e8 IC |
301 | else Cont = myBSplineCurve->Degree(); |
302 | Standard_Integer Degree = myBSplineCurve->Degree(); | |
303 | Standard_Integer NbKnots = myBSplineCurve->NbKnots(); | |
7fd59977 | 304 | TColStd_Array1OfInteger Mults (1, NbKnots); |
3b25c0e8 | 305 | myBSplineCurve->Multiplicities (Mults); |
7fd59977 | 306 | NbSplit = 1; |
307 | Standard_Integer Index = FirstIndex; | |
308 | Inter (NbSplit) = Index; | |
309 | Index++; | |
310 | NbSplit++; | |
311 | while (Index < LastIndex) | |
312 | { | |
313 | if (Degree - Mults (Index) < Cont) | |
314 | { | |
315 | Inter (NbSplit) = Index; | |
316 | NbSplit++; | |
317 | } | |
318 | Index++; | |
319 | } | |
320 | Inter (NbSplit) = Index; | |
321 | ||
322 | Standard_Integer NbInt = NbSplit-1; | |
323 | ||
3b25c0e8 | 324 | Standard_Integer Nb = myBSplineCurve->NbKnots(); |
7fd59977 | 325 | Standard_Integer Index1 = 0; |
326 | Standard_Integer Index2 = 0; | |
327 | Standard_Real newFirst, newLast; | |
328 | TColStd_Array1OfReal TK(1,Nb); | |
329 | TColStd_Array1OfInteger TM(1,Nb); | |
3b25c0e8 IC |
330 | myBSplineCurve->Knots(TK); |
331 | myBSplineCurve->Multiplicities(TM); | |
332 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst, | |
333 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 334 | 1,Nb,Index1,newFirst); |
3b25c0e8 IC |
335 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast, |
336 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 337 | 1,Nb,Index2,newLast); |
338 | ||
339 | // On decale eventuellement les indices | |
340 | // On utilise une "petite" tolerance, la resolution ne doit | |
341 | // servir que pour les tres longue courbes....(PRO9248) | |
342 | Standard_Real Eps = Min(Resolution(Precision::Confusion()), | |
343 | Precision::PConfusion()); | |
344 | if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++; | |
345 | if ( newLast-TK(Index2)> Eps) Index2++; | |
346 | ||
347 | myNbIntervals = 1; | |
348 | for ( Standard_Integer i=1; i<=NbInt; i++) | |
349 | if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++; | |
350 | } | |
351 | break; | |
352 | } | |
353 | } | |
354 | } | |
1aec3320 | 355 | else if (myTypeCurve == GeomAbs_OffsetCurve){ |
7fd59977 | 356 | GeomAbs_Shape BaseS=GeomAbs_C0; |
357 | switch(S){ | |
358 | case GeomAbs_G1: | |
359 | case GeomAbs_G2: | |
9775fa61 | 360 | throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals"); |
7fd59977 | 361 | break; |
362 | case GeomAbs_C0: BaseS = GeomAbs_C1; break; | |
363 | case GeomAbs_C1: BaseS = GeomAbs_C2; break; | |
364 | case GeomAbs_C2: BaseS = GeomAbs_C3; break; | |
365 | default: BaseS = GeomAbs_CN; | |
366 | } | |
d660a72a | 367 | Geom2dAdaptor_Curve anAdaptor( Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve() ); |
368 | myNbIntervals = anAdaptor.NbIntervals(BaseS); | |
7fd59977 | 369 | } |
370 | ||
371 | return myNbIntervals; | |
372 | } | |
373 | ||
374 | //======================================================================= | |
375 | //function : Intervals | |
376 | //purpose : | |
377 | //======================================================================= | |
378 | ||
379 | void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T, | |
380 | const GeomAbs_Shape S ) const | |
381 | { | |
382 | Standard_Integer myNbIntervals = 1; | |
383 | Standard_Integer NbSplit; | |
384 | if (myTypeCurve == GeomAbs_BSplineCurve) { | |
3b25c0e8 IC |
385 | Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex(); |
386 | Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex(); | |
7fd59977 | 387 | TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1); |
388 | if ( S > Continuity()) { | |
389 | Standard_Integer Cont; | |
390 | switch ( S) { | |
391 | case GeomAbs_G1: | |
392 | case GeomAbs_G2: | |
9775fa61 | 393 | throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals"); |
7fd59977 | 394 | break; |
395 | case GeomAbs_C0: | |
396 | myNbIntervals = 1; | |
397 | break; | |
398 | case GeomAbs_C1: | |
399 | case GeomAbs_C2: | |
400 | case GeomAbs_C3: | |
401 | case GeomAbs_CN: | |
402 | { | |
403 | if ( S == GeomAbs_C1) Cont = 1; | |
404 | else if ( S == GeomAbs_C2) Cont = 2; | |
405 | else if ( S == GeomAbs_C3) Cont = 3; | |
3b25c0e8 IC |
406 | else Cont = myBSplineCurve->Degree(); |
407 | Standard_Integer Degree = myBSplineCurve->Degree(); | |
408 | Standard_Integer NbKnots = myBSplineCurve->NbKnots(); | |
7fd59977 | 409 | TColStd_Array1OfInteger Mults (1, NbKnots); |
3b25c0e8 | 410 | myBSplineCurve->Multiplicities (Mults); |
7fd59977 | 411 | NbSplit = 1; |
412 | Standard_Integer Index = FirstIndex; | |
413 | Inter (NbSplit) = Index; | |
414 | Index++; | |
415 | NbSplit++; | |
416 | while (Index < LastIndex) | |
417 | { | |
418 | if (Degree - Mults (Index) < Cont) | |
419 | { | |
420 | Inter (NbSplit) = Index; | |
421 | NbSplit++; | |
422 | } | |
423 | Index++; | |
424 | } | |
425 | Inter (NbSplit) = Index; | |
426 | Standard_Integer NbInt = NbSplit-1; | |
427 | ||
3b25c0e8 | 428 | Standard_Integer Nb = myBSplineCurve->NbKnots(); |
7fd59977 | 429 | Standard_Integer Index1 = 0; |
430 | Standard_Integer Index2 = 0; | |
431 | Standard_Real newFirst, newLast; | |
432 | TColStd_Array1OfReal TK(1,Nb); | |
433 | TColStd_Array1OfInteger TM(1,Nb); | |
3b25c0e8 IC |
434 | myBSplineCurve->Knots(TK); |
435 | myBSplineCurve->Multiplicities(TM); | |
436 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst, | |
437 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 438 | 1,Nb,Index1,newFirst); |
3b25c0e8 IC |
439 | BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast, |
440 | myBSplineCurve->IsPeriodic(), | |
7fd59977 | 441 | 1,Nb,Index2,newLast); |
442 | ||
443 | ||
444 | // On decale eventuellement les indices | |
445 | // On utilise une "petite" tolerance, la resolution ne doit | |
446 | // servir que pour les tres longue courbes....(PRO9248) | |
447 | Standard_Real Eps = Min(Resolution(Precision::Confusion()), | |
448 | Precision::PConfusion()); | |
449 | if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++; | |
450 | if ( newLast-TK(Index2)> Eps) Index2++; | |
451 | ||
452 | Inter( 1) = Index1; | |
453 | myNbIntervals = 1; | |
454 | for ( Standard_Integer i=1; i<=NbInt; i++) { | |
455 | if (Inter(i) > Index1 && Inter(i)<Index2 ) { | |
456 | myNbIntervals++; | |
457 | Inter(myNbIntervals) = Inter(i); | |
458 | } | |
459 | } | |
460 | Inter(myNbIntervals+1) = Index2; | |
461 | ||
462 | Standard_Integer ii = T.Lower() - 1; | |
463 | for (Standard_Integer I=1;I<=myNbIntervals+1;I++) { | |
464 | T(ii + I) = TK(Inter(I)); | |
465 | } | |
466 | } | |
467 | break; | |
468 | } | |
469 | } | |
470 | } | |
1aec3320 | 471 | else if (myTypeCurve == GeomAbs_OffsetCurve){ |
7fd59977 | 472 | GeomAbs_Shape BaseS=GeomAbs_C0; |
473 | switch(S){ | |
474 | case GeomAbs_G1: | |
475 | case GeomAbs_G2: | |
9775fa61 | 476 | throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals"); |
7fd59977 | 477 | break; |
478 | case GeomAbs_C0: BaseS = GeomAbs_C1; break; | |
479 | case GeomAbs_C1: BaseS = GeomAbs_C2; break; | |
480 | case GeomAbs_C2: BaseS = GeomAbs_C3; break; | |
481 | default: BaseS = GeomAbs_CN; | |
482 | } | |
d660a72a | 483 | |
484 | Geom2dAdaptor_Curve anAdaptor( Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve() ); | |
485 | myNbIntervals = anAdaptor.NbIntervals(BaseS); | |
486 | anAdaptor.Intervals(T, BaseS); | |
7fd59977 | 487 | } |
488 | ||
489 | T( T.Lower() ) = myFirst; | |
490 | T( T.Lower() + myNbIntervals ) = myLast; | |
491 | } | |
492 | ||
493 | //======================================================================= | |
494 | //function : Trim | |
495 | //purpose : | |
496 | //======================================================================= | |
497 | ||
498 | Handle(Adaptor2d_HCurve2d) Geom2dAdaptor_Curve::Trim | |
499 | (const Standard_Real First, | |
500 | const Standard_Real Last, | |
501 | // const Standard_Real Tol) const | |
502 | const Standard_Real ) const | |
503 | { | |
504 | Handle(Geom2dAdaptor_HCurve) HE = new Geom2dAdaptor_HCurve(myCurve,First,Last); | |
505 | return HE; | |
506 | } | |
507 | ||
508 | ||
509 | //======================================================================= | |
510 | //function : IsClosed | |
511 | //purpose : | |
512 | //======================================================================= | |
513 | ||
514 | Standard_Boolean Geom2dAdaptor_Curve::IsClosed() const | |
515 | { | |
516 | if (!Precision::IsPositiveInfinite(myLast) && | |
517 | !Precision::IsNegativeInfinite(myFirst)) { | |
518 | gp_Pnt2d Pd = Value(myFirst); | |
519 | gp_Pnt2d Pf = Value(myLast); | |
520 | return ( Pd.Distance(Pf) <= Precision::Confusion()); | |
521 | } | |
522 | else | |
523 | return Standard_False; | |
524 | } | |
525 | ||
526 | //======================================================================= | |
527 | //function : IsPeriodic | |
528 | //purpose : | |
529 | //======================================================================= | |
530 | ||
531 | Standard_Boolean Geom2dAdaptor_Curve::IsPeriodic() const | |
532 | { | |
533 | if (myCurve->IsPeriodic()) | |
534 | return IsClosed(); | |
535 | else | |
536 | return Standard_False; | |
537 | } | |
538 | ||
539 | //======================================================================= | |
540 | //function : Period | |
541 | //purpose : | |
542 | //======================================================================= | |
543 | ||
544 | Standard_Real Geom2dAdaptor_Curve::Period() const | |
545 | { | |
546 | return myCurve->LastParameter() - myCurve->FirstParameter(); | |
547 | } | |
548 | ||
94f71cad | 549 | //======================================================================= |
550 | //function : RebuildCache | |
551 | //purpose : | |
552 | //======================================================================= | |
553 | void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const | |
554 | { | |
c8b5b3d8 | 555 | if (myTypeCurve == GeomAbs_BezierCurve) |
556 | { | |
81093856 | 557 | // Create cache for Bezier |
c8b5b3d8 | 558 | Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve); |
559 | Standard_Integer aDeg = aBezier->Degree(); | |
560 | TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); | |
81093856 | 561 | if (myCurveCache.IsNull()) |
562 | myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots, | |
563 | aBezier->Poles(), aBezier->Weights()); | |
c8b5b3d8 | 564 | myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots, |
565 | aBezier->Poles(), aBezier->Weights()); | |
566 | } | |
567 | else if (myTypeCurve == GeomAbs_BSplineCurve) | |
568 | { | |
81093856 | 569 | // Create cache for B-spline |
570 | if (myCurveCache.IsNull()) | |
571 | myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(), | |
572 | myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights()); | |
3b25c0e8 IC |
573 | myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(), |
574 | myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(), | |
575 | myBSplineCurve->Poles(), myBSplineCurve->Weights()); | |
c8b5b3d8 | 576 | } |
94f71cad | 577 | } |
578 | ||
7fd59977 | 579 | //======================================================================= |
d660a72a | 580 | //function : IsBoundary |
7fd59977 | 581 | //purpose : |
582 | //======================================================================= | |
d660a72a | 583 | Standard_Boolean Geom2dAdaptor_Curve::IsBoundary(const Standard_Real theU, |
584 | Standard_Integer& theSpanStart, | |
585 | Standard_Integer& theSpanFinish) const | |
7fd59977 | 586 | { |
3b25c0e8 | 587 | if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast)) |
94f71cad | 588 | { |
94f71cad | 589 | if (theU == myFirst) |
590 | { | |
3b25c0e8 | 591 | myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish); |
d660a72a | 592 | if (theSpanStart < 1) |
593 | theSpanStart = 1; | |
594 | if (theSpanStart >= theSpanFinish) | |
595 | theSpanFinish = theSpanStart + 1; | |
7fd59977 | 596 | } |
d660a72a | 597 | else if (theU == myLast) |
94f71cad | 598 | { |
3b25c0e8 IC |
599 | myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish); |
600 | if (theSpanFinish > myBSplineCurve->NbKnots()) | |
601 | theSpanFinish = myBSplineCurve->NbKnots(); | |
d660a72a | 602 | if (theSpanStart >= theSpanFinish) |
603 | theSpanStart = theSpanFinish - 1; | |
7fd59977 | 604 | } |
d660a72a | 605 | return Standard_True; |
7fd59977 | 606 | } |
d660a72a | 607 | return Standard_False; |
94f71cad | 608 | } |
609 | ||
610 | //======================================================================= | |
d660a72a | 611 | //function : Value |
612 | //purpose : | |
94f71cad | 613 | //======================================================================= |
d660a72a | 614 | |
615 | gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const | |
94f71cad | 616 | { |
d660a72a | 617 | gp_Pnt2d aRes; |
618 | D0(U, aRes); | |
619 | return aRes; | |
7fd59977 | 620 | } |
621 | ||
622 | //======================================================================= | |
623 | //function : D0 | |
624 | //purpose : | |
625 | //======================================================================= | |
626 | ||
627 | void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const | |
628 | { | |
d660a72a | 629 | switch (myTypeCurve) |
94f71cad | 630 | { |
d660a72a | 631 | case GeomAbs_BezierCurve: |
632 | case GeomAbs_BSplineCurve: | |
633 | { | |
634 | Standard_Integer aStart = 0, aFinish = 0; | |
635 | if (IsBoundary(U, aStart, aFinish)) | |
636 | { | |
3b25c0e8 | 637 | myBSplineCurve->LocalD0(U, aStart, aFinish, P); |
7fd59977 | 638 | } |
81093856 | 639 | else |
d660a72a | 640 | { |
81093856 | 641 | // use cached data |
642 | if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) | |
d660a72a | 643 | RebuildCache(U); |
644 | myCurveCache->D0(U, P); | |
7fd59977 | 645 | } |
d660a72a | 646 | break; |
94f71cad | 647 | } |
94f71cad | 648 | |
d660a72a | 649 | case GeomAbs_OffsetCurve: |
650 | myNestedEvaluator->D0(U, P); | |
651 | break; | |
652 | ||
653 | default: | |
654 | myCurve->D0(U, P); | |
655 | } | |
7fd59977 | 656 | } |
657 | ||
658 | //======================================================================= | |
659 | //function : D1 | |
660 | //purpose : | |
661 | //======================================================================= | |
662 | ||
94f71cad | 663 | void Geom2dAdaptor_Curve::D1(const Standard_Real U, |
664 | gp_Pnt2d& P, gp_Vec2d& V) const | |
665 | { | |
d660a72a | 666 | switch (myTypeCurve) |
94f71cad | 667 | { |
d660a72a | 668 | case GeomAbs_BezierCurve: |
669 | case GeomAbs_BSplineCurve: | |
670 | { | |
671 | Standard_Integer aStart = 0, aFinish = 0; | |
672 | if (IsBoundary(U, aStart, aFinish)) | |
673 | { | |
3b25c0e8 | 674 | myBSplineCurve->LocalD1(U, aStart, aFinish, P, V); |
7fd59977 | 675 | } |
81093856 | 676 | else |
d660a72a | 677 | { |
81093856 | 678 | // use cached data |
679 | if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) | |
d660a72a | 680 | RebuildCache(U); |
681 | myCurveCache->D1(U, P, V); | |
7fd59977 | 682 | } |
d660a72a | 683 | break; |
94f71cad | 684 | } |
94f71cad | 685 | |
d660a72a | 686 | case GeomAbs_OffsetCurve: |
687 | myNestedEvaluator->D1(U, P, V); | |
688 | break; | |
94f71cad | 689 | |
d660a72a | 690 | default: |
691 | myCurve->D1(U, P, V); | |
692 | } | |
7fd59977 | 693 | } |
694 | ||
695 | //======================================================================= | |
696 | //function : D2 | |
697 | //purpose : | |
698 | //======================================================================= | |
699 | ||
700 | void Geom2dAdaptor_Curve::D2(const Standard_Real U, | |
94f71cad | 701 | gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const |
7fd59977 | 702 | { |
d660a72a | 703 | switch (myTypeCurve) |
94f71cad | 704 | { |
d660a72a | 705 | case GeomAbs_BezierCurve: |
706 | case GeomAbs_BSplineCurve: | |
707 | { | |
708 | Standard_Integer aStart = 0, aFinish = 0; | |
709 | if (IsBoundary(U, aStart, aFinish)) | |
710 | { | |
3b25c0e8 | 711 | myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2); |
7fd59977 | 712 | } |
81093856 | 713 | else |
d660a72a | 714 | { |
81093856 | 715 | // use cached data |
716 | if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) | |
d660a72a | 717 | RebuildCache(U); |
718 | myCurveCache->D2(U, P, V1, V2); | |
7fd59977 | 719 | } |
d660a72a | 720 | break; |
7fd59977 | 721 | } |
94f71cad | 722 | |
d660a72a | 723 | case GeomAbs_OffsetCurve: |
724 | myNestedEvaluator->D2(U, P, V1, V2); | |
725 | break; | |
94f71cad | 726 | |
d660a72a | 727 | default: |
728 | myCurve->D2(U, P, V1, V2); | |
729 | } | |
7fd59977 | 730 | } |
731 | ||
732 | //======================================================================= | |
733 | //function : D3 | |
734 | //purpose : | |
735 | //======================================================================= | |
736 | ||
737 | void Geom2dAdaptor_Curve::D3(const Standard_Real U, | |
94f71cad | 738 | gp_Pnt2d& P, gp_Vec2d& V1, |
739 | gp_Vec2d& V2, gp_Vec2d& V3) const | |
7fd59977 | 740 | { |
d660a72a | 741 | switch (myTypeCurve) |
94f71cad | 742 | { |
d660a72a | 743 | case GeomAbs_BezierCurve: |
744 | case GeomAbs_BSplineCurve: | |
745 | { | |
746 | Standard_Integer aStart = 0, aFinish = 0; | |
747 | if (IsBoundary(U, aStart, aFinish)) | |
748 | { | |
3b25c0e8 | 749 | myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3); |
7fd59977 | 750 | } |
81093856 | 751 | else |
d660a72a | 752 | { |
81093856 | 753 | // use cached data |
754 | if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) | |
d660a72a | 755 | RebuildCache(U); |
756 | myCurveCache->D3(U, P, V1, V2, V3); | |
7fd59977 | 757 | } |
d660a72a | 758 | break; |
7fd59977 | 759 | } |
94f71cad | 760 | |
d660a72a | 761 | case GeomAbs_OffsetCurve: |
762 | myNestedEvaluator->D3(U, P, V1, V2, V3); | |
763 | break; | |
94f71cad | 764 | |
d660a72a | 765 | default: |
766 | myCurve->D3(U, P, V1, V2, V3); | |
767 | } | |
7fd59977 | 768 | } |
769 | ||
770 | //======================================================================= | |
771 | //function : DN | |
772 | //purpose : | |
773 | //======================================================================= | |
774 | ||
775 | gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U, | |
94f71cad | 776 | const Standard_Integer N) const |
7fd59977 | 777 | { |
d660a72a | 778 | switch (myTypeCurve) |
94f71cad | 779 | { |
d660a72a | 780 | case GeomAbs_BezierCurve: |
781 | case GeomAbs_BSplineCurve: | |
782 | { | |
783 | Standard_Integer aStart = 0, aFinish = 0; | |
784 | if (IsBoundary(U, aStart, aFinish)) | |
785 | { | |
3b25c0e8 | 786 | myBSplineCurve->LocalDN(U, aStart, aFinish, N); |
7fd59977 | 787 | } |
d660a72a | 788 | else |
789 | return myCurve->DN(U, N); | |
790 | break; | |
7fd59977 | 791 | } |
94f71cad | 792 | |
d660a72a | 793 | case GeomAbs_OffsetCurve: |
794 | return myNestedEvaluator->DN(U, N); | |
94f71cad | 795 | break; |
d660a72a | 796 | |
797 | default: // to eliminate gcc warning | |
94f71cad | 798 | break; |
94f71cad | 799 | } |
d660a72a | 800 | return myCurve->DN(U, N); |
7fd59977 | 801 | } |
802 | ||
803 | //======================================================================= | |
804 | //function : Resolution | |
805 | //purpose : | |
806 | //======================================================================= | |
807 | ||
808 | Standard_Real Geom2dAdaptor_Curve::Resolution(const Standard_Real Ruv) const { | |
809 | switch ( myTypeCurve) { | |
810 | case GeomAbs_Line : | |
811 | return Ruv; | |
812 | case GeomAbs_Circle: { | |
c5f3a425 | 813 | Standard_Real R = Handle(Geom2d_Circle)::DownCast (myCurve)->Circ2d().Radius(); |
7fd59977 | 814 | if ( R > Ruv/2.) |
815 | return 2*ASin(Ruv/(2*R)); | |
816 | else | |
c6541a0c | 817 | return 2*M_PI; |
7fd59977 | 818 | } |
819 | case GeomAbs_Ellipse: { | |
c5f3a425 | 820 | return Ruv / Handle(Geom2d_Ellipse)::DownCast (myCurve)->MajorRadius(); |
7fd59977 | 821 | } |
822 | case GeomAbs_BezierCurve: { | |
823 | Standard_Real res; | |
c5f3a425 | 824 | Handle(Geom2d_BezierCurve)::DownCast (myCurve)->Resolution(Ruv,res); |
7fd59977 | 825 | return res; |
826 | } | |
827 | case GeomAbs_BSplineCurve: { | |
828 | Standard_Real res; | |
c5f3a425 | 829 | Handle(Geom2d_BSplineCurve)::DownCast (myCurve)->Resolution(Ruv,res); |
7fd59977 | 830 | return res; |
831 | } | |
832 | default: | |
833 | return Precision::Parametric(Ruv); | |
834 | } | |
835 | } | |
836 | ||
837 | ||
838 | // -- | |
839 | // -- The following methods must be called when GetType returned | |
840 | // -- the corresponding type. | |
841 | // -- | |
842 | ||
843 | //======================================================================= | |
844 | //function : Line | |
845 | //purpose : | |
846 | //======================================================================= | |
847 | ||
848 | gp_Lin2d Geom2dAdaptor_Curve::Line() const | |
849 | { | |
850 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, ""); | |
c5f3a425 | 851 | return Handle(Geom2d_Line)::DownCast (myCurve)->Lin2d(); |
7fd59977 | 852 | } |
853 | ||
854 | //======================================================================= | |
855 | //function : Circle | |
856 | //purpose : | |
857 | //======================================================================= | |
858 | ||
859 | gp_Circ2d Geom2dAdaptor_Curve::Circle() const | |
860 | { | |
861 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, ""); | |
c5f3a425 | 862 | return Handle(Geom2d_Circle)::DownCast (myCurve)->Circ2d(); |
7fd59977 | 863 | } |
864 | ||
865 | //======================================================================= | |
866 | //function : Ellipse | |
867 | //purpose : | |
868 | //======================================================================= | |
869 | ||
870 | gp_Elips2d Geom2dAdaptor_Curve::Ellipse() const | |
871 | { | |
872 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, ""); | |
c5f3a425 | 873 | return Handle(Geom2d_Ellipse)::DownCast (myCurve)->Elips2d(); |
7fd59977 | 874 | } |
875 | ||
876 | //======================================================================= | |
877 | //function : Hyperbola | |
878 | //purpose : | |
879 | //======================================================================= | |
880 | ||
881 | gp_Hypr2d Geom2dAdaptor_Curve::Hyperbola() const | |
882 | { | |
883 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, ""); | |
c5f3a425 | 884 | return Handle(Geom2d_Hyperbola)::DownCast (myCurve)->Hypr2d(); |
7fd59977 | 885 | } |
886 | ||
887 | //======================================================================= | |
888 | //function : Parabola | |
889 | //purpose : | |
890 | //======================================================================= | |
891 | ||
892 | gp_Parab2d Geom2dAdaptor_Curve::Parabola() const | |
893 | { | |
894 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, ""); | |
c5f3a425 | 895 | return Handle(Geom2d_Parabola)::DownCast (myCurve)->Parab2d(); |
7fd59977 | 896 | } |
897 | ||
898 | //======================================================================= | |
899 | //function : Degree | |
900 | //purpose : | |
901 | //======================================================================= | |
902 | ||
903 | Standard_Integer Geom2dAdaptor_Curve::Degree() const | |
904 | { | |
905 | if (myTypeCurve == GeomAbs_BezierCurve) | |
c5f3a425 | 906 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->Degree(); |
7fd59977 | 907 | else if (myTypeCurve == GeomAbs_BSplineCurve) |
3b25c0e8 | 908 | return myBSplineCurve->Degree(); |
7fd59977 | 909 | else |
9775fa61 | 910 | throw Standard_NoSuchObject(); |
7fd59977 | 911 | } |
912 | ||
913 | //======================================================================= | |
914 | //function : IsRational | |
915 | //purpose : | |
916 | //======================================================================= | |
917 | ||
918 | Standard_Boolean Geom2dAdaptor_Curve::IsRational() const { | |
919 | switch( myTypeCurve) { | |
920 | case GeomAbs_BSplineCurve: | |
3b25c0e8 | 921 | return myBSplineCurve->IsRational(); |
7fd59977 | 922 | case GeomAbs_BezierCurve: |
c5f3a425 | 923 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->IsRational(); |
7fd59977 | 924 | default: |
925 | return Standard_False; | |
926 | } | |
927 | } | |
928 | ||
929 | //======================================================================= | |
930 | //function : NbPoles | |
931 | //purpose : | |
932 | //======================================================================= | |
933 | ||
934 | Standard_Integer Geom2dAdaptor_Curve::NbPoles() const | |
935 | { | |
936 | if (myTypeCurve == GeomAbs_BezierCurve) | |
c5f3a425 | 937 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve)->NbPoles(); |
7fd59977 | 938 | else if (myTypeCurve == GeomAbs_BSplineCurve) |
3b25c0e8 | 939 | return myBSplineCurve->NbPoles(); |
7fd59977 | 940 | else |
9775fa61 | 941 | throw Standard_NoSuchObject(); |
7fd59977 | 942 | } |
943 | ||
944 | //======================================================================= | |
945 | //function : NbKnots | |
946 | //purpose : | |
947 | //======================================================================= | |
948 | ||
3b25c0e8 IC |
949 | Standard_Integer Geom2dAdaptor_Curve::NbKnots() const |
950 | { | |
7fd59977 | 951 | if ( myTypeCurve != GeomAbs_BSplineCurve) |
9775fa61 | 952 | throw Standard_NoSuchObject("Geom2dAdaptor_Curve::NbKnots"); |
3b25c0e8 | 953 | return myBSplineCurve->NbKnots(); |
7fd59977 | 954 | } |
955 | ||
956 | //======================================================================= | |
957 | //function : Bezier | |
958 | //purpose : | |
959 | //======================================================================= | |
960 | ||
961 | Handle(Geom2d_BezierCurve) Geom2dAdaptor_Curve::Bezier() const | |
962 | { | |
c5f3a425 | 963 | return Handle(Geom2d_BezierCurve)::DownCast (myCurve); |
7fd59977 | 964 | } |
965 | ||
966 | //======================================================================= | |
967 | //function : BSpline | |
968 | //purpose : | |
969 | //======================================================================= | |
970 | ||
971 | Handle(Geom2d_BSplineCurve) Geom2dAdaptor_Curve::BSpline() const | |
972 | { | |
3b25c0e8 | 973 | return myBSplineCurve; |
7fd59977 | 974 | } |
975 | ||
a874a4a0 | 976 | static Standard_Integer nbPoints(const Handle(Geom2d_Curve)& theCurve) |
977 | { | |
978 | ||
5ae6e53d | 979 | Standard_Integer nbs = 20; |
a874a4a0 | 980 | |
981 | if(theCurve->IsKind(STANDARD_TYPE( Geom2d_Line)) ) | |
982 | nbs = 2; | |
983 | else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BezierCurve))) | |
984 | { | |
c5f3a425 | 985 | nbs = 3 + Handle(Geom2d_BezierCurve)::DownCast (theCurve)->NbPoles(); |
a874a4a0 | 986 | } |
987 | else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BSplineCurve))) { | |
c5f3a425 | 988 | nbs = Handle(Geom2d_BSplineCurve)::DownCast (theCurve)->NbKnots(); |
989 | nbs*= Handle(Geom2d_BSplineCurve)::DownCast (theCurve)->Degree(); | |
a874a4a0 | 990 | if(nbs < 2.0) nbs=2; |
991 | } | |
992 | else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) | |
993 | { | |
c5f3a425 | 994 | Handle(Geom2d_Curve) aCurve = Handle(Geom2d_OffsetCurve)::DownCast (theCurve)->BasisCurve(); |
a874a4a0 | 995 | return Max(nbs, nbPoints(aCurve)); |
996 | } | |
997 | ||
998 | else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) | |
999 | { | |
c5f3a425 | 1000 | Handle(Geom2d_Curve) aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (theCurve)->BasisCurve(); |
a874a4a0 | 1001 | return Max(nbs, nbPoints(aCurve)); |
1002 | } | |
1003 | if(nbs>300) | |
1004 | nbs = 300; | |
1005 | return nbs; | |
3b25c0e8 | 1006 | |
a874a4a0 | 1007 | } |
1008 | ||
1009 | Standard_Integer Geom2dAdaptor_Curve::NbSamples() const | |
1010 | { | |
1011 | return nbPoints(myCurve); | |
1012 | } |