0027232: Configuration - fix mblen missing building issue on Android
[occt.git] / src / BndLib / BndLib_Add3dCurve.cxx
CommitLineData
b311480e 1// Copyright (c) 1996-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
42cf5bc1 15
16#include <Adaptor3d_Curve.hxx>
17#include <Bnd_Box.hxx>
7fd59977 18#include <BndLib.hxx>
42cf5bc1 19#include <BndLib_Add3dCurve.hxx>
20#include <ElCLib.hxx>
7fd59977 21#include <Geom_BezierCurve.hxx>
22#include <Geom_BSplineCurve.hxx>
42cf5bc1 23#include <GeomAbs_CurveType.hxx>
24#include <GeomAdaptor_Curve.hxx>
7fd59977 25#include <gp_Circ.hxx>
26#include <gp_Elips.hxx>
7fd59977 27#include <gp_Hypr.hxx>
42cf5bc1 28#include <gp_Lin.hxx>
29#include <gp_Parab.hxx>
30#include <gp_Pnt.hxx>
7fd59977 31#include <Precision.hxx>
42cf5bc1 32#include <TColgp_Array1OfPnt.hxx>
7fd59977 33#include <TColStd_Array1OfInteger.hxx>
42cf5bc1 34#include <TColStd_Array1OfReal.hxx>
7fd59977 35
bcd19756 36//=======================================================================
37//function : reduceSplineBox
38//purpose : This method intended to reduce box in case of
39// bezier and bspline curve.
40//=======================================================================
41static void reduceSplineBox(const Adaptor3d_Curve& theCurve,
42 const Bnd_Box& theOrigBox,
43 Bnd_Box & theReducedBox)
44{
45 // Guaranteed bounding box based on poles of bspline.
46 Bnd_Box aPolesBox;
47 Standard_Real aPolesXMin, aPolesYMin, aPolesZMin,
48 aPolesXMax, aPolesYMax, aPolesZMax;
49
50 if (theCurve.GetType() == GeomAbs_BSplineCurve)
51 {
52 Handle(Geom_BSplineCurve) aC = theCurve.BSpline();
53 const TColgp_Array1OfPnt& aPoles = aC->Poles();
54
55 for(Standard_Integer anIdx = aPoles.Lower();
56 anIdx <= aPoles.Upper();
57 ++anIdx)
58 {
59 aPolesBox.Add(aPoles.Value(anIdx));
60 }
61 }
62 if (theCurve.GetType() == GeomAbs_BezierCurve)
63 {
64 Handle(Geom_BezierCurve) aC = theCurve.Bezier();
65 const TColgp_Array1OfPnt& aPoles = aC->Poles();
66
67 for(Standard_Integer anIdx = aPoles.Lower();
68 anIdx <= aPoles.Upper();
69 ++anIdx)
70 {
71 aPolesBox.Add(aPoles.Value(anIdx));
72 }
73 }
74
75 aPolesBox.Get(aPolesXMin, aPolesYMin, aPolesZMin,
76 aPolesXMax, aPolesYMax, aPolesZMax);
77
78 Standard_Real x, y, z, X, Y, Z;
79 theOrigBox.Get(x, y, z, X, Y, Z);
80
81 // Left bound.
82 if (aPolesXMin > x)
83 x = aPolesXMin;
84 if (aPolesYMin > y)
85 y = aPolesYMin;
86 if (aPolesZMin > z)
87 z = aPolesZMin;
88
89 // Right bound.
90 if (aPolesXMax < X)
91 X = aPolesXMax;
92 if (aPolesYMax < Y)
93 Y = aPolesYMax;
94 if (aPolesZMax < Z)
95 Z = aPolesZMax;
96
97 theReducedBox.Update(x, y, z, X, Y, Z);
98}
99
7fd59977 100//=======================================================================
101//function : Add
102//purpose :
103//=======================================================================
7fd59977 104void BndLib_Add3dCurve::Add( const Adaptor3d_Curve& C,
105 const Standard_Real Tol,
106 Bnd_Box& B )
107{
108 BndLib_Add3dCurve::Add(C,
109 C.FirstParameter(),
110 C.LastParameter (),
111 Tol,B);
112}
113
114//OCC566(apo)->
115static Standard_Real FillBox(Bnd_Box& B, const Adaptor3d_Curve& C,
116 const Standard_Real first, const Standard_Real last,
117 const Standard_Integer N)
118{
119 gp_Pnt P1, P2, P3;
120 C.D0(first,P1); B.Add(P1);
121 Standard_Real p = first, dp = last-first, tol= 0.;
122 if(Abs(dp) > Precision::PConfusion()){
123 Standard_Integer i;
124 dp /= 2*N;
125 for(i = 1; i <= N; i++){
126 p += dp; C.D0(p,P2); B.Add(P2);
127 p += dp; C.D0(p,P3); B.Add(P3);
128 gp_Pnt Pc((P1.XYZ()+P3.XYZ())/2.0);
129 tol = Max(tol,Pc.Distance(P2));
130 P1 = P3;
131 }
132 }else{
133 C.D0(first,P1); B.Add(P1);
134 C.D0(last,P3); B.Add(P3);
135 tol = 0.;
136 }
137 return tol;
138}
139//<-OCC566(apo)
140//=======================================================================
141//function : Add
142//purpose :
143//=======================================================================
144
145void BndLib_Add3dCurve::Add( const Adaptor3d_Curve& C,
146 const Standard_Real U1,
147 const Standard_Real U2,
148 const Standard_Real Tol,
149 Bnd_Box& B )
150{
151 static Standard_Real weakness = 1.5; //OCC566(apo)
152 Standard_Real tol = 0.0;
153 switch (C.GetType()) {
154
155 case GeomAbs_Line:
156 {
157 BndLib::Add(C.Line(),U1,U2,Tol,B);
158 break;
159 }
160 case GeomAbs_Circle:
161 {
162 BndLib::Add(C.Circle(),U1,U2,Tol,B);
163 break;
164 }
165 case GeomAbs_Ellipse:
166 {
167 BndLib::Add(C.Ellipse(),U1,U2,Tol,B);
168 break;
169 }
170 case GeomAbs_Hyperbola:
171 {
172 BndLib::Add(C.Hyperbola(),U1,U2,Tol,B);
173 break;
174 }
175 case GeomAbs_Parabola:
176 {
177 BndLib::Add(C.Parabola(),U1,U2,Tol,B);
178 break;
179 }
180 case GeomAbs_BezierCurve:
181 {
182 Handle(Geom_BezierCurve) Bz = C.Bezier();
7fd59977 183 Standard_Integer N = Bz->Degree();
184 GeomAdaptor_Curve GACurve(Bz);
185 Bnd_Box B1;
186 tol = FillBox(B1,GACurve,U1,U2,N);
187 B1.Enlarge(weakness*tol);
bcd19756 188 reduceSplineBox(C, B1, B);
7fd59977 189 B.Enlarge(Tol);
7fd59977 190 break;
191 }
192 case GeomAbs_BSplineCurve:
193 {
194 Handle(Geom_BSplineCurve) Bs = C.BSpline();
195 if(Abs(Bs->FirstParameter() - U1) > Precision::Parametric(Tol)||
196 Abs(Bs->LastParameter() - U2) > Precision::Parametric(Tol)) {
197
198 Handle(Geom_Geometry) G = Bs->Copy();
a1eb3afd 199 Handle(Geom_BSplineCurve) Bsaux (Handle(Geom_BSplineCurve)::DownCast (G));
7fd59977 200 Standard_Real u1 = U1, u2 = U2;
201 //// modified by jgv, 24.10.01 for BUC61031 ////
202 if (Bsaux->IsPeriodic())
203 ElCLib::AdjustPeriodic( Bsaux->FirstParameter(), Bsaux->LastParameter(), Precision::PConfusion(), u1, u2 );
1bd657ae 204 else {
253881cf 205 ////////////////////////////////////////////////
206 // modified by NIZHNY-EAP Fri Dec 3 14:29:14 1999 ___BEGIN___
207 // To avoid exeption in Segment
208 if(Bsaux->FirstParameter() > U1) u1 = Bsaux->FirstParameter();
209 if(Bsaux->LastParameter() < U2 ) u2 = Bsaux->LastParameter();
210 // modified by NIZHNY-EAP Fri Dec 3 14:29:18 1999 ___END___
1bd657ae 211 }
7fd59977 212 Bsaux->Segment(u1, u2);
213 Bs = Bsaux;
214 }
215 //OCC566(apo)->
216 Bnd_Box B1;
217 Standard_Integer k, k1 = Bs->FirstUKnotIndex(), k2 = Bs->LastUKnotIndex(),
218 N = Bs->Degree(), NbKnots = Bs->NbKnots();
219 TColStd_Array1OfReal Knots(1,NbKnots);
220 Bs->Knots(Knots);
221 GeomAdaptor_Curve GACurve(Bs);
222 Standard_Real first = Knots(k1), last;
223 for(k = k1 + 1; k <= k2; k++){
224 last = Knots(k);
225 tol = Max(FillBox(B1,GACurve,first,last,N), tol);
226 first = last;
227 }
44fb70f2
M
228 if (!B1.IsVoid())
229 {
230 B1.Enlarge(weakness*tol);
bcd19756 231 reduceSplineBox(C, B1, B);
44fb70f2
M
232 B.Enlarge(Tol);
233 }
7fd59977 234 //<-OCC566(apo)
235 break;
236 }
237 default:
238 {
239 Bnd_Box B1;
240 static Standard_Integer N = 33;
241 tol = FillBox(B1,C,U1,U2,N);
242 B1.Enlarge(weakness*tol);
243 Standard_Real x, y, z, X, Y, Z;
244 B1.Get(x, y, z, X, Y, Z);
245 B.Update(x, y, z, X, Y, Z);
246 B.Enlarge(Tol);
247 }
248 }
249}