Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GeomAdaptor / GeomAdaptor_Curve.cxx
CommitLineData
7fd59977 1// File: GeomAdaptor_Curve.cxx
2// Created: Thu Apr 29 11:54:32 1993
3// Author: Bruno DUMORTIER
4// Copyright: OPEN CASCADE 1993
5
6// 20/02/97 : PMN -> Positionement local sur BSpline (PRO6902)
7// 10/07/97 : PMN -> Pas de calcul de resolution dans Nb(Intervals)(PRO9248)
8// 20/10/97 : RBV -> traitement des offset curves
9
10#define No_Standard_RangeError
11#define No_Standard_OutOfRange
12
13#include <GeomAdaptor_Curve.ixx>
14
15#include <GeomAdaptor_HCurve.hxx>
16#include <Adaptor3d_HCurve.hxx>
17#include <BSplCLib.hxx>
18#include <GeomAbs_Shape.hxx>
19#include <TColgp_Array1OfPnt.hxx>
20#include <TColStd_Array1OfReal.hxx>
21#include <TColStd_Array1OfInteger.hxx>
22#include <TColStd_HArray1OfInteger.hxx>
23#include <Precision.hxx>
24#include <Geom_TrimmedCurve.hxx>
25#include <Geom_Circle.hxx>
26#include <Geom_Line.hxx>
27#include <Geom_TrimmedCurve.hxx>
28#include <Geom_BezierCurve.hxx>
29#include <Geom_BSplineCurve.hxx>
30#include <Geom_Ellipse.hxx>
31#include <Geom_Parabola.hxx>
32#include <Geom_Hyperbola.hxx>
33//#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
34
35#include <Standard_OutOfRange.hxx>
36#include <Standard_NoSuchObject.hxx>
37#include <Standard_NotImplemented.hxx>
38#include <Geom_OffsetCurve.hxx>
39
40#define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve))
41#define PosTol Precision::PConfusion()/2
42
43//=======================================================================
44//function : LocalContinuity
45//purpose : Computes the Continuity of a BSplineCurve
46// between the parameters U1 and U2
47// The continuity is C(d-m)
48// with d = degree,
49// m = max multiplicity of the Knots between U1 and U2
50//=======================================================================
51
52GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
53 const Standard_Real U2)
54 const
55{
56 Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
57 Standard_Integer Nb = myBspl->NbKnots();
58 Standard_Integer Index1 = 0;
59 Standard_Integer Index2 = 0;
60 Standard_Real newFirst, newLast;
61 TColStd_Array1OfReal TK(1,Nb);
62 TColStd_Array1OfInteger TM(1,Nb);
63 myBspl->Knots(TK);
64 myBspl->Multiplicities(TM);
65 BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U1,myBspl->IsPeriodic(),
66 1,Nb,Index1,newFirst);
67 BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U2,myBspl->IsPeriodic(),
68 1,Nb,Index2,newLast);
69 if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) {
70 if (Index1 < Nb) Index1++;
71 }
72 if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
73 Index2--;
74 Standard_Integer MultMax;
75 // attention aux courbes peridiques.
76 if ( (myBspl->IsPeriodic()) && (Index1 == Nb) )
77 Index1 = 1;
78
79 if ( Index2 - Index1 <= 0) {
80 MultMax = 100; // CN entre 2 Noeuds consecutifs
81 }
82 else {
83 MultMax = TM(Index1+1);
84 for(Standard_Integer i = Index1+1;i<=Index2;i++) {
85 if ( TM(i)>MultMax) MultMax=TM(i);
86 }
87 MultMax = myBspl->Degree() - MultMax;
88 }
89 if ( MultMax <= 0) {
90 return GeomAbs_C0;
91 }
92 else if ( MultMax == 1) {
93 return GeomAbs_C1;
94 }
95 else if ( MultMax == 2) {
96 return GeomAbs_C2;
97 }
98 else if ( MultMax == 3) {
99 return GeomAbs_C3;
100 }
101 else {
102 return GeomAbs_CN;
103 }
104}
105
106
107//=======================================================================
108//function : Load
109//purpose :
110//=======================================================================
111
112void GeomAdaptor_Curve::Load(const Handle(Geom_Curve)& C,
113 const Standard_Real UFirst,
114 const Standard_Real ULast)
115{
116 if ( UFirst > ULast) Standard_ConstructionError::Raise();
117 myFirst = UFirst;
118 myLast = ULast;
119
120 if ( myCurve != C) {
121 myCurve = C;
122
123 const Handle(Standard_Type)& TheType = C->DynamicType();
124 if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
125 Load((*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve(),UFirst,ULast);
126 }
127 else if ( TheType == STANDARD_TYPE(Geom_Circle)) {
128 myTypeCurve = GeomAbs_Circle;
129 }
130 else if ( TheType ==STANDARD_TYPE(Geom_Line)) {
131 myTypeCurve = GeomAbs_Line;
132 }
133 else if ( TheType == STANDARD_TYPE(Geom_Ellipse)) {
134 myTypeCurve = GeomAbs_Ellipse;
135 }
136 else if ( TheType == STANDARD_TYPE(Geom_Parabola)) {
137 myTypeCurve = GeomAbs_Parabola;
138 }
139 else if ( TheType == STANDARD_TYPE(Geom_Hyperbola)) {
140 myTypeCurve = GeomAbs_Hyperbola;
141 }
142 else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
143 myTypeCurve = GeomAbs_BezierCurve;
144 }
145 else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
146 myTypeCurve = GeomAbs_BSplineCurve;
147 }
148 else {
149 myTypeCurve = GeomAbs_OtherCurve;
150 }
151 }
152}
153
154// --
155// -- Global methods - Apply to the whole curve.
156// --
157
158//=======================================================================
159//function : Continuity
160//purpose :
161//=======================================================================
162
163GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
164{
165 if (myTypeCurve == GeomAbs_BSplineCurve)
166 return LocalContinuity(myFirst, myLast);
167
168 if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
169 {
170 const GeomAbs_Shape S =
171 (*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve()->Continuity();
172 switch(S)
173 {
174 case GeomAbs_CN: return GeomAbs_CN;
175 case GeomAbs_C3: return GeomAbs_C2;
176 case GeomAbs_C2: return GeomAbs_C1;
177 case GeomAbs_C1: return GeomAbs_C0;
178 default:
179 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
180 }
181 }
182 else if (myTypeCurve == GeomAbs_OtherCurve) {
183 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Contunuity");
184 }
185
186 return GeomAbs_CN;
187}
188
189//=======================================================================
190//function : NbIntervals
191//purpose :
192//=======================================================================
193
194Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S)
195{
196 Standard_Integer myNbIntervals = 1;
197 Standard_Integer NbSplit;
198 if (myTypeCurve == GeomAbs_BSplineCurve) {
199 Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
200 Standard_Integer LastIndex = myBspl->LastUKnotIndex();
201 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
202 if ( S > Continuity()) {
203 Standard_Integer Cont;
204 switch ( S) {
205 case GeomAbs_G1:
206 case GeomAbs_G2:
207 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
208 break;
209 case GeomAbs_C0:
210 myNbIntervals = 1;
211 break;
212 case GeomAbs_C1:
213 case GeomAbs_C2:
214 case GeomAbs_C3:
215 case GeomAbs_CN:
216 {
217 if ( S == GeomAbs_C1) Cont = 1;
218 else if ( S == GeomAbs_C2) Cont = 2;
219 else if ( S == GeomAbs_C3) Cont = 3;
220 else Cont = myBspl->Degree();
221 Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
222 Standard_Integer LastIndex = myBspl->LastUKnotIndex();
223 Standard_Integer Degree = myBspl->Degree();
224 Standard_Integer NbKnots = myBspl->NbKnots();
225 TColStd_Array1OfInteger Mults (1, NbKnots);
226 myBspl->Multiplicities (Mults);
227 NbSplit = 1;
228 Standard_Integer Index = FirstIndex;
229 Inter (NbSplit) = Index;
230 Index++;
231 NbSplit++;
232 while (Index < LastIndex)
233 {
234 if (Degree - Mults (Index) < Cont)
235 {
236 Inter (NbSplit) = Index;
237 NbSplit++;
238 }
239 Index++;
240 }
241 Inter (NbSplit) = Index;
242
243 Standard_Integer NbInt = NbSplit-1;
244
245 Standard_Integer Nb = myBspl->NbKnots();
246 Standard_Integer Index1 = 0;
247 Standard_Integer Index2 = 0;
248 Standard_Real newFirst, newLast;
249 TColStd_Array1OfReal TK(1,Nb);
250 TColStd_Array1OfInteger TM(1,Nb);
251 myBspl->Knots(TK);
252 myBspl->Multiplicities(TM);
253 BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst,
254 myBspl->IsPeriodic(),
255 1,Nb,Index1,newFirst);
256 BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast,
257 myBspl->IsPeriodic(),
258 1,Nb,Index2,newLast);
259
260 // On decale eventuellement les indices
261 // On utilise une "petite" tolerance, la resolution ne doit
262 // servir que pour les tres longue courbes....(PRO9248)
263 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
264 Precision::PConfusion());
265 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
266 if ( newLast-TK(Index2)> Eps) Index2++;
267
268 myNbIntervals = 1;
269 for ( Standard_Integer i=1; i<=NbInt; i++)
270 if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
271 }
272 break;
273 }
274 }
275 }
276
277 else if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))){
278 GeomAbs_Shape BaseS=GeomAbs_C0;
279 switch(S){
280 case GeomAbs_G1:
281 case GeomAbs_G2:
282 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
283 break;
284 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
285 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
286 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
287 default: BaseS = GeomAbs_CN;
288 }
289 GeomAdaptor_Curve C
290 ((*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve());
291 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
292 // the number of intervals obtained from the basis to
293 // vvv reflect parameter bounds
294 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
295 if (iNbBasisInt>1)
296 {
297 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
298 C.Intervals(rdfInter,BaseS);
299 for (iInt=1; iInt<=iNbBasisInt; iInt++)
300 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
301 myNbIntervals++;
302 }
303 // akm 05/04/02 ^^^
304 }
305 return myNbIntervals;
306}
307
308//=======================================================================
309//function : Intervals
310//purpose :
311//=======================================================================
312
313void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
314 const GeomAbs_Shape S )
315{
316 Standard_Integer myNbIntervals = 1;
317 Standard_Integer NbSplit;
318
319 if (myTypeCurve == GeomAbs_BSplineCurve)
320 {
321 Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
322 Standard_Integer LastIndex = myBspl->LastUKnotIndex();
323 TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
324
325 if ( S > Continuity()) {
326 Standard_Integer Cont;
327 switch ( S) {
328 case GeomAbs_G1:
329 case GeomAbs_G2:
330 Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
331 break;
332 case GeomAbs_C0:
333 myNbIntervals = 1;
334 break;
335 case GeomAbs_C1:
336 case GeomAbs_C2:
337 case GeomAbs_C3:
338 case GeomAbs_CN:
339 {
340 if ( S == GeomAbs_C1) Cont = 1;
341 else if ( S == GeomAbs_C2) Cont = 2;
342 else if ( S == GeomAbs_C3) Cont = 3;
343 else Cont = myBspl->Degree();
344 Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
345 Standard_Integer LastIndex = myBspl->LastUKnotIndex();
346 Standard_Integer Degree = myBspl->Degree();
347 Standard_Integer NbKnots = myBspl->NbKnots();
348 TColStd_Array1OfInteger Mults (1, NbKnots);
349 myBspl->Multiplicities (Mults);
350 NbSplit = 1;
351 Standard_Integer Index = FirstIndex;
352 Inter (NbSplit) = Index;
353 Index++;
354 NbSplit++;
355 while (Index < LastIndex)
356 {
357 if (Degree - Mults (Index) < Cont)
358 {
359 Inter (NbSplit) = Index;
360 NbSplit++;
361 }
362 Index++;
363 }
364 Inter (NbSplit) = Index;
365 Standard_Integer NbInt = NbSplit-1;
366 // GeomConvert_BSplineCurveKnotSplitting Convector(myBspl, Cont);
367 // Standard_Integer NbInt = Convector.NbSplits()-1;
368 // TColStd_Array1OfInteger Inter(1,NbInt+1);
369 // Convector.Splitting( Inter);
370
371 Standard_Integer Nb = myBspl->NbKnots();
372 Standard_Integer Index1 = 0;
373 Standard_Integer Index2 = 0;
374 Standard_Real newFirst, newLast;
375 TColStd_Array1OfReal TK(1,Nb);
376 TColStd_Array1OfInteger TM(1,Nb);
377 myBspl->Knots(TK);
378 myBspl->Multiplicities(TM);
379 BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst,
380 myBspl->IsPeriodic(),
381 1,Nb,Index1,newFirst);
382 BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast,
383 myBspl->IsPeriodic(),
384 1,Nb,Index2,newLast);
385 // On decale eventuellement les indices
386 // On utilise une "petite" tolerance, la resolution ne doit
387 // servir que pour les tres longue courbes....(PRO9248)
388 Standard_Real Eps = Min(Resolution(Precision::Confusion()),
389 Precision::PConfusion());
390 if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
391 if ( newLast-TK(Index2)> Eps) Index2++;
392
393 Inter( 1) = Index1;
394 myNbIntervals = 1;
395 for ( Standard_Integer i=1; i<=NbInt; i++) {
396 if (Inter(i) > Index1 && Inter(i)<Index2 ) {
397 myNbIntervals++;
398 Inter(myNbIntervals) = Inter(i);
399 }
400 }
401 Inter(myNbIntervals+1) = Index2;
402
403 for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
404 T(I) = TK(Inter(I));
405 }
406 }
407 break;
408 }
409 }
410 }
411
412 else if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))){
413 GeomAbs_Shape BaseS=GeomAbs_C0;
414 switch(S){
415 case GeomAbs_G1:
416 case GeomAbs_G2:
417 Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
418 break;
419 case GeomAbs_C0: BaseS = GeomAbs_C1; break;
420 case GeomAbs_C1: BaseS = GeomAbs_C2; break;
421 case GeomAbs_C2: BaseS = GeomAbs_C3; break;
422 default: BaseS = GeomAbs_CN;
423 }
424 GeomAdaptor_Curve C
425 ((*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve());
426 // akm 05/04/02 (OCC278) If our curve is trimmed we must recalculate
427 // the array of intervals obtained from the basis to
428 // vvv reflect parameter bounds
429 Standard_Integer iNbBasisInt = C.NbIntervals(BaseS), iInt;
430 if (iNbBasisInt>1)
431 {
432 TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
433 C.Intervals(rdfInter,BaseS);
434 for (iInt=1; iInt<=iNbBasisInt; iInt++)
435 if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
436 T(++myNbIntervals)=rdfInter(iInt);
437 }
438 // old - myNbIntervals = C.NbIntervals(BaseS);
439 // old - C.Intervals(T, BaseS);
440 // akm 05/04/02 ^^^
441 }
442
443 T( T.Lower() ) = myFirst;
444 T( T.Lower() + myNbIntervals ) = myLast;
445}
446
447//=======================================================================
448//function : Trim
449//purpose :
450//=======================================================================
451
452Handle(Adaptor3d_HCurve) GeomAdaptor_Curve::Trim(const Standard_Real First,
453 const Standard_Real Last,
454 const Standard_Real /*Tol*/) const
455{
456 return Handle(GeomAdaptor_HCurve)(new GeomAdaptor_HCurve(myCurve,First,Last));
457}
458
459
460//=======================================================================
461//function : IsClosed
462//purpose :
463//=======================================================================
464
465Standard_Boolean GeomAdaptor_Curve::IsClosed() const
466{
467 if (!Precision::IsPositiveInfinite(myLast) &&
468 !Precision::IsNegativeInfinite(myFirst))
469 {
470 const gp_Pnt Pd = Value(myFirst);
471 const gp_Pnt Pf = Value(myLast);
472 return (Pd.Distance(Pf) <= Precision::Confusion());
473 }
474 return Standard_False;
475}
476
477//=======================================================================
478//function : IsPeriodic
479//purpose :
480//=======================================================================
481
482Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const
483{
484 return (myCurve->IsPeriodic()? IsClosed() : Standard_False);
485}
486
487//=======================================================================
488//function : Period
489//purpose :
490//=======================================================================
491
492Standard_Real GeomAdaptor_Curve::Period() const
493{
494 return myCurve->LastParameter() - myCurve->FirstParameter();
495}
496
497//=======================================================================
498//function : Value
499//purpose :
500//=======================================================================
501
502gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
503{
504 if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
505 (U==myFirst || U==myLast) ) {
506 Standard_Integer Ideb, Ifin;
507 if (U==myFirst) {
508 myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
509 if (Ideb<1) Ideb=1;
510 if (Ideb>=Ifin) Ifin = Ideb+1;
511 }
512 if (U==myLast) {
513 myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
514 if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
515 if (Ideb>=Ifin) Ideb = Ifin-1;
516 }
517 return myBspl->LocalValue(U, Ideb, Ifin);
518 }
519 return myCurve->Value(U);
520}
521
522//=======================================================================
523//function : D0
524//purpose :
525//=======================================================================
526
527void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
528{
529 if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
530 (U==myFirst || U==myLast) ) {
531 Standard_Integer Ideb, Ifin;
532 if (U==myFirst) {
533 myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
534 if (Ideb<1) Ideb=1;
535 if (Ideb>=Ifin) Ifin = Ideb+1;
536 }
537 if (U==myLast) {
538 myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
539 if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
540 if (Ideb>=Ifin) Ideb = Ifin-1;
541 }
542 myBspl->LocalD0( U, Ideb, Ifin, P);
543 }
544 else {
545 myCurve->D0(U, P);
546 }
547}
548
549//=======================================================================
550//function : D1
551//purpose :
552//=======================================================================
553
554void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
555{
556 if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
557 (U==myFirst || U==myLast) ) {
558 Standard_Integer Ideb, Ifin;
559 if (U==myFirst) {
560 myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
561 if (Ideb<1) Ideb=1;
562 if (Ideb>=Ifin) Ifin = Ideb+1;
563 }
564 if (U==myLast) {
565 myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
566 if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
567 if (Ideb>=Ifin) Ideb = Ifin-1;
568 }
569 myBspl->LocalD1( U, Ideb, Ifin, P, V);
570 }
571 else {
572 myCurve->D1( U, P, V);
573 }
574}
575
576//=======================================================================
577//function : D2
578//purpose :
579//=======================================================================
580
581void GeomAdaptor_Curve::D2(const Standard_Real U,
582 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
583{
584 if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
585 (U==myFirst || U==myLast) ) {
586 Standard_Integer Ideb, Ifin;
587 if (U==myFirst) {
588 myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
589 if (Ideb<1) Ideb=1;
590 if (Ideb>=Ifin) Ifin = Ideb+1;
591 }
592 if (U==myLast) {
593 myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
594 if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
595 if (Ideb>=Ifin) Ideb = Ifin-1;
596 }
597 myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
598 }
599 else {
600 myCurve->D2( U, P, V1, V2);
601 }
602}
603
604//=======================================================================
605//function : D3
606//purpose :
607//=======================================================================
608
609void GeomAdaptor_Curve::D3(const Standard_Real U,
610 gp_Pnt& P, gp_Vec& V1,
611 gp_Vec& V2, gp_Vec& V3) const
612{
613 if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
614 (U==myFirst || U==myLast) ) {
615 Standard_Integer Ideb, Ifin;
616 if (U==myFirst) {
617 myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
618 if (Ideb<1) Ideb=1;
619 if (Ideb>=Ifin) Ifin = Ideb+1;
620 }
621 if (U==myLast) {
622 myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
623 if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
624 if (Ideb>=Ifin) Ideb = Ifin-1;
625 }
626 myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
627 }
628 else {
629 myCurve->D3( U, P, V1, V2, V3);
630 }
631}
632
633//=======================================================================
634//function : DN
635//purpose :
636//=======================================================================
637
638gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
639 const Standard_Integer N) const
640{
641 if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
642 (U==myFirst || U==myLast) ) {
643 Standard_Integer Ideb, Ifin;
644 if (U==myFirst) {
645 myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
646 if (Ideb<1) Ideb=1;
647 if (Ideb>=Ifin) Ifin = Ideb+1;
648 }
649 if (U==myLast) {
650 myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
651 if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
652 if (Ideb>=Ifin) Ideb = Ifin-1;
653 }
654 return myBspl->LocalDN( U, Ideb, Ifin, N);
655 }
656 else {
657 return myCurve->DN( U, N);
658 }
659}
660
661//=======================================================================
662//function : Resolution
663//purpose :
664//=======================================================================
665
666Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
667{
668 switch ( myTypeCurve) {
669 case GeomAbs_Line :
670 return R3D;
671 case GeomAbs_Circle: {
672 Standard_Real R = (*((Handle(Geom_Circle)*)&myCurve))->Circ().Radius();
673 if ( R > R3D/2. )
674 return 2*ASin(R3D/(2*R));
675 else
676 return 2*PI;
677 }
678 case GeomAbs_Ellipse: {
679 return R3D / (*((Handle(Geom_Ellipse)*)&myCurve))->MajorRadius();
680 }
681 case GeomAbs_BezierCurve: {
682 Standard_Real res;
683 (*((Handle(Geom_BezierCurve)*)&myCurve))->Resolution(R3D,res);
684 return res;
685 }
686 case GeomAbs_BSplineCurve: {
687 Standard_Real res;
688 (*((Handle(Geom_BSplineCurve)*)&myCurve))->Resolution(R3D,res);
689 return res;
690 }
691 default:
692 return Precision::Parametric(R3D);
693 }
694}
695
696
697// --
698// -- The following methods must be called when GetType returned
699// -- the corresponding type.
700// --
701
702//=======================================================================
703//function : Line
704//purpose :
705//=======================================================================
706
707gp_Lin GeomAdaptor_Curve::Line() const
708{
709 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, "");
710 return (*((Handle(Geom_Line)*)&myCurve))->Lin();
711}
712
713//=======================================================================
714//function : Circle
715//purpose :
716//=======================================================================
717
718gp_Circ GeomAdaptor_Curve::Circle() const
719{
720 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, "");
721 return (*((Handle(Geom_Circle)*)&myCurve))->Circ();
722}
723
724//=======================================================================
725//function : Ellipse
726//purpose :
727//=======================================================================
728
729gp_Elips GeomAdaptor_Curve::Ellipse() const
730{
731 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, "");
732 return (*((Handle(Geom_Ellipse)*)&myCurve))->Elips();
733}
734
735//=======================================================================
736//function : Hyperbola
737//purpose :
738//=======================================================================
739
740gp_Hypr GeomAdaptor_Curve::Hyperbola() const
741{
742 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, "");
743 return (*((Handle(Geom_Hyperbola)*)&myCurve))->Hypr();
744}
745
746//=======================================================================
747//function : Parabola
748//purpose :
749//=======================================================================
750
751gp_Parab GeomAdaptor_Curve::Parabola() const
752{
753 Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, "");
754 return (*((Handle(Geom_Parabola)*)&myCurve))->Parab();
755}
756
757//=======================================================================
758//function : Degree
759//purpose :
760//=======================================================================
761
762Standard_Integer GeomAdaptor_Curve::Degree() const
763{
764 if (myTypeCurve == GeomAbs_BezierCurve)
765 return (*((Handle(Geom_BezierCurve)*)&myCurve))->Degree();
766 else if (myTypeCurve == GeomAbs_BSplineCurve)
767 return (*((Handle(Geom_BSplineCurve)*)&myCurve))->Degree();
768 else
769 Standard_NoSuchObject::Raise();
770 // portage WNT
771 return 0;
772}
773
774//=======================================================================
775//function : IsRational
776//purpose :
777//=======================================================================
778
779Standard_Boolean GeomAdaptor_Curve::IsRational() const {
780 switch( myTypeCurve) {
781 case GeomAbs_BSplineCurve:
782 return (*((Handle(Geom_BSplineCurve)*)&myCurve))->IsRational();
783 case GeomAbs_BezierCurve:
784 return (*((Handle(Geom_BezierCurve)*)&myCurve))->IsRational();
785 default:
786 return Standard_False;
787 }
788}
789
790//=======================================================================
791//function : NbPoles
792//purpose :
793//=======================================================================
794
795Standard_Integer GeomAdaptor_Curve::NbPoles() const
796{
797 if (myTypeCurve == GeomAbs_BezierCurve)
798 return (*((Handle(Geom_BezierCurve)*)&myCurve))->NbPoles();
799 else if (myTypeCurve == GeomAbs_BSplineCurve)
800 return (*((Handle(Geom_BSplineCurve)*)&myCurve))->NbPoles();
801 else
802 Standard_NoSuchObject::Raise();
803 // portage WNT
804 return 0;
805}
806
807//=======================================================================
808//function : NbKnots
809//purpose :
810//=======================================================================
811
812Standard_Integer GeomAdaptor_Curve::NbKnots() const
813{
814 if ( myTypeCurve != GeomAbs_BSplineCurve)
815 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::NbKnots");
816 return (*((Handle(Geom_BSplineCurve)*)&myCurve))->NbKnots();
817}
818
819//=======================================================================
820//function : Bezier
821//purpose :
822//=======================================================================
823
824Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
825{
826 if ( myTypeCurve != GeomAbs_BezierCurve)
827 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Bezier");
828 return *((Handle(Geom_BezierCurve)*)&myCurve);
829}
830
831//=======================================================================
832//function : BSpline
833//purpose :
834//=======================================================================
835
836Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
837{
838 if ( myTypeCurve != GeomAbs_BSplineCurve)
839 Standard_NoSuchObject::Raise("GeomAdaptor_Curve::BSpline");
840
841 return *((Handle(Geom_BSplineCurve)*)&myCurve);
842}
843