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