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