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