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