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