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