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