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