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