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