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