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