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