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