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_HSurface.hxx>
20 #include <Adaptor3d_Surface.hxx>
21 #include <Bnd_Box.hxx>
23 #include <BndLib_AddSurface.hxx>
24 #include <BSplCLib.hxx>
26 #include <Geom_BezierSurface.hxx>
27 #include <Geom_BSplineSurface.hxx>
28 #include <GeomAbs_SurfaceType.hxx>
31 #include <Precision.hxx>
32 #include <TColgp_Array2OfPnt.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TColStd_Array1OfReal.hxx>
36 //=======================================================================
39 //=======================================================================
40 void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
41 const Standard_Real Tol,
45 BndLib_AddSurface::Add(S,
49 S.LastVParameter (),Tol,B);
51 //=======================================================================
52 //function : NbUSamples
54 //=======================================================================
56 static Standard_Integer NbUSamples(const Adaptor3d_Surface& S)
59 GeomAbs_SurfaceType Type = S.GetType();
61 case GeomAbs_BezierSurface:
66 case GeomAbs_BSplineSurface:
68 const Handle(Geom_BSplineSurface)& BS = S.BSpline();
69 N = 2*(BS->UDegree() + 1)*(BS->NbUKnots() -1);
78 //=======================================================================
79 //function : NbVSamples
81 //=======================================================================
83 static Standard_Integer NbVSamples(const Adaptor3d_Surface& S)
86 GeomAbs_SurfaceType Type = S.GetType();
88 case GeomAbs_BezierSurface:
93 case GeomAbs_BSplineSurface:
95 const Handle(Geom_BSplineSurface)& BS = S.BSpline();
96 N = 2*(BS->VDegree() + 1)*(BS->NbVKnots() - 1) ;
105 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 Begin
106 static gp_Pnt BaryCenter(const gp_Pln &aPlane,
107 const Standard_Real aUMin,
108 const Standard_Real aUMax,
109 const Standard_Real aVMin,
110 const Standard_Real aVMax)
112 Standard_Real aU, aV;
113 Standard_Boolean isU1Inf = Precision::IsInfinite(aUMin);
114 Standard_Boolean isU2Inf = Precision::IsInfinite(aUMax);
115 Standard_Boolean isV1Inf = Precision::IsInfinite(aVMin);
116 Standard_Boolean isV2Inf = Precision::IsInfinite(aVMax);
118 if (isU1Inf && isU2Inf)
125 aU = (aUMin + aUMax)/2.;
127 if (isV1Inf && isV2Inf)
134 aV = (aVMin + aVMax)/2.;
136 gp_Pnt aCenter = ElSLib::Value(aU, aV, aPlane);
141 static void TreatInfinitePlane(const gp_Pln &aPlane,
142 const Standard_Real aUMin,
143 const Standard_Real aUMax,
144 const Standard_Real aVMin,
145 const Standard_Real aVMax,
146 const Standard_Real aTol,
149 // Get 3 coordinate axes of the plane.
150 const gp_Dir &aNorm = aPlane.Axis().Direction();
151 const Standard_Real anAngularTol = RealEpsilon();
153 // Get location of the plane as its barycenter
154 gp_Pnt aLocation = BaryCenter(aPlane, aUMin, aUMax, aVMin, aVMax);
156 if (aNorm.IsParallel(gp::DX(), anAngularTol)) {
162 } else if (aNorm.IsParallel(gp::DY(), anAngularTol)) {
168 } else if (aNorm.IsParallel(gp::DZ(), anAngularTol)) {
182 // Compute start and finish indexes used in convex hull.
183 // theMinIdx - minimum poles index, that can be used.
184 // theMaxIdx - maximum poles index, that can be used.
185 // theShiftCoeff - shift between flatknots array and poles array.
186 // This vaule should be equal to 1 in case of non periodic BSpline,
187 // and (degree + 1) - mults(the lowest index).
188 void ComputePolesIndexes(const TColStd_Array1OfReal &theFlatKnots,
189 const Standard_Integer theDegree,
190 const Standard_Real theMin,
191 const Standard_Real theMax,
192 const Standard_Integer theMinIdx,
193 const Standard_Integer theMaxIdx,
194 const Standard_Integer theShiftCoeff,
195 Standard_Integer &theOutMinIdx,
196 Standard_Integer &theOutMaxIdx)
198 // Compute first and last used flat knots.
199 for(Standard_Integer aKnotIdx = theFlatKnots.Lower();
200 aKnotIdx < theFlatKnots.Upper();
203 if (theFlatKnots(aKnotIdx) <= theMin)
204 theOutMinIdx = aKnotIdx;
206 if (theFlatKnots(theFlatKnots.Upper() - aKnotIdx + theFlatKnots.Lower()) >= theMax)
207 theOutMaxIdx = theFlatKnots.Upper() - aKnotIdx + theFlatKnots.Lower();
210 theOutMinIdx = Max(theOutMinIdx - 2 * theDegree + 2 - theShiftCoeff, theMinIdx);
211 theOutMaxIdx = Min(theOutMaxIdx - 2 + theDegree + 1 - theShiftCoeff, theMaxIdx);
214 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End
215 //=======================================================================
218 //=======================================================================
219 void BndLib_AddSurface::Add(const Adaptor3d_Surface& S,
220 const Standard_Real UMin,
221 const Standard_Real UMax,
222 const Standard_Real VMin,
223 const Standard_Real VMax,
224 const Standard_Real Tol,
227 GeomAbs_SurfaceType Type = S.GetType(); // skv OCC6503
229 if (Precision::IsInfinite(VMin) ||
230 Precision::IsInfinite(VMax) ||
231 Precision::IsInfinite(UMin) ||
232 Precision::IsInfinite(UMax) ) {
233 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 Begin
239 TreatInfinitePlane(S.Plane(), UMin, UMax, VMin, VMax, Tol, B);
248 // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End
251 // GeomAbs_SurfaceType Type = S.GetType(); // skv OCC6503
257 gp_Pln Plan = S.Plane();
258 B.Add(ElSLib::Value(UMin,VMin,Plan));
259 B.Add(ElSLib::Value(UMin,VMax,Plan));
260 B.Add(ElSLib::Value(UMax,VMin,Plan));
261 B.Add(ElSLib::Value(UMax,VMax,Plan));
265 case GeomAbs_Cylinder:
267 BndLib::Add(S.Cylinder(),UMin,UMax,VMin,VMax,Tol,B);
272 BndLib::Add(S.Cone(),UMin,UMax,VMin,VMax,Tol,B);
277 BndLib::Add(S.Torus(),UMin,UMax,VMin,VMax,Tol,B);
282 if (Abs(UMin) < Precision::Angular() &&
283 Abs(UMax - 2.*M_PI) < Precision::Angular() &&
284 Abs(VMin + M_PI/2.) < Precision::Angular() &&
285 Abs(VMax - M_PI/2.) < Precision::Angular()) // a whole sphere
286 BndLib::Add(S.Sphere(),Tol,B);
288 BndLib::Add(S.Sphere(),UMin,UMax,VMin,VMax,Tol,B);
291 case GeomAbs_OffsetSurface:
293 Handle(Adaptor3d_HSurface) HS = S.BasisSurface();
294 Add (HS->Surface(),UMin,UMax,VMin,VMax,Tol,B);
295 B.Enlarge(S.OffsetValue());
299 case GeomAbs_BezierSurface:
300 case GeomAbs_BSplineSurface:
302 Standard_Boolean isUseConvexHullAlgorithm = Standard_True;
303 Standard_Real PTol = Precision::Parametric(Precision::Confusion());
304 // Borders of underlying geometry.
305 Standard_Real anUMinParam = UMin, anUMaxParam = UMax,// BSpline case.
306 aVMinParam = VMin, aVMaxParam = VMax;
307 if (Type == GeomAbs_BezierSurface)
310 // All of poles used for any parameter,
311 // thats why in case of trimmed parameters handled by grid algorithm.
313 if (Abs(UMin-S.FirstUParameter()) > PTol ||
314 Abs(VMin-S.FirstVParameter()) > PTol ||
315 Abs(UMax-S.LastUParameter ()) > PTol ||
316 Abs(VMax-S.LastVParameter ()) > PTol )
318 // Borders not equal to topology borders.
319 isUseConvexHullAlgorithm = Standard_False;
325 // If Umin, Vmin, Umax, Vmax lies inside geometry bounds then:
326 // use convex hull algorithm,
327 // if Umin, VMin, Umax, Vmax lies outside then:
328 // use grid algorithm on analytic continuation (default case).
329 S.BSpline()->Bounds(anUMinParam, anUMaxParam, aVMinParam, aVMaxParam);
331 if ( (UMin - anUMinParam) < -PTol ||
332 (VMin - aVMinParam) < -PTol ||
333 (UMax - anUMaxParam) > PTol ||
334 (VMax - aVMaxParam) > PTol )
336 // Out of geometry borders.
337 isUseConvexHullAlgorithm = Standard_False;
341 if (isUseConvexHullAlgorithm)
343 TColgp_Array2OfPnt Tp(1,S.NbUPoles(),1,S.NbVPoles());
344 Standard_Integer UMinIdx = 0, UMaxIdx = 0;
345 Standard_Integer VMinIdx = 0, VMaxIdx = 0;
346 if (Type == GeomAbs_BezierSurface)
348 S.Bezier()->Poles(Tp);
350 UMinIdx = Tp.LowerRow();
351 UMaxIdx = Tp.UpperRow();
352 VMinIdx = Tp.LowerCol();
353 VMaxIdx = Tp.UpperCol();
357 S.BSpline()->Poles(Tp);
359 UMinIdx = Tp.LowerRow();
360 UMaxIdx = Tp.UpperRow();
361 VMinIdx = Tp.LowerCol();
362 VMaxIdx = Tp.UpperCol();
364 if (UMin > anUMinParam ||
367 Standard_Integer anUFlatKnotsCount = S.BSpline()->NbUPoles() + S.BSpline()->UDegree() + 1;
368 Standard_Integer aShift = 1;
370 if (S.BSpline()->IsUPeriodic())
372 TColStd_Array1OfInteger aMults(1, S.BSpline()->NbUKnots());
373 S.BSpline()->UMultiplicities(aMults);
374 anUFlatKnotsCount = BSplCLib::KnotSequenceLength(aMults, S.BSpline()->UDegree(), Standard_True);
376 aShift = S.BSpline()->UDegree() + 1 - S.BSpline()->UMultiplicity(1);
379 TColStd_Array1OfReal anUFlatKnots(1, anUFlatKnotsCount);
380 S.BSpline()->UKnotSequence(anUFlatKnots);
382 ComputePolesIndexes(anUFlatKnots,
383 S.BSpline()->UDegree(),
385 UMinIdx, UMaxIdx, // Min and Max Indexes
387 UMinIdx, UMaxIdx); // the Output indexes
390 if (VMin > aVMinParam ||
393 Standard_Integer anVFlatKnotsCount = S.BSpline()->NbVPoles() + S.BSpline()->VDegree() + 1;
394 Standard_Integer aShift = 1;
396 if (S.BSpline()->IsVPeriodic())
398 TColStd_Array1OfInteger aMults(1, S.BSpline()->NbVKnots());
399 S.BSpline()->VMultiplicities(aMults);
400 anVFlatKnotsCount = BSplCLib::KnotSequenceLength(aMults, S.BSpline()->VDegree(), Standard_True);
402 aShift = S.BSpline()->VDegree() + 1 - S.BSpline()->VMultiplicity(1);
405 TColStd_Array1OfReal anVFlatKnots(1, anVFlatKnotsCount);
406 S.BSpline()->VKnotSequence(anVFlatKnots);
408 ComputePolesIndexes(anVFlatKnots,
409 S.BSpline()->VDegree(),
411 VMinIdx, VMaxIdx, // Min and Max Indexes
413 VMinIdx, VMaxIdx); // the Output indexes
418 // Use poles to build convex hull.
419 for (Standard_Integer i = UMinIdx; i <= UMaxIdx; i++)
421 for (Standard_Integer j = VMinIdx; j <= VMaxIdx; j++)
433 Standard_Integer Nu = NbUSamples(S);
434 Standard_Integer Nv = NbVSamples(S);
436 for (Standard_Integer i =1 ;i<=Nu;i++){
437 Standard_Real U = UMin + ((UMax-UMin)*(i-1)/(Nu-1));
438 for (Standard_Integer j=1 ;j<=Nv;j++){
439 Standard_Real V = VMin + ((VMax-VMin)*(j-1)/(Nv-1));