1 // Created on: 1995-07-24
2 // Created by: Modelistation
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503
19 #include <Adaptor3d_Surface.hxx>
20 #include <Adaptor3d_Surface.hxx>
21 #include <Bnd_Box.hxx>
23 #include <BndLib_AddSurface.hxx>
26 #include <Geom_BezierSurface.hxx>
27 #include <Geom_BSplineSurface.hxx>
28 #include <GeomAbs_SurfaceType.hxx>
31 #include <gp_Cone.hxx>
32 #include <Precision.hxx>
33 #include <TColgp_Array2OfPnt.hxx>
34 #include <TColStd_Array1OfInteger.hxx>
35 #include <TColStd_Array1OfReal.hxx>
36 #include <math_PSO.hxx>
37 #include <math_Powell.hxx>
39 static Standard_Integer NbUSamples(const Adaptor3d_Surface& S,
40 const Standard_Real Umin,
41 const Standard_Real Umax);
43 static Standard_Integer NbVSamples(const Adaptor3d_Surface& S,
44 const Standard_Real Vmin,
45 const Standard_Real Vmax);
47 static Standard_Real AdjustExtr(const Adaptor3d_Surface& S,
48 const Standard_Real UMin,
49 const Standard_Real UMax,
50 const Standard_Real VMin,
51 const Standard_Real VMax,
52 const Standard_Real Extr0,
53 const Standard_Integer CoordIndx,
54 const Standard_Real Tol,
55 const Standard_Boolean IsMin);
58 static void ComputePolesIndexes(const TColStd_Array1OfReal &theKnots,
59 const TColStd_Array1OfInteger &theMults,
60 const Standard_Integer theDegree,
61 const Standard_Real theMin,
62 const Standard_Real theMax,
63 const Standard_Integer theMaxPoleIdx,
64 const Standard_Boolean theIsPeriodic,
65 Standard_Integer &theOutMinIdx,
66 Standard_Integer &theOutMaxIdx);
68 //=======================================================================
71 //=======================================================================
72 void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
73 const Standard_Real Tol,
77 BndLib_AddSurface::Add(S,
81 S.LastVParameter (),Tol,B);
83 //=======================================================================
84 //function : NbUSamples
86 //=======================================================================
88 static Standard_Integer NbUSamples(const Adaptor3d_Surface& S)
91 GeomAbs_SurfaceType Type = S.GetType();
93 case GeomAbs_BezierSurface:
98 case GeomAbs_BSplineSurface:
100 const Handle(Geom_BSplineSurface)& BS = S.BSpline();
101 N = 2*(BS->UDegree() + 1)*(BS->NbUKnots() -1);
110 //=======================================================================
111 //function : NbVSamples
113 //=======================================================================
115 static Standard_Integer NbVSamples(const Adaptor3d_Surface& S)
118 GeomAbs_SurfaceType Type = S.GetType();
120 case GeomAbs_BezierSurface:
125 case GeomAbs_BSplineSurface:
127 const Handle(Geom_BSplineSurface)& BS = S.BSpline();
128 N = 2*(BS->VDegree() + 1)*(BS->NbVKnots() - 1) ;
137 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 Begin
138 static gp_Pnt BaryCenter(const gp_Pln &aPlane,
139 const Standard_Real aUMin,
140 const Standard_Real aUMax,
141 const Standard_Real aVMin,
142 const Standard_Real aVMax)
144 Standard_Real aU, aV;
145 Standard_Boolean isU1Inf = Precision::IsInfinite(aUMin);
146 Standard_Boolean isU2Inf = Precision::IsInfinite(aUMax);
147 Standard_Boolean isV1Inf = Precision::IsInfinite(aVMin);
148 Standard_Boolean isV2Inf = Precision::IsInfinite(aVMax);
150 if (isU1Inf && isU2Inf)
157 aU = (aUMin + aUMax)/2.;
159 if (isV1Inf && isV2Inf)
166 aV = (aVMin + aVMax)/2.;
168 gp_Pnt aCenter = ElSLib::Value(aU, aV, aPlane);
173 static void TreatInfinitePlane(const gp_Pln &aPlane,
174 const Standard_Real aUMin,
175 const Standard_Real aUMax,
176 const Standard_Real aVMin,
177 const Standard_Real aVMax,
178 const Standard_Real aTol,
181 // Get 3 coordinate axes of the plane.
182 const gp_Dir &aNorm = aPlane.Axis().Direction();
183 const Standard_Real anAngularTol = RealEpsilon();
185 // Get location of the plane as its barycenter
186 gp_Pnt aLocation = BaryCenter(aPlane, aUMin, aUMax, aVMin, aVMax);
188 if (aNorm.IsParallel(gp::DX(), anAngularTol)) {
194 } else if (aNorm.IsParallel(gp::DY(), anAngularTol)) {
200 } else if (aNorm.IsParallel(gp::DZ(), anAngularTol)) {
214 // Compute start and finish indexes used in convex hull.
215 // theMinIdx - minimum poles index, that can be used.
216 // theMaxIdx - maximum poles index, that can be used.
217 // theShiftCoeff - shift between flatknots array and poles array.
218 // This vaule should be equal to 1 in case of non periodic BSpline,
219 // and (degree + 1) - mults(the lowest index).
221 void ComputePolesIndexes(const TColStd_Array1OfReal &theKnots,
222 const TColStd_Array1OfInteger &theMults,
223 const Standard_Integer theDegree,
224 const Standard_Real theMin,
225 const Standard_Real theMax,
226 const Standard_Integer theMaxPoleIdx,
227 const Standard_Boolean theIsPeriodic,
228 Standard_Integer &theOutMinIdx,
229 Standard_Integer &theOutMaxIdx)
231 BSplCLib::Hunt(theKnots, theMin, theOutMinIdx);
232 theOutMinIdx = Max(theOutMinIdx, theKnots.Lower());
234 BSplCLib::Hunt(theKnots, theMax, theOutMaxIdx);
236 theOutMaxIdx = Min(theOutMaxIdx, theKnots.Upper());
237 Standard_Integer mult = theMults(theOutMaxIdx);
239 theOutMinIdx = BSplCLib::PoleIndex(theDegree, theOutMinIdx, theIsPeriodic, theMults) + 1;
240 theOutMinIdx = Max(theOutMinIdx, 1);
241 theOutMaxIdx = BSplCLib::PoleIndex(theDegree, theOutMaxIdx, theIsPeriodic, theMults) + 1;
242 theOutMaxIdx += theDegree - mult;
244 theOutMaxIdx = Min(theOutMaxIdx, theMaxPoleIdx);
247 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End
248 //=======================================================================
251 //=======================================================================
252 void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
253 const Standard_Real UMin,
254 const Standard_Real UMax,
255 const Standard_Real VMin,
256 const Standard_Real VMax,
257 const Standard_Real Tol,
260 GeomAbs_SurfaceType Type = S.GetType(); // skv OCC6503
262 if (Precision::IsInfinite(VMin) ||
263 Precision::IsInfinite(VMax) ||
264 Precision::IsInfinite(UMin) ||
265 Precision::IsInfinite(UMax) ) {
266 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 Begin
272 TreatInfinitePlane(S.Plane(), UMin, UMax, VMin, VMax, Tol, B);
281 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End
284 // GeomAbs_SurfaceType Type = S.GetType(); // skv OCC6503
290 gp_Pln Plan = S.Plane();
291 B.Add(ElSLib::Value(UMin,VMin,Plan));
292 B.Add(ElSLib::Value(UMin,VMax,Plan));
293 B.Add(ElSLib::Value(UMax,VMin,Plan));
294 B.Add(ElSLib::Value(UMax,VMax,Plan));
298 case GeomAbs_Cylinder:
300 BndLib::Add(S.Cylinder(),UMin,UMax,VMin,VMax,Tol,B);
305 BndLib::Add(S.Cone(),UMin,UMax,VMin,VMax,Tol,B);
310 BndLib::Add(S.Torus(),UMin,UMax,VMin,VMax,Tol,B);
315 if (Abs(UMin) < Precision::Angular() &&
316 Abs(UMax - 2.*M_PI) < Precision::Angular() &&
317 Abs(VMin + M_PI/2.) < Precision::Angular() &&
318 Abs(VMax - M_PI/2.) < Precision::Angular()) // a whole sphere
319 BndLib::Add(S.Sphere(),Tol,B);
321 BndLib::Add(S.Sphere(),UMin,UMax,VMin,VMax,Tol,B);
324 case GeomAbs_OffsetSurface:
326 Handle(Adaptor3d_Surface) HS = S.BasisSurface();
327 Add (*HS,UMin,UMax,VMin,VMax,Tol,B);
328 B.Enlarge(S.OffsetValue());
332 case GeomAbs_BezierSurface:
333 case GeomAbs_BSplineSurface:
335 Standard_Boolean isUseConvexHullAlgorithm = Standard_True;
336 Standard_Real PTol = Precision::Parametric(Precision::Confusion());
337 // Borders of underlying geometry.
338 Standard_Real anUMinParam = UMin, anUMaxParam = UMax,// BSpline case.
339 aVMinParam = VMin, aVMaxParam = VMax;
340 Handle(Geom_BSplineSurface) aBS;
341 if (Type == GeomAbs_BezierSurface)
344 // All of poles used for any parameter,
345 // that's why in case of trimmed parameters handled by grid algorithm.
347 if (Abs(UMin-S.FirstUParameter()) > PTol ||
348 Abs(VMin-S.FirstVParameter()) > PTol ||
349 Abs(UMax-S.LastUParameter ()) > PTol ||
350 Abs(VMax-S.LastVParameter ()) > PTol )
352 // Borders not equal to topology borders.
353 isUseConvexHullAlgorithm = Standard_False;
359 // If Umin, Vmin, Umax, Vmax lies inside geometry bounds then:
360 // use convex hull algorithm,
361 // if Umin, VMin, Umax, Vmax lies outside then:
362 // use grid algorithm on analytic continuation (default case).
364 aBS->Bounds(anUMinParam, anUMaxParam, aVMinParam, aVMaxParam);
365 if ( (UMin - anUMinParam) < -PTol ||
366 (VMin - aVMinParam) < -PTol ||
367 (UMax - anUMaxParam) > PTol ||
368 (VMax - aVMaxParam) > PTol )
370 // Out of geometry borders.
371 isUseConvexHullAlgorithm = Standard_False;
375 if (isUseConvexHullAlgorithm)
377 Standard_Integer aNbUPoles = S.NbUPoles(), aNbVPoles = S.NbVPoles();
378 TColgp_Array2OfPnt Tp(1, aNbUPoles, 1, aNbVPoles);
379 Standard_Integer UMinIdx = 0, UMaxIdx = 0;
380 Standard_Integer VMinIdx = 0, VMaxIdx = 0;
381 Standard_Boolean isUPeriodic = S.IsUPeriodic(), isVPeriodic = S.IsVPeriodic();
382 if (Type == GeomAbs_BezierSurface)
384 S.Bezier()->Poles(Tp);
385 UMinIdx = 1; UMaxIdx = aNbUPoles;
386 VMinIdx = 1; VMaxIdx = aNbVPoles;
397 if (UMin > anUMinParam ||
400 TColStd_Array1OfInteger aMults(1, aBS->NbUKnots());
401 TColStd_Array1OfReal aKnots(1, aBS->NbUKnots());
403 aBS->UMultiplicities(aMults);
405 ComputePolesIndexes(aKnots,
411 UMinIdx, UMaxIdx); // the Output indexes
415 if (VMin > aVMinParam ||
418 TColStd_Array1OfInteger aMults(1, aBS->NbVKnots());
419 TColStd_Array1OfReal aKnots(1, aBS->NbVKnots());
421 aBS->VMultiplicities(aMults);
423 ComputePolesIndexes(aKnots,
429 VMinIdx, VMaxIdx); // the Output indexes
434 // Use poles to build convex hull.
435 Standard_Integer ip, jp;
436 for (Standard_Integer i = UMinIdx; i <= UMaxIdx; i++)
439 if (isUPeriodic && ip > aNbUPoles)
443 for (Standard_Integer j = VMinIdx; j <= VMaxIdx; j++)
446 if (isVPeriodic && jp > aNbVPoles)
461 Standard_Integer Nu = NbUSamples(S);
462 Standard_Integer Nv = NbVSamples(S);
464 for (Standard_Integer i =1 ;i<=Nu;i++){
465 Standard_Real U = UMin + ((UMax-UMin)*(i-1)/(Nu-1));
466 for (Standard_Integer j=1 ;j<=Nv;j++){
467 Standard_Real V = VMin + ((VMax-VMin)*(j-1)/(Nv-1));
476 //----- Methods for AddOptimal ---------------------------------------
478 //=======================================================================
479 //function : AddOptimal
481 //=======================================================================
482 void BndLib_AddSurface::AddOptimal(const Adaptor3d_Surface& S,
483 const Standard_Real Tol,
487 BndLib_AddSurface::AddOptimal(S,
491 S.LastVParameter (),Tol,B);
493 //=======================================================================
494 //function : AddOptimal
496 //=======================================================================
498 void BndLib_AddSurface::AddOptimal(const Adaptor3d_Surface& S,
499 const Standard_Real UMin,
500 const Standard_Real UMax,
501 const Standard_Real VMin,
502 const Standard_Real VMax,
503 const Standard_Real Tol,
506 GeomAbs_SurfaceType Type = S.GetType();
508 if (Precision::IsInfinite(VMin) ||
509 Precision::IsInfinite(VMax) ||
510 Precision::IsInfinite(UMin) ||
511 Precision::IsInfinite(UMax) ) {
515 TreatInfinitePlane(S.Plane(), UMin, UMax, VMin, VMax, Tol, B);
530 gp_Pln Plan = S.Plane();
531 B.Add(ElSLib::Value(UMin,VMin,Plan));
532 B.Add(ElSLib::Value(UMin,VMax,Plan));
533 B.Add(ElSLib::Value(UMax,VMin,Plan));
534 B.Add(ElSLib::Value(UMax,VMax,Plan));
538 case GeomAbs_Cylinder:
540 BndLib::Add(S.Cylinder(), UMin, UMax, VMin, VMax, Tol, B);
545 BndLib::Add(S.Cone(), UMin, UMax, VMin, VMax, Tol, B);
550 BndLib::Add(S.Sphere(), UMin, UMax, VMin, VMax, Tol, B);
555 AddGenSurf(S, UMin, UMax, VMin, VMax, Tol, B);
559 //=======================================================================
560 //function : AddGenSurf
562 //=======================================================================
563 void BndLib_AddSurface::AddGenSurf(const Adaptor3d_Surface& S,
564 const Standard_Real UMin,
565 const Standard_Real UMax,
566 const Standard_Real VMin,
567 const Standard_Real VMax,
568 const Standard_Real Tol,
571 Standard_Integer Nu = NbUSamples(S, UMin, UMax);
572 Standard_Integer Nv = NbVSamples(S, VMin, VMax);
574 Standard_Real CoordMin[3] = {RealLast(), RealLast(), RealLast()};
575 Standard_Real CoordMax[3] = {-RealLast(), -RealLast(), -RealLast()};
576 Standard_Real DeflMax[3] = {-RealLast(), -RealLast(), -RealLast()};
579 Standard_Real du = (UMax-UMin)/(Nu-1), du2 = du / 2.;
580 Standard_Real dv = (VMax-VMin)/(Nv-1), dv2 = dv / 2.;
581 NCollection_Array2<gp_XYZ> aPnts(1, Nu, 1, Nv);
583 Standard_Integer i, j, k;
585 for (i = 1, u = UMin; i <= Nu; i++, u += du){
586 for (j = 1, v = VMin;j <= Nv; j++, v += dv){
588 aPnts(i, j) = P.XYZ();
590 for(k = 0; k < 3; ++k)
592 if(CoordMin[k] > P.Coord(k+1))
594 CoordMin[k] = P.Coord(k+1);
596 if(CoordMax[k] < P.Coord(k+1))
598 CoordMax[k] = P.Coord(k+1);
604 gp_XYZ aPm = 0.5 * (aPnts(i-1,j) + aPnts(i, j));
606 gp_XYZ aD = (P.XYZ() - aPm);
607 for(k = 0; k < 3; ++k)
609 if(CoordMin[k] > P.Coord(k+1))
611 CoordMin[k] = P.Coord(k+1);
613 if(CoordMax[k] < P.Coord(k+1))
615 CoordMax[k] = P.Coord(k+1);
617 Standard_Real d = Abs(aD.Coord(k+1));
626 gp_XYZ aPm = 0.5 * (aPnts(i,j-1) + aPnts(i, j));
627 S.D0(u , v - dv2, P);
628 gp_XYZ aD = (P.XYZ() - aPm);
629 for(k = 0; k < 3; ++k)
631 if(CoordMin[k] > P.Coord(k+1))
633 CoordMin[k] = P.Coord(k+1);
635 if(CoordMax[k] < P.Coord(k+1))
637 CoordMax[k] = P.Coord(k+1);
639 Standard_Real d = Abs(aD.Coord(k+1));
650 Standard_Real eps = Max(Tol, Precision::Confusion());
651 for(k = 0; k < 3; ++k)
653 Standard_Real d = DeflMax[k];
659 Standard_Real CMin = CoordMin[k];
660 Standard_Real CMax = CoordMax[k];
661 for(i = 1; i <= Nu; ++i)
663 for(j = 1; j <= Nv; ++j)
665 if(aPnts(i,j).Coord(k+1) - CMin < d)
667 Standard_Real umin, umax, vmin, vmax;
668 umin = UMin + Max(0, i-2) * du;
669 umax = UMin + Min(Nu-1, i) * du;
670 vmin = VMin + Max(0, j-2) * dv;
671 vmax = VMin + Min(Nv-1, j) * dv;
672 Standard_Real cmin = AdjustExtr(S, umin, umax, vmin, vmax,
673 CMin, k + 1, eps, Standard_True);
679 else if(CMax - aPnts(i,j).Coord(k+1) < d)
681 Standard_Real umin, umax, vmin, vmax;
682 umin = UMin + Max(0, i-2) * du;
683 umax = UMin + Min(Nu-1, i) * du;
684 vmin = VMin + Max(0, j-2) * dv;
685 vmax = VMin + Min(Nv-1, j) * dv;
686 Standard_Real cmax = AdjustExtr(S, umin, umax, vmin, vmax,
687 CMax, k + 1, eps, Standard_False);
700 B.Add(gp_Pnt(CoordMin[0], CoordMin[1], CoordMin[2]));
701 B.Add(gp_Pnt(CoordMax[0], CoordMax[1], CoordMax[2]));
707 class SurfMaxMinCoord : public math_MultipleVarFunction
710 SurfMaxMinCoord(const Adaptor3d_Surface& theSurf,
711 const Standard_Real UMin,
712 const Standard_Real UMax,
713 const Standard_Real VMin,
714 const Standard_Real VMax,
715 const Standard_Integer CoordIndx,
716 const Standard_Real Sign)
722 myCoordIndx(CoordIndx),
728 X(2) = (VMin + VMax) / 2.;
729 Standard_Real F1, F2;
733 Standard_Real DU = Abs((F2 - F1) / (UMax - UMin));
734 X(1) = (UMin + UMax) / 2.;
739 Standard_Real DV = Abs((F2 - F1) / (VMax - VMin));
740 myPenalty = 10. * Max(DU, DV);
741 myPenalty = Max(myPenalty, 1.);
744 Standard_Boolean Value (const math_Vector& X,
747 if (CheckInputData(X))
749 gp_Pnt aP = mySurf.Value(X(1), X(2));
750 F = mySign * aP.Coord(myCoordIndx);
754 Standard_Real UPen = 0., VPen = 0., u0, v0;
757 UPen = myPenalty * (myUMin - X(1));
760 else if(X(1) > myUMax)
762 UPen = myPenalty * (X(1) - myUMax);
772 VPen = myPenalty * (myVMin - X(2));
775 else if(X(2) > myVMax)
777 VPen = myPenalty * (X(2) - myVMax);
785 gp_Pnt aP = mySurf.Value(u0, v0);
786 F = mySign * aP.Coord(myCoordIndx) + UPen + VPen;
789 return Standard_True;
794 Standard_Integer NbVariables() const
800 SurfMaxMinCoord & operator = (const SurfMaxMinCoord & theOther);
802 Standard_Boolean CheckInputData(const math_Vector& theParams)
804 if (theParams(1) < myUMin ||
805 theParams(1) > myUMax ||
806 theParams(2) < myVMin ||
807 theParams(2) > myVMax)
808 return Standard_False;
809 return Standard_True;
812 const Adaptor3d_Surface& mySurf;
813 Standard_Real myUMin;
814 Standard_Real myUMax;
815 Standard_Real myVMin;
816 Standard_Real myVMax;
817 Standard_Integer myCoordIndx;
818 Standard_Real mySign;
819 Standard_Real myPenalty;
822 //=======================================================================
823 //function : AdjustExtr
825 //=======================================================================
827 Standard_Real AdjustExtr(const Adaptor3d_Surface& S,
828 const Standard_Real UMin,
829 const Standard_Real UMax,
830 const Standard_Real VMin,
831 const Standard_Real VMax,
832 const Standard_Real Extr0,
833 const Standard_Integer CoordIndx,
834 const Standard_Real Tol,
835 const Standard_Boolean IsMin)
837 Standard_Real aSign = IsMin ? 1.:-1.;
838 Standard_Real extr = aSign * Extr0;
839 Standard_Real relTol = 2.*Tol;
844 Standard_Real Du = (S.LastUParameter() - S.FirstUParameter());
845 Standard_Real Dv = (S.LastVParameter() - S.FirstVParameter());
848 math_Vector aLowBorder(1,2);
849 math_Vector aUppBorder(1,2);
850 math_Vector aSteps(1,2);
851 aLowBorder(1) = UMin;
852 aUppBorder(1) = UMax;
853 aLowBorder(2) = VMin;
854 aUppBorder(2) = VMax;
856 Standard_Integer aNbU = Max(8, RealToInt(32 * (UMax - UMin) / Du));
857 Standard_Integer aNbV = Max(8, RealToInt(32 * (VMax - VMin) / Dv));
858 Standard_Integer aNbParticles = aNbU * aNbV;
859 Standard_Real aMaxUStep = (UMax - UMin) / (aNbU + 1);
860 aSteps(1) = Min(0.1 * Du, aMaxUStep);
861 Standard_Real aMaxVStep = (VMax - VMin) / (aNbV + 1);
862 aSteps(2) = Min(0.1 * Dv, aMaxVStep);
864 SurfMaxMinCoord aFunc(S, UMin, UMax, VMin, VMax, CoordIndx, aSign);
865 math_PSO aFinder(&aFunc, aLowBorder, aUppBorder, aSteps, aNbParticles);
866 aFinder.Perform(aSteps, extr, aT);
868 //Refinement of extremal value
869 math_Matrix aDir(1, 2, 1, 2, 0.0);
875 Standard_Integer aNbIter = 200;
876 math_Powell powell(aFunc, relTol, aNbIter, Tol);
877 powell.Perform(aFunc, aT, aDir);
882 extr = powell.Minimum();
888 //=======================================================================
889 //function : NbUSamples
891 //=======================================================================
893 Standard_Integer NbUSamples(const Adaptor3d_Surface& S,
894 const Standard_Real Umin,
895 const Standard_Real Umax)
898 GeomAbs_SurfaceType Type = S.GetType();
900 case GeomAbs_BezierSurface:
903 //By default parametric range of Bezier surf is [0, 1] [0, 1]
904 Standard_Real du = Umax - Umin;
907 N = RealToInt(du*N) + 1;
912 case GeomAbs_BSplineSurface:
914 const Handle(Geom_BSplineSurface)& BS = S.BSpline();
915 N = 2*(BS->UDegree() + 1)*(BS->NbUKnots() -1);
916 Standard_Real umin, umax, vmin, vmax;
917 BS->Bounds(umin, umax, vmin, vmax);
918 Standard_Real du = (Umax - Umin) / (umax - umin);
921 N = RealToInt(du*N) + 1;
932 //=======================================================================
933 //function : NbVSamples
935 //=======================================================================
937 Standard_Integer NbVSamples(const Adaptor3d_Surface& S,
938 const Standard_Real Vmin,
939 const Standard_Real Vmax)
942 GeomAbs_SurfaceType Type = S.GetType();
944 case GeomAbs_BezierSurface:
947 //By default parametric range of Bezier surf is [0, 1] [0, 1]
948 Standard_Real dv = Vmax - Vmin;
951 N = RealToInt(dv*N) + 1;
956 case GeomAbs_BSplineSurface:
958 const Handle(Geom_BSplineSurface)& BS = S.BSpline();
959 N = 2*(BS->VDegree() + 1)*(BS->NbVKnots() - 1) ;
960 Standard_Real umin, umax, vmin, vmax;
961 BS->Bounds(umin, umax, vmin, vmax);
962 Standard_Real dv = (Vmax - Vmin) / (vmax - vmin);
965 N = RealToInt(dv*N) + 1;