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