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