0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / GeomAdaptor / GeomAdaptor_Surface.cxx
1 // Created on: 1993-05-14
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified:    Thu Nov 26 16:37:18 1998
18 //              correction in NbUIntervals for SurfaceOfLinearExtrusion 
19 //              (PRO16346)
20
21 #define No_Standard_RangeError
22 #define No_Standard_OutOfRange
23 #define PosTol (Precision::PConfusion()*0.5)
24
25 #include <GeomAdaptor_Surface.ixx>
26
27 #include <GeomAdaptor_HSurface.hxx>
28 #include <GeomAdaptor_HCurve.hxx>
29 #include <GeomAdaptor_Curve.hxx>
30 #include <Adaptor3d_HSurface.hxx>
31 #include <Standard_OutOfRange.hxx>
32 #include <Geom_RectangularTrimmedSurface.hxx>
33 #include <Geom_BSplineSurface.hxx> 
34 #include <Geom_BezierSurface.hxx> 
35 #include <Geom_OffsetSurface.hxx>
36 //#include <GeomConvert_BSplineSurfaceKnotSplitting.hxx>
37 #include <Standard_OutOfRange.hxx>
38 #include <TColStd_HArray1OfInteger.hxx>
39 #include <TColStd_Array1OfReal.hxx>
40 #include <TColStd_Array1OfInteger.hxx>
41 #include <Geom_Plane.hxx>
42 #include <Geom_CylindricalSurface.hxx>
43 #include <Geom_SphericalSurface.hxx>
44 #include <Geom_ToroidalSurface.hxx>
45 #include <Geom_ConicalSurface.hxx>
46 #include <Geom_SurfaceOfRevolution.hxx>
47 #include <Geom_SurfaceOfLinearExtrusion.hxx>
48 #include <Geom_Curve.hxx>
49 #include <Geom_Circle.hxx>
50 #include <gp_Circ.hxx>
51 #include <gp_Lin.hxx>
52 #include <gp_Trsf.hxx>
53 #include <BSplCLib.hxx>
54 #include <BSplSLib_Cache.hxx>
55 #include <Precision.hxx>
56 #include <Standard_NoSuchObject.hxx>
57 #include <Standard_NullObject.hxx>
58
59 #define myBspl Handle(Geom_BSplineSurface)::DownCast (mySurface)
60 #define myExtSurf Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)
61 #define myRevSurf Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)
62 #define myOffSurf Handle(Geom_OffsetSurface)::DownCast (mySurface)
63
64 //=======================================================================
65 //function : LocalContinuity
66 //purpose  : 
67 //=======================================================================
68
69 GeomAbs_Shape LocalContinuity(Standard_Integer         Degree,
70                               Standard_Integer         Nb,
71                               TColStd_Array1OfReal&    TK,
72                               TColStd_Array1OfInteger& TM,
73                               Standard_Real            PFirst,
74                               Standard_Real            PLast,
75                               Standard_Boolean         IsPeriodic) 
76 {
77   Standard_DomainError_Raise_if( (TK.Length()!=Nb || TM.Length()!=Nb )," ");
78   Standard_Integer Index1 = 0;
79   Standard_Integer Index2 = 0;
80   Standard_Real newFirst, newLast;
81   BSplCLib::LocateParameter(Degree,TK,TM,PFirst,IsPeriodic,1,Nb,Index1,newFirst);
82   BSplCLib::LocateParameter(Degree,TK,TM,PLast, IsPeriodic,1,Nb,Index2,newLast );
83   const Standard_Real EpsKnot = Precision::PConfusion();
84   if (Abs(newFirst-TK(Index1+1))< EpsKnot) Index1++;
85   if (Abs(newLast -TK(Index2  ))< EpsKnot) Index2--;
86   // attention aux courbes peridiques.
87   if ( (IsPeriodic) && (Index1 == Nb) )
88     Index1 = 1;
89
90   if (Index2!=Index1)
91   {
92     Standard_Integer i, Multmax = TM(Index1+1);
93         for (i = Index1+1; i<=Index2; i++) {
94       if (TM(i)>Multmax) Multmax=TM(i);
95     }
96     Multmax = Degree - Multmax;
97     if (Multmax <= 0) return GeomAbs_C0;
98     switch (Multmax) {
99     case 1: return GeomAbs_C1;
100     case 2: return GeomAbs_C2;
101     case 3: return GeomAbs_C3;
102     }
103   }
104   return GeomAbs_CN;
105 }
106
107 //=======================================================================
108 //function : Load
109 //purpose  : 
110 //=======================================================================
111
112 void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
113                                const Standard_Real UFirst,
114                                const Standard_Real ULast,
115                                const Standard_Real VFirst,
116                                const Standard_Real VLast,
117                                const Standard_Real TolU,
118                                const Standard_Real TolV)
119 {
120   myTolU =  TolU;
121   myTolV =  TolV;  
122   myUFirst = UFirst;
123   myULast  = ULast;
124   myVFirst = VFirst;
125   myVLast  = VLast;
126
127   if ( mySurface != S) {
128     mySurface = S;
129     
130     const Handle(Standard_Type)& TheType = S->DynamicType();
131     if ( TheType == STANDARD_TYPE(Geom_BezierSurface))
132       mySurfaceType = GeomAbs_BezierSurface;
133     else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
134       Load(Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(),
135            UFirst,ULast,VFirst,VLast);
136     }
137     else if ( TheType == STANDARD_TYPE(Geom_Plane))
138       mySurfaceType = GeomAbs_Plane;
139     else if ( TheType == STANDARD_TYPE(Geom_CylindricalSurface))
140       mySurfaceType = GeomAbs_Cylinder;
141     else if ( TheType == STANDARD_TYPE(Geom_ConicalSurface))
142       mySurfaceType = GeomAbs_Cone;
143     else if ( TheType == STANDARD_TYPE(Geom_SphericalSurface))
144       mySurfaceType = GeomAbs_Sphere;
145     else if ( TheType == STANDARD_TYPE(Geom_ToroidalSurface))
146       mySurfaceType = GeomAbs_Torus;
147     else if ( TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
148       mySurfaceType = GeomAbs_SurfaceOfRevolution;
149     else if ( TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
150       mySurfaceType = GeomAbs_SurfaceOfExtrusion;
151     else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
152       mySurfaceType = GeomAbs_BSplineSurface;
153       myBspl        = Handle(Geom_BSplineSurface)::DownCast (mySurface);
154       // Create cache for B-spline
155       mySurfaceCache = new BSplSLib_Cache( 
156         myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), 
157         myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), 
158         myBspl->Poles(), myBspl->Weights());
159     }
160     else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
161       mySurfaceType = GeomAbs_OffsetSurface;
162     else
163       mySurfaceType = GeomAbs_OtherSurface;
164   }
165 }
166
167 //    --
168 //    --     Global methods - Apply to the whole Surface.
169 //    --     
170
171
172 //=======================================================================
173 //function : UContinuity
174 //purpose  : 
175 //=======================================================================
176
177 GeomAbs_Shape GeomAdaptor_Surface::UContinuity() const 
178 {
179   switch (mySurfaceType)
180   {
181     case GeomAbs_BSplineSurface:
182     {
183       const Standard_Integer N = myBspl->NbUKnots();
184       TColStd_Array1OfReal TK(1,N);
185       TColStd_Array1OfInteger TM(1,N);
186       myBspl->UKnots(TK);
187       myBspl->UMultiplicities(TM);
188       return LocalContinuity(myBspl->UDegree(), myBspl->NbUKnots(), TK, TM,
189                              myUFirst, myULast, IsUPeriodic());
190     }
191     case GeomAbs_OffsetSurface:
192     {
193       switch(BasisSurface()->UContinuity())
194       {
195       case GeomAbs_CN :
196       case GeomAbs_C3 : return GeomAbs_CN;
197       case GeomAbs_G2 :
198       case GeomAbs_C2 : return GeomAbs_C1;
199       case GeomAbs_G1 :
200       case GeomAbs_C1 : return GeomAbs_C0;
201       case GeomAbs_C0 : break;
202       }
203       Standard_NoSuchObject::Raise("GeomAdaptor_Surface::UContinuity");
204       break;
205     }
206     case GeomAbs_SurfaceOfExtrusion:
207     {
208       GeomAdaptor_Curve GC
209         (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
210       return GC.Continuity();
211     }
212     case GeomAbs_OtherSurface: 
213       Standard_NoSuchObject::Raise("GeomAdaptor_Surface::UContinuity");
214     case GeomAbs_Plane:
215     case GeomAbs_Cylinder:
216     case GeomAbs_Cone:
217     case GeomAbs_Sphere:
218     case GeomAbs_Torus:
219     case GeomAbs_BezierSurface:
220     case GeomAbs_SurfaceOfRevolution: break;
221   }
222   return GeomAbs_CN;
223 }
224
225 //=======================================================================
226 //function : VContinuity
227 //purpose  : 
228 //=======================================================================
229
230 GeomAbs_Shape GeomAdaptor_Surface::VContinuity() const 
231 {
232   switch (mySurfaceType)
233   {
234     case GeomAbs_BSplineSurface:
235     {
236       const Standard_Integer N = myBspl->NbVKnots();
237       TColStd_Array1OfReal TK(1,N);
238       TColStd_Array1OfInteger TM(1,N);
239       myBspl->VKnots(TK);
240       myBspl->VMultiplicities(TM);
241       return LocalContinuity(myBspl->VDegree(), myBspl->NbVKnots(), TK, TM,
242                              myVFirst, myVLast, IsVPeriodic());
243     }
244     case GeomAbs_OffsetSurface:
245     {
246       switch(BasisSurface()->VContinuity())
247       {
248       case GeomAbs_CN : 
249       case GeomAbs_C3 : return GeomAbs_CN; 
250       case GeomAbs_G2 :
251       case GeomAbs_C2 : return GeomAbs_C1;
252       case GeomAbs_G1 :
253       case GeomAbs_C1 : return GeomAbs_C0;
254       case GeomAbs_C0 : break;
255       }
256       Standard_NoSuchObject::Raise("GeomAdaptor_Surface::VContinuity");
257       break;
258     }
259     case GeomAbs_SurfaceOfRevolution:
260     {
261       GeomAdaptor_Curve GC
262         (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myVFirst,myVLast);
263       return GC.Continuity();
264     }
265     case GeomAbs_OtherSurface:
266       Standard_NoSuchObject::Raise("GeomAdaptor_Surface::VContinuity");
267     case GeomAbs_Plane:
268     case GeomAbs_Cylinder:
269     case GeomAbs_Cone:
270     case GeomAbs_Sphere:
271     case GeomAbs_Torus:
272     case GeomAbs_BezierSurface:
273     case GeomAbs_SurfaceOfExtrusion: break;
274   }
275   return GeomAbs_CN;
276 }
277
278 //=======================================================================
279 //function : NbUIntervals
280 //purpose  : 
281 //=======================================================================
282
283 Standard_Integer GeomAdaptor_Surface::NbUIntervals(const GeomAbs_Shape S) const
284 {
285   switch (mySurfaceType)
286   {
287     case GeomAbs_BSplineSurface:
288     {
289       GeomAdaptor_Curve myBasisCurve
290         (myBspl->VIso(myBspl->VKnot(myBspl->FirstVKnotIndex())),myUFirst,myULast);
291       return myBasisCurve.NbIntervals(S);
292     }
293           case GeomAbs_SurfaceOfExtrusion:
294     {
295       GeomAdaptor_Curve myBasisCurve
296         (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
297           if (myBasisCurve.GetType() == GeomAbs_BSplineCurve)
298         return myBasisCurve.NbIntervals(S);
299       break;
300     }
301           case GeomAbs_OffsetSurface:
302     {
303       GeomAbs_Shape BaseS = GeomAbs_CN;
304       switch(S)
305       {
306         case GeomAbs_G1:
307         case GeomAbs_G2: Standard_DomainError::Raise("GeomAdaptor_Curve::NbUIntervals");
308         case GeomAbs_C0: BaseS = GeomAbs_C1; break;
309         case GeomAbs_C1: BaseS = GeomAbs_C2; break;
310         case GeomAbs_C2: BaseS = GeomAbs_C3; break;
311         case GeomAbs_C3:
312         case GeomAbs_CN: break;
313       }
314       GeomAdaptor_Surface Sur(Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface());
315       return Sur.NbUIntervals(BaseS);
316     }
317     case GeomAbs_Plane:
318     case GeomAbs_Cylinder:
319     case GeomAbs_Cone:
320     case GeomAbs_Sphere:
321     case GeomAbs_Torus:
322     case GeomAbs_BezierSurface:
323     case GeomAbs_OtherSurface:
324     case GeomAbs_SurfaceOfRevolution: break;
325   }
326   return 1;
327 }
328
329 //=======================================================================
330 //function : NbVIntervals
331 //purpose  : 
332 //=======================================================================
333
334 Standard_Integer GeomAdaptor_Surface::NbVIntervals(const GeomAbs_Shape S) const
335 {
336   switch (mySurfaceType)
337   {
338     case GeomAbs_BSplineSurface:
339     {
340       GeomAdaptor_Curve myBasisCurve
341         (myBspl->UIso(myBspl->UKnot(myBspl->FirstUKnotIndex())),myVFirst,myVLast);
342       return myBasisCurve.NbIntervals(S);
343     }
344           case GeomAbs_SurfaceOfRevolution:
345     {
346       GeomAdaptor_Curve myBasisCurve
347         (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myVFirst,myVLast);
348           if (myBasisCurve.GetType() == GeomAbs_BSplineCurve)
349         return myBasisCurve.NbIntervals(S);
350       break;
351     }
352           case GeomAbs_OffsetSurface:
353     {
354       GeomAbs_Shape BaseS = GeomAbs_CN;
355       switch(S)
356       {
357         case GeomAbs_G1:
358         case GeomAbs_G2: Standard_DomainError::Raise("GeomAdaptor_Curve::NbVIntervals");
359         case GeomAbs_C0: BaseS = GeomAbs_C1; break;
360         case GeomAbs_C1: BaseS = GeomAbs_C2; break;
361         case GeomAbs_C2: BaseS = GeomAbs_C3; break;
362         case GeomAbs_C3:
363         case GeomAbs_CN: break;
364       }
365       GeomAdaptor_Surface Sur(Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface());
366       return Sur.NbVIntervals(BaseS);
367           }
368     case GeomAbs_Plane:
369     case GeomAbs_Cylinder:
370     case GeomAbs_Cone:
371     case GeomAbs_Sphere:
372     case GeomAbs_Torus:
373     case GeomAbs_BezierSurface:
374     case GeomAbs_OtherSurface:
375     case GeomAbs_SurfaceOfExtrusion: break;
376   }
377   return 1;
378 }
379
380 //=======================================================================
381 //function : UIntervals
382 //purpose  : 
383 //=======================================================================
384
385 void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
386 {
387   Standard_Integer myNbUIntervals = 1;
388
389   switch (mySurfaceType)
390   {
391     case GeomAbs_BSplineSurface:
392     {
393       GeomAdaptor_Curve myBasisCurve
394         (myBspl->VIso(myBspl->VKnot(myBspl->FirstVKnotIndex())),myUFirst,myULast);
395       myNbUIntervals = myBasisCurve.NbIntervals(S);
396       myBasisCurve.Intervals(T,S);
397       break;
398     }
399           case GeomAbs_SurfaceOfExtrusion:
400     {
401       GeomAdaptor_Curve myBasisCurve
402         (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
403       if (myBasisCurve.GetType() == GeomAbs_BSplineCurve)
404       {
405         myNbUIntervals = myBasisCurve.NbIntervals(S);
406         myBasisCurve.Intervals(T,S);
407       }
408       break;
409     }
410           case GeomAbs_OffsetSurface:
411     {
412       GeomAbs_Shape BaseS = GeomAbs_CN;
413       switch(S)
414       {
415         case GeomAbs_G1:
416         case GeomAbs_G2: Standard_DomainError::Raise("GeomAdaptor_Curve::UIntervals");
417         case GeomAbs_C0: BaseS = GeomAbs_C1; break;
418         case GeomAbs_C1: BaseS = GeomAbs_C2; break;
419         case GeomAbs_C2: BaseS = GeomAbs_C3; break;
420         case GeomAbs_C3:
421         case GeomAbs_CN: break;
422       }
423       GeomAdaptor_Surface Sur(Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface());
424       myNbUIntervals = Sur.NbUIntervals(BaseS);
425       Sur.UIntervals(T, BaseS);
426     }
427     case GeomAbs_Plane:
428     case GeomAbs_Cylinder:
429     case GeomAbs_Cone:
430     case GeomAbs_Sphere:
431     case GeomAbs_Torus:
432     case GeomAbs_BezierSurface:
433     case GeomAbs_OtherSurface:
434     case GeomAbs_SurfaceOfRevolution: break;
435   }
436
437   T(T.Lower()) = myUFirst;
438   T(T.Lower() + myNbUIntervals) = myULast;
439 }
440
441 //=======================================================================
442 //function : VIntervals
443 //purpose  : 
444 //=======================================================================
445
446 void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
447 {
448   Standard_Integer myNbVIntervals = 1;
449
450   switch (mySurfaceType)
451   {
452     case GeomAbs_BSplineSurface:
453     {
454       GeomAdaptor_Curve myBasisCurve
455         (myBspl->UIso(myBspl->UKnot(myBspl->FirstUKnotIndex())),myVFirst,myVLast);
456       myNbVIntervals = myBasisCurve.NbIntervals(S);
457       myBasisCurve.Intervals(T,S);
458       break;
459     }
460           case GeomAbs_SurfaceOfRevolution:
461     {
462       GeomAdaptor_Curve myBasisCurve
463         (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myVFirst,myVLast);
464       if (myBasisCurve.GetType() == GeomAbs_BSplineCurve)
465       {
466         myNbVIntervals = myBasisCurve.NbIntervals(S);
467         myBasisCurve.Intervals(T,S);
468       }
469       break;
470     }
471           case GeomAbs_OffsetSurface:
472     {
473       GeomAbs_Shape BaseS = GeomAbs_CN;
474       switch(S)
475       {
476         case GeomAbs_G1:
477         case GeomAbs_G2: Standard_DomainError::Raise("GeomAdaptor_Curve::VIntervals");
478         case GeomAbs_C0: BaseS = GeomAbs_C1; break;
479         case GeomAbs_C1: BaseS = GeomAbs_C2; break;
480         case GeomAbs_C2: BaseS = GeomAbs_C3; break;
481         case GeomAbs_C3:
482         case GeomAbs_CN: break;
483       }
484       GeomAdaptor_Surface Sur(Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface());
485       myNbVIntervals = Sur.NbVIntervals(BaseS);
486       Sur.VIntervals(T, BaseS);
487     }
488     case GeomAbs_Plane:
489     case GeomAbs_Cylinder:
490     case GeomAbs_Cone:
491     case GeomAbs_Sphere:
492     case GeomAbs_Torus:
493     case GeomAbs_BezierSurface:
494     case GeomAbs_OtherSurface:
495     case GeomAbs_SurfaceOfExtrusion: break;
496   }
497   
498   T(T.Lower()) = myVFirst;
499   T(T.Lower() + myNbVIntervals) = myVLast;
500 }
501
502 //=======================================================================
503 //function : UTrim
504 //purpose  : 
505 //=======================================================================
506
507 Handle(Adaptor3d_HSurface) GeomAdaptor_Surface::UTrim(const Standard_Real First,
508                                                       const Standard_Real Last ,
509                                                       const Standard_Real Tol   ) const
510 {
511   return Handle(GeomAdaptor_HSurface)
512     (new GeomAdaptor_HSurface(mySurface,First,Last,myVFirst,myVLast,Tol,myTolV));
513 }
514
515 //=======================================================================
516 //function : VTrim
517 //purpose  : 
518 //=======================================================================
519
520 Handle(Adaptor3d_HSurface) GeomAdaptor_Surface::VTrim(const Standard_Real First,
521                                                       const Standard_Real Last ,
522                                                       const Standard_Real Tol   ) const
523 {
524   return Handle(GeomAdaptor_HSurface)
525     (new GeomAdaptor_HSurface(mySurface,myUFirst,myULast,First,Last,myTolU,Tol));
526 }
527
528 //=======================================================================
529 //function : IsUClosed
530 //purpose  : 
531 //=======================================================================
532
533 Standard_Boolean GeomAdaptor_Surface::IsUClosed() const 
534 {
535   if (!mySurface->IsUClosed())
536     return Standard_False;
537
538   Standard_Real U1,U2,V1,V2;
539   mySurface->Bounds(U1,U2,V1,V2);
540   if (mySurface->IsUPeriodic())
541     return (Abs(Abs(U1-U2)-Abs(myUFirst-myULast))<Precision::PConfusion());
542
543   return (   Abs(U1-myUFirst)<Precision::PConfusion() 
544           && Abs(U2-myULast )<Precision::PConfusion() );
545 }
546
547 //=======================================================================
548 //function : IsVClosed
549 //purpose  : 
550 //=======================================================================
551
552 Standard_Boolean GeomAdaptor_Surface::IsVClosed() const 
553 {
554   if (!mySurface->IsVClosed())
555     return Standard_False;
556
557   Standard_Real U1,U2,V1,V2;
558   mySurface->Bounds(U1,U2,V1,V2);
559   if (mySurface->IsVPeriodic())
560     return (Abs(Abs(V1-V2)-Abs(myVFirst-myVLast))<Precision::PConfusion());
561
562   return (   Abs(V1-myVFirst)<Precision::PConfusion() 
563           && Abs(V2-myVLast )<Precision::PConfusion() );
564 }
565
566 //=======================================================================
567 //function : IsUPeriodic
568 //purpose  : 
569 //=======================================================================
570
571 Standard_Boolean GeomAdaptor_Surface::IsUPeriodic() const 
572 {
573   return (mySurface->IsUPeriodic());
574 }
575
576 //=======================================================================
577 //function : UPeriod
578 //purpose  : 
579 //=======================================================================
580
581 Standard_Real GeomAdaptor_Surface::UPeriod() const 
582 {
583   Standard_NoSuchObject_Raise_if(!IsUPeriodic()," ");
584   return mySurface->UPeriod();
585 }
586
587 //=======================================================================
588 //function : IsVPeriodic
589 //purpose  : 
590 //=======================================================================
591
592 Standard_Boolean GeomAdaptor_Surface::IsVPeriodic() const 
593 {
594   return (mySurface->IsVPeriodic());
595 }
596
597 //=======================================================================
598 //function : VPeriod
599 //purpose  : 
600 //=======================================================================
601
602 Standard_Real GeomAdaptor_Surface::VPeriod() const 
603 {
604   Standard_NoSuchObject_Raise_if(!IsVPeriodic()," ");
605   return mySurface->VPeriod();
606 }
607
608 //=======================================================================
609 //function : RebuildCache
610 //purpose  : 
611 //=======================================================================
612 void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
613                                        const Standard_Real theV) const
614 {
615   mySurfaceCache->BuildCache(theU, theV, 
616     myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), 
617     myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), 
618     myBspl->Poles(), myBspl->Weights());
619 }
620
621 //=======================================================================
622 //function : Value
623 //purpose  : 
624 //=======================================================================
625
626 gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U, 
627                                   const Standard_Real V) const 
628 {
629   if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
630   {
631     if (!mySurfaceCache->IsCacheValid(U, V))
632       RebuildCache(U, V);
633     gp_Pnt P;
634     mySurfaceCache->D0(U, V, P);
635     return P;
636   }
637
638   return mySurface->Value(U,V);
639 }
640
641 //=======================================================================
642 //function : D0
643 //purpose  : 
644 //=======================================================================
645
646 void GeomAdaptor_Surface::D0(const Standard_Real U, 
647                              const Standard_Real V, gp_Pnt& P) const 
648 {
649   if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
650   {
651     if (!mySurfaceCache->IsCacheValid(U, V))
652       RebuildCache(U, V);
653     mySurfaceCache->D0(U, V, P);
654     return;
655   }
656
657   mySurface->D0(U,V,P);
658 }
659
660
661 //=======================================================================
662 //function : D1
663 //purpose  : 
664 //=======================================================================
665
666 void GeomAdaptor_Surface::D1(const Standard_Real U, 
667                              const Standard_Real V, 
668                                    gp_Pnt&       P,
669                                    gp_Vec&       D1U, 
670                                    gp_Vec&       D1V ) const 
671 {
672   Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
673   Standard_Real u = U, v = V;
674   if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
675   else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
676   if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
677   else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
678
679   switch(mySurfaceType) {
680   case GeomAbs_BSplineSurface:
681     if ((USide != 0 || VSide != 0) && 
682         IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
683       myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
684     else if (!mySurfaceCache.IsNull())
685     {
686       if (!mySurfaceCache->IsCacheValid(U, V))
687         RebuildCache(U, V);
688       mySurfaceCache->D1(U, V, P, D1U, D1V);
689     }
690     else
691       myBspl->D1(u, v, P, D1U, D1V);
692     break;
693
694   case GeomAbs_SurfaceOfExtrusion:
695     if (USide==0) 
696       myExtSurf->D1(u, v, P, D1U, D1V);
697     else 
698       myExtSurf->LocalD1(u, v, USide, P, D1U, D1V);
699     break;
700
701   case GeomAbs_SurfaceOfRevolution:
702     if (VSide==0) 
703       myRevSurf->D1(u, v, P, D1U, D1V);
704     else 
705       myRevSurf->LocalD1(u, v, VSide, P, D1U, D1V);
706     break;
707
708   case GeomAbs_OffsetSurface:
709     if (USide==0 && VSide==0) 
710       myOffSurf->D1(u, v, P, D1U, D1V);
711     else 
712       myOffSurf->LocalD1(u, v, USide, VSide, P, D1U, D1V);
713     break;
714   default:
715     mySurface->D1(u, v, P, D1U, D1V);
716   }
717 }
718
719 //=======================================================================
720 //function : D2
721 //purpose  : 
722 //=======================================================================
723
724 void GeomAdaptor_Surface::D2(const Standard_Real U,
725                              const Standard_Real V, 
726                                    gp_Pnt&       P,
727                                    gp_Vec&       D1U, 
728                                    gp_Vec&       D1V, 
729                                    gp_Vec&       D2U,
730                                    gp_Vec&       D2V, 
731                                    gp_Vec&       D2UV) const 
732
733   Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
734   Standard_Real u = U, v = V;
735   if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
736   else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
737   if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
738   else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
739
740   switch(mySurfaceType) {
741   case  GeomAbs_BSplineSurface:
742     if((USide != 0 || VSide != 0) && 
743        IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
744       myBspl->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV);
745     else if (!mySurfaceCache.IsNull())
746     {
747       if (!mySurfaceCache->IsCacheValid(U, V))
748         RebuildCache(U, V);
749       mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
750     }
751     else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
752     break;
753
754   case GeomAbs_SurfaceOfExtrusion  :
755
756     if(USide==0)  myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
757     else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
758     break;
759
760   case GeomAbs_SurfaceOfRevolution :
761
762     if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
763     else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
764     break;
765
766   case  GeomAbs_OffsetSurface :
767     {
768       if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV ); 
769       else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV ); 
770       break;
771     }
772   default :  { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
773     break;}
774   }
775 }
776
777
778 //=======================================================================
779 //function : D3
780 //purpose  : 
781 //=======================================================================
782
783 void GeomAdaptor_Surface::D3(const Standard_Real U, const Standard_Real V,
784                              gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V,
785                              gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
786                              gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV,
787                              gp_Vec& D3UVV) const
788 {  
789   Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
790   Standard_Real u = U, v = V;
791   if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
792   else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
793   if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
794   else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
795
796   switch(mySurfaceType) {
797   case  GeomAbs_BSplineSurface:
798     
799       if((USide==0)&&(VSide==0))
800         myBspl->D3(u,v,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
801       else {
802         if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
803           myBspl-> LocalD3 (u, v, Ideb, Ifin,IVdeb ,IVfin ,
804                             P ,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); 
805         else
806           myBspl->D3(u,v,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
807       }
808       break;
809     
810   case GeomAbs_SurfaceOfExtrusion  :
811     
812       if(USide==0)  myExtSurf->D3(u,v,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
813       else myExtSurf->LocalD3(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV,
814                               D3U,D3V,D3UUV,D3UVV);
815       break;
816     
817   case GeomAbs_SurfaceOfRevolution :
818     
819       if(VSide==0) myRevSurf->D3 (u, v, P ,D1U,D1V,D2U,D2V,D2UV,
820                                   D3U,D3V,D3UUV,D3UVV);
821       else myRevSurf->LocalD3 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV,
822                                D3U,D3V,D3UUV,D3UVV );
823       break;
824     
825   case  GeomAbs_OffsetSurface : 
826     {
827       if((USide==0)&&(VSide==0)) myOffSurf->D3 (u, v,P ,D1U,D1V,D2U,D2V,D2UV,
828                                                 D3U,D3V,D3UUV,D3UVV); 
829       else   myOffSurf->LocalD3 (u, v, USide, VSide ,P ,D1U,D1V,D2U,D2V,D2UV,
830                                  D3U,D3V,D3UUV,D3UVV); 
831       break; 
832     }
833     default : {  mySurface->D3(u,v,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); 
834                  break;}
835   }
836 }
837
838 //=======================================================================
839 //function : DN
840 //purpose  : 
841 //=======================================================================
842
843 gp_Vec GeomAdaptor_Surface::DN(const Standard_Real    U,
844                                const Standard_Real    V, 
845                                const Standard_Integer Nu,
846                                const Standard_Integer Nv) const 
847 {
848   Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
849   Standard_Real u = U, v = V;
850   if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
851   else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
852   if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
853   else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
854
855   switch(mySurfaceType) 
856   {
857   case GeomAbs_BSplineSurface:
858     
859     if((USide==0)&&(VSide==0)) return  myBspl->DN(u,v,Nu,Nv);
860     else {
861       if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
862         return myBspl->LocalDN (u, v, Ideb, Ifin,IVdeb ,IVfin ,Nu,Nv ); 
863       else
864         return  myBspl->DN(u,v,Nu,Nv); 
865     }
866     
867   case GeomAbs_SurfaceOfExtrusion:
868     
869     if(USide==0)  return myExtSurf-> DN (u, v,Nu,Nv );
870     else return myExtSurf->LocalDN (u, v, USide,Nu,Nv );
871     
872   case GeomAbs_SurfaceOfRevolution:
873
874     if(VSide==0)  return myRevSurf->DN (u, v, Nu, Nv );
875     else  return myRevSurf->LocalDN (u, v,VSide, Nu, Nv );
876      
877   case GeomAbs_OffsetSurface:
878     
879     if((USide==0)&&(VSide==0)) return myOffSurf->DN (u, v, Nu, Nv );
880     else return myOffSurf->LocalDN (u, v, USide, VSide, Nu, Nv );
881
882   case GeomAbs_Plane:
883   case GeomAbs_Cylinder:
884   case GeomAbs_Cone:
885   case GeomAbs_Sphere:
886   case GeomAbs_Torus:
887   case GeomAbs_BezierSurface:
888   case GeomAbs_OtherSurface:
889   default:
890     break;
891   }
892   
893   return mySurface->DN(u,v, Nu, Nv);
894 }
895
896
897 //=======================================================================
898 //function : UResolution
899 //purpose  : 
900 //=======================================================================
901
902 Standard_Real GeomAdaptor_Surface::UResolution(const Standard_Real R3d) const
903 {
904   Standard_Real Res = 0.;
905
906   switch (mySurfaceType)
907   {
908     case GeomAbs_SurfaceOfExtrusion:
909     {
910       GeomAdaptor_Curve myBasisCurve
911         (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
912       return myBasisCurve.Resolution(R3d);
913     }
914         case GeomAbs_Torus:
915     {
916       Handle(Geom_ToroidalSurface)& S = Handle(Geom_ToroidalSurface)::DownCast (mySurface);
917       const Standard_Real R = S->MajorRadius() + S->MinorRadius();
918       if(R>Precision::Confusion())
919         Res = R3d/(2.*R);
920           break;
921     }
922         case GeomAbs_Sphere:
923     {
924       Handle(Geom_SphericalSurface)& S = Handle(Geom_SphericalSurface)::DownCast (mySurface);
925       const Standard_Real R = S->Radius();
926       if(R>Precision::Confusion())
927         Res = R3d/(2.*R);
928           break;
929     }
930         case GeomAbs_Cylinder:
931     {
932       Handle(Geom_CylindricalSurface)& S = Handle(Geom_CylindricalSurface)::DownCast (mySurface);
933       const Standard_Real R = S->Radius();
934       if(R>Precision::Confusion())
935         Res = R3d/(2.*R);
936           break;
937     }
938         case GeomAbs_Cone:
939     {
940       if (myVLast - myVFirst > 1.e10) {
941         // Pas vraiment borne => resolution inconnue
942         return Precision::Parametric(R3d);
943       }
944       Handle(Geom_ConicalSurface)& S = Handle(Geom_ConicalSurface)::DownCast (mySurface);
945       Handle(Geom_Curve) C = S->VIso(myVLast);
946       const Standard_Real Rayon1 = Handle(Geom_Circle)::DownCast (C)->Radius();
947       C = S->VIso(myVFirst);
948       const Standard_Real Rayon2 = Handle(Geom_Circle)::DownCast (C)->Radius();
949           const Standard_Real R = (Rayon1 > Rayon2)? Rayon1 : Rayon2;
950           return (R>Precision::Confusion()? (R3d / R) : 0.);
951     }
952         case GeomAbs_Plane:
953     {
954       return R3d;
955     }
956         case GeomAbs_BezierSurface:
957     {
958       Standard_Real Ures,Vres;
959       Handle(Geom_BezierSurface)::DownCast (mySurface)->Resolution(R3d,Ures,Vres);
960       return Ures;
961     }
962         case GeomAbs_BSplineSurface:
963     {
964       Standard_Real Ures,Vres;
965       Handle(Geom_BSplineSurface)::DownCast (mySurface)->Resolution(R3d,Ures,Vres);
966       return Ures;
967     }
968         case GeomAbs_OffsetSurface:
969     {
970       Handle(Geom_Surface) base = Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface();
971       GeomAdaptor_Surface gabase(base,myUFirst,myULast,myVFirst,myVLast);
972       return gabase.UResolution(R3d);
973     }
974         default: return Precision::Parametric(R3d);
975   }
976
977   if ( Res <= 1.)  
978     return 2.*ASin(Res);
979   
980   return 2.*M_PI;
981 }
982
983 //=======================================================================
984 //function : VResolution
985 //purpose  : 
986 //=======================================================================
987
988 Standard_Real GeomAdaptor_Surface::VResolution(const Standard_Real R3d) const
989 {
990   Standard_Real Res = 0.;
991
992   switch (mySurfaceType)
993   {
994     case GeomAbs_SurfaceOfRevolution:
995     {
996       GeomAdaptor_Curve myBasisCurve
997         (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
998       return myBasisCurve.Resolution(R3d);
999     }
1000         case GeomAbs_Torus:
1001     {
1002       Handle(Geom_ToroidalSurface)& S = Handle(Geom_ToroidalSurface)::DownCast (mySurface);
1003       const Standard_Real R = S->MinorRadius();
1004       if(R>Precision::Confusion())
1005         Res = R3d/(2.*R);
1006       break;
1007     }
1008         case GeomAbs_Sphere:
1009     {
1010       Handle(Geom_SphericalSurface)& S = Handle(Geom_SphericalSurface)::DownCast (mySurface);
1011       const Standard_Real R = S->Radius();
1012       if(R>Precision::Confusion())
1013         Res = R3d/(2.*R);
1014       break;
1015     }
1016         case GeomAbs_SurfaceOfExtrusion:
1017         case GeomAbs_Cylinder:
1018         case GeomAbs_Cone:
1019         case GeomAbs_Plane:
1020     {
1021       return R3d;
1022     }
1023         case GeomAbs_BezierSurface:
1024     {
1025       Standard_Real Ures,Vres;
1026       Handle(Geom_BezierSurface)::DownCast (mySurface)->Resolution(R3d,Ures,Vres);
1027       return Vres;
1028     }
1029         case GeomAbs_BSplineSurface:
1030     {
1031       Standard_Real Ures,Vres;
1032       Handle(Geom_BSplineSurface)::DownCast (mySurface)->Resolution(R3d,Ures,Vres);
1033       return Vres;
1034     }
1035         case GeomAbs_OffsetSurface:
1036     {
1037       Handle(Geom_Surface) base = Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface();
1038       GeomAdaptor_Surface gabase(base,myUFirst,myULast,myVFirst,myVLast);
1039       return gabase.VResolution(R3d);
1040     }
1041         default: return Precision::Parametric(R3d);
1042   }
1043
1044   if ( Res <= 1.) 
1045     return 2.*ASin(Res);
1046
1047   return 2.*M_PI;
1048 }
1049
1050 //=======================================================================
1051 //function : Plane
1052 //purpose  : 
1053 //=======================================================================
1054
1055 gp_Pln GeomAdaptor_Surface::Plane() const 
1056 {
1057   if (mySurfaceType != GeomAbs_Plane)
1058     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Plane");
1059   return Handle(Geom_Plane)::DownCast (mySurface)->Pln();
1060 }
1061
1062 //=======================================================================
1063 //function : Cylinder
1064 //purpose  : 
1065 //=======================================================================
1066
1067 gp_Cylinder GeomAdaptor_Surface::Cylinder() const 
1068 {
1069   if (mySurfaceType != GeomAbs_Cylinder)
1070     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Cylinder");
1071   return Handle(Geom_CylindricalSurface)::DownCast (mySurface)->Cylinder();
1072 }
1073
1074 //=======================================================================
1075 //function : Cone
1076 //purpose  : 
1077 //=======================================================================
1078
1079 gp_Cone GeomAdaptor_Surface::Cone() const 
1080 {
1081   if (mySurfaceType != GeomAbs_Cone)
1082     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Cone");
1083   return Handle(Geom_ConicalSurface)::DownCast (mySurface)->Cone();
1084 }
1085
1086 //=======================================================================
1087 //function : Sphere
1088 //purpose  : 
1089 //=======================================================================
1090
1091 gp_Sphere GeomAdaptor_Surface::Sphere() const 
1092 {
1093   if (mySurfaceType != GeomAbs_Sphere)
1094     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Sphere");
1095   return Handle(Geom_SphericalSurface)::DownCast (mySurface)->Sphere();
1096 }
1097
1098 //=======================================================================
1099 //function : Torus
1100 //purpose  : 
1101 //=======================================================================
1102
1103 gp_Torus GeomAdaptor_Surface::Torus() const 
1104 {
1105   if (mySurfaceType != GeomAbs_Torus)
1106     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Torus");
1107   return Handle(Geom_ToroidalSurface)::DownCast (mySurface)->Torus(); 
1108 }
1109
1110 //=======================================================================
1111 //function : UDegree
1112 //purpose  : 
1113 //=======================================================================
1114
1115 Standard_Integer GeomAdaptor_Surface::UDegree() const
1116 {
1117   if (mySurfaceType == GeomAbs_BSplineSurface)
1118     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->UDegree(); 
1119   if ( mySurfaceType == GeomAbs_BezierSurface)
1120     return Handle(Geom_BezierSurface)::DownCast (mySurface)->UDegree(); 
1121   if ( mySurfaceType == GeomAbs_SurfaceOfExtrusion)
1122   {
1123     GeomAdaptor_Curve myBasisCurve
1124       (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
1125     return myBasisCurve.Degree();
1126   }
1127   Standard_NoSuchObject::Raise("GeomAdaptor_Surface::UDegree");
1128   return 0;
1129 }
1130
1131 //=======================================================================
1132 //function : NbUPoles
1133 //purpose  : 
1134 //=======================================================================
1135
1136 Standard_Integer GeomAdaptor_Surface::NbUPoles() const
1137 {
1138   if (mySurfaceType == GeomAbs_BSplineSurface)
1139     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->NbUPoles();
1140   if ( mySurfaceType == GeomAbs_BezierSurface)
1141     return Handle(Geom_BezierSurface)::DownCast (mySurface)->NbUPoles(); 
1142   if ( mySurfaceType == GeomAbs_SurfaceOfExtrusion)
1143   {
1144     GeomAdaptor_Curve myBasisCurve
1145       (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
1146     return myBasisCurve.NbPoles();
1147   }
1148   Standard_NoSuchObject::Raise("GeomAdaptor_Surface::NbUPoles");
1149   return 0;
1150 }
1151
1152 //=======================================================================
1153 //function : VDegree
1154 //purpose  : 
1155 //=======================================================================
1156
1157 Standard_Integer GeomAdaptor_Surface::VDegree() const
1158 {
1159   if (mySurfaceType == GeomAbs_BSplineSurface)
1160     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->VDegree(); 
1161   if ( mySurfaceType == GeomAbs_BezierSurface)
1162     return Handle(Geom_BezierSurface)::DownCast (mySurface)->VDegree(); 
1163   if ( mySurfaceType == GeomAbs_SurfaceOfRevolution)
1164   {
1165     GeomAdaptor_Curve myBasisCurve
1166       (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
1167     return myBasisCurve.Degree();
1168   }
1169   Standard_NoSuchObject::Raise("GeomAdaptor_Surface::VDegree");
1170   return 0;
1171 }
1172
1173 //=======================================================================
1174 //function : NbVPoles
1175 //purpose  : 
1176 //=======================================================================
1177
1178 Standard_Integer GeomAdaptor_Surface::NbVPoles() const
1179 {
1180   if (mySurfaceType == GeomAbs_BSplineSurface)
1181     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->NbVPoles(); 
1182   if ( mySurfaceType == GeomAbs_BezierSurface)
1183     return Handle(Geom_BezierSurface)::DownCast (mySurface)->NbVPoles(); 
1184   if ( mySurfaceType == GeomAbs_SurfaceOfRevolution)
1185   {
1186     GeomAdaptor_Curve myBasisCurve
1187       (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
1188     return myBasisCurve.NbPoles();
1189   }
1190   Standard_NoSuchObject::Raise("GeomAdaptor_Surface::NbVPoles");
1191   return 0;
1192 }
1193
1194 //=======================================================================
1195 //function : NbUKnots
1196 //purpose  : 
1197 //=======================================================================
1198
1199 Standard_Integer GeomAdaptor_Surface::NbUKnots() const
1200 {
1201   if (mySurfaceType == GeomAbs_BSplineSurface)
1202     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->NbUKnots(); 
1203   if ( mySurfaceType == GeomAbs_SurfaceOfExtrusion)
1204   {
1205     GeomAdaptor_Curve myBasisCurve
1206       (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast);
1207     return myBasisCurve.NbKnots();
1208   }
1209   Standard_NoSuchObject::Raise("GeomAdaptor_Surface::NbUKnots");
1210   return 0;
1211 }
1212
1213 //=======================================================================
1214 //function : NbVKnots
1215 //purpose  : 
1216 //=======================================================================
1217
1218 Standard_Integer GeomAdaptor_Surface::NbVKnots() const 
1219 {
1220   if (mySurfaceType == GeomAbs_BSplineSurface)
1221     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->NbVKnots(); 
1222   Standard_NoSuchObject::Raise("GeomAdaptor_Surface::NbVKnots");
1223   return 0;
1224 }
1225 //=======================================================================
1226 //function : IsURational
1227 //purpose  : 
1228 //=======================================================================
1229
1230 Standard_Boolean GeomAdaptor_Surface::IsURational() const
1231 {
1232   if (mySurfaceType == GeomAbs_BSplineSurface)
1233     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->IsURational(); 
1234   if (mySurfaceType == GeomAbs_BezierSurface)
1235     return Handle(Geom_BezierSurface)::DownCast (mySurface)->IsURational(); 
1236   return Standard_False;
1237 }
1238
1239 //=======================================================================
1240 //function : IsVRational
1241 //purpose  : 
1242 //=======================================================================
1243
1244 Standard_Boolean GeomAdaptor_Surface::IsVRational() const
1245 {
1246   if (mySurfaceType == GeomAbs_BSplineSurface)
1247     return Handle(Geom_BSplineSurface)::DownCast (mySurface)->IsVRational(); 
1248   if (mySurfaceType == GeomAbs_BezierSurface)
1249     return Handle(Geom_BezierSurface)::DownCast (mySurface)->IsVRational(); 
1250   return Standard_False;
1251 }
1252
1253 //=======================================================================
1254 //function : Bezier
1255 //purpose  : 
1256 //=======================================================================
1257
1258 Handle(Geom_BezierSurface) GeomAdaptor_Surface::Bezier() const 
1259 {
1260   if (mySurfaceType != GeomAbs_BezierSurface)
1261     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Bezier");
1262   return Handle(Geom_BezierSurface)::DownCast (mySurface);
1263 }
1264
1265 //=======================================================================
1266 //function : BSpline
1267 //purpose  : 
1268 //=======================================================================
1269
1270 Handle(Geom_BSplineSurface) GeomAdaptor_Surface::BSpline() const 
1271 {
1272   if (mySurfaceType != GeomAbs_BSplineSurface)  
1273     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::BSpline");
1274   return Handle(Geom_BSplineSurface)::DownCast (mySurface);
1275 }
1276
1277 //=======================================================================
1278 //function : AxeOfRevolution
1279 //purpose  : 
1280 //=======================================================================
1281
1282 gp_Ax1 GeomAdaptor_Surface::AxeOfRevolution() const 
1283 {
1284   if (mySurfaceType != GeomAbs_SurfaceOfRevolution)
1285     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::AxeOfRevolution");
1286   return Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->Axis();
1287 }
1288
1289 //=======================================================================
1290 //function : Direction
1291 //purpose  : 
1292 //=======================================================================
1293
1294 gp_Dir GeomAdaptor_Surface::Direction() const 
1295 {
1296   if (mySurfaceType != GeomAbs_SurfaceOfExtrusion)
1297     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::Direction");
1298   return Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->Direction();
1299 }
1300
1301 //=======================================================================
1302 //function : BasisCurve
1303 //purpose  : 
1304 //=======================================================================
1305
1306 Handle(Adaptor3d_HCurve) GeomAdaptor_Surface::BasisCurve() const 
1307 {
1308   Handle(Geom_Curve) C;
1309   if (mySurfaceType == GeomAbs_SurfaceOfExtrusion)
1310     C = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve();
1311   else if (mySurfaceType == GeomAbs_SurfaceOfRevolution)
1312     C = Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve();
1313   else
1314     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::BasisCurve");
1315   return Handle(GeomAdaptor_HCurve)(new GeomAdaptor_HCurve(C));
1316 }
1317
1318 //=======================================================================
1319 //function : BasisSurface
1320 //purpose  : 
1321 //=======================================================================
1322
1323 Handle(Adaptor3d_HSurface) GeomAdaptor_Surface::BasisSurface() const 
1324 {
1325   if (mySurfaceType != GeomAbs_OffsetSurface) 
1326     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::BasisSurface");
1327   return new GeomAdaptor_HSurface
1328     (Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface(),
1329      myUFirst,myULast,myVFirst,myVLast);
1330 }
1331
1332 //=======================================================================
1333 //function : OffsetValue
1334 //purpose  : 
1335 //=======================================================================
1336
1337 Standard_Real GeomAdaptor_Surface::OffsetValue() const 
1338 {
1339   if (mySurfaceType != GeomAbs_OffsetSurface) 
1340     Standard_NoSuchObject::Raise("GeomAdaptor_Surface::BasisSurface");
1341   return Handle(Geom_OffsetSurface)::DownCast (mySurface)->Offset();
1342 }
1343
1344 //=======================================================================
1345 //function : IfUVBound <private>
1346 //purpose  :  locates U,V parameters if U,V =First, Last, 
1347 //            processes the finding span and returns the 
1348 //            parameters for LocalDi     
1349 //=======================================================================
1350
1351 Standard_Boolean GeomAdaptor_Surface::IfUVBound(const Standard_Real U,
1352                                                 const Standard_Real V,
1353                                                 Standard_Integer& IOutDeb,
1354                                                 Standard_Integer& IOutFin,
1355                                                 Standard_Integer& IOutVDeb,
1356                                                 Standard_Integer& IOutVFin,
1357                                                 const Standard_Integer USide,
1358                                                 const Standard_Integer VSide) const
1359 {
1360   Standard_Integer Ideb,Ifin;
1361   Standard_Integer anUFKIndx = myBspl->FirstUKnotIndex(), 
1362     anULKIndx = myBspl->LastUKnotIndex(), 
1363     aVFKIndx = myBspl->FirstVKnotIndex(), aVLKIndx = myBspl->LastVKnotIndex();
1364   myBspl->LocateU(U, PosTol, Ideb, Ifin, Standard_False);
1365   Standard_Boolean Local = (Ideb == Ifin);
1366   Span(USide,Ideb,Ifin,Ideb,Ifin,anUFKIndx,anULKIndx);
1367   Standard_Integer IVdeb,IVfin;
1368   myBspl->LocateV(V, PosTol, IVdeb, IVfin, Standard_False); 
1369   if(IVdeb == IVfin) Local = Standard_True;
1370   Span(VSide,IVdeb,IVfin,IVdeb,IVfin,aVFKIndx,aVLKIndx);
1371
1372   IOutDeb=Ideb;   IOutFin=Ifin; 
1373   IOutVDeb=IVdeb; IOutVFin=IVfin;
1374
1375   return Local;
1376 }     
1377 //=======================================================================
1378 //function : Span <private>
1379 //purpose  : locates U,V parameters if U=UFirst or U=ULast, 
1380 //           processes the finding span and returns the 
1381 //           parameters for LocalDi   
1382 //=======================================================================
1383
1384 void GeomAdaptor_Surface::Span(const Standard_Integer Side,
1385                                const Standard_Integer Ideb,
1386                                const Standard_Integer Ifin,
1387                                Standard_Integer& OutIdeb,
1388                                Standard_Integer& OutIfin,
1389                                const Standard_Integer theFKIndx,
1390                                const Standard_Integer theLKIndx) const
1391 {
1392   if(Ideb!=Ifin)//not a knot
1393   { 
1394     if(Ideb<theFKIndx)                 { OutIdeb=theFKIndx; OutIfin=theFKIndx+1; }
1395         else if(Ifin>theLKIndx)      { OutIdeb=theLKIndx-1; OutIfin=theLKIndx; }
1396         else if(Ideb>=(theLKIndx-1)) { OutIdeb=theLKIndx-1; OutIfin=theLKIndx; }
1397         else if(Ifin<=theFKIndx+1)           { OutIdeb=theFKIndx; OutIfin=theFKIndx+1; }
1398         else if(Ideb>Ifin)         { OutIdeb=Ifin-1;   OutIfin=Ifin; }
1399         else                       { OutIdeb=Ideb;   OutIfin=Ifin; }
1400   }
1401   else
1402   {
1403     if(Ideb<=theFKIndx){ OutIdeb=theFKIndx;   OutIfin=theFKIndx+1;}//first knot
1404     else if(Ifin>=theLKIndx) { OutIdeb=theLKIndx-1;OutIfin=theLKIndx;}//last knot
1405     else
1406     {
1407           if(Side==-1){OutIdeb=Ideb-1;   OutIfin=Ifin;}
1408           else {OutIdeb=Ideb;   OutIfin=Ifin+1;}
1409     } 
1410   }
1411 }