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