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