Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: BndLib_AddSurface.gxx |
2 | // Created: Mon Jul 24 14:18:23 1995 | |
3 | // Author: Modelistation | |
4 | // <model@metrox> | |
5 | ||
6 | // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 | |
7 | ||
8 | ||
9 | #include <BndLib_AddSurface.ixx> | |
10 | ||
11 | ||
12 | #include <Adaptor3d_HSurface.hxx> | |
13 | #include <GeomAbs_SurfaceType.hxx> | |
14 | #include <BndLib.hxx> | |
15 | #include <gp_Pnt.hxx> | |
16 | #include <gp_Pln.hxx> | |
17 | #include <ElSLib.hxx> | |
18 | #include <TColgp_Array2OfPnt.hxx> | |
19 | #include <Geom_BSplineSurface.hxx> | |
20 | #include <Geom_BezierSurface.hxx> | |
21 | ||
22 | #include <Precision.hxx> | |
23 | ||
24 | //======================================================================= | |
25 | //function : Add | |
26 | //purpose : | |
27 | //======================================================================= | |
28 | ||
29 | void BndLib_AddSurface::Add(const Adaptor3d_Surface& S, | |
30 | const Standard_Real Tol, | |
31 | Bnd_Box& B ) | |
32 | { | |
33 | ||
34 | BndLib_AddSurface::Add(S, | |
35 | S.FirstUParameter(), | |
36 | S.LastUParameter (), | |
37 | S.FirstVParameter(), | |
38 | S.LastVParameter (),Tol,B); | |
39 | } | |
40 | //======================================================================= | |
41 | //function : NbUSamples | |
42 | //purpose : | |
43 | //======================================================================= | |
44 | ||
45 | static Standard_Integer NbUSamples(const Adaptor3d_Surface& S) | |
46 | { | |
47 | Standard_Integer N; | |
48 | GeomAbs_SurfaceType Type = S.GetType(); | |
49 | switch (Type) { | |
50 | case GeomAbs_BezierSurface: | |
51 | { | |
52 | N = 2*S.NbUPoles(); | |
53 | break; | |
54 | } | |
55 | case GeomAbs_BSplineSurface: | |
56 | { | |
57 | const Handle(Geom_BSplineSurface)& BS = S.BSpline(); | |
58 | N = 2*(BS->UDegree() + 1)*(BS->NbUKnots() -1); | |
59 | break; | |
60 | } | |
61 | default: | |
62 | N = 33; | |
63 | } | |
64 | return Min (50,N); | |
65 | } | |
66 | ||
67 | //======================================================================= | |
68 | //function : NbVSamples | |
69 | //purpose : | |
70 | //======================================================================= | |
71 | ||
72 | static Standard_Integer NbVSamples(const Adaptor3d_Surface& S) | |
73 | { | |
74 | Standard_Integer N; | |
75 | GeomAbs_SurfaceType Type = S.GetType(); | |
76 | switch (Type) { | |
77 | case GeomAbs_BezierSurface: | |
78 | { | |
79 | N = 2*S.NbVPoles(); | |
80 | break; | |
81 | } | |
82 | case GeomAbs_BSplineSurface: | |
83 | { | |
84 | const Handle(Geom_BSplineSurface)& BS = S.BSpline(); | |
85 | N = 2*(BS->VDegree() + 1)*(BS->NbVKnots() - 1) ; | |
86 | break; | |
87 | } | |
88 | default: | |
89 | N = 33; | |
90 | } | |
91 | return Min(50,N); | |
92 | } | |
93 | ||
94 | // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 Begin | |
95 | static gp_Pnt BaryCenter(const gp_Pln &aPlane, | |
96 | const Standard_Real aUMin, | |
97 | const Standard_Real aUMax, | |
98 | const Standard_Real aVMin, | |
99 | const Standard_Real aVMax) | |
100 | { | |
101 | Standard_Real aU, aV; | |
102 | Standard_Boolean isU1Inf = Precision::IsInfinite(aUMin); | |
103 | Standard_Boolean isU2Inf = Precision::IsInfinite(aUMax); | |
104 | Standard_Boolean isV1Inf = Precision::IsInfinite(aVMin); | |
105 | Standard_Boolean isV2Inf = Precision::IsInfinite(aVMax); | |
106 | ||
107 | if (isU1Inf && isU2Inf) | |
108 | aU = 0; | |
109 | else if (isU1Inf) | |
110 | aU = aUMax - 10.; | |
111 | else if (isU2Inf) | |
112 | aU = aUMin + 10.; | |
113 | else | |
114 | aU = (aUMin + aUMax)/2.; | |
115 | ||
116 | if (isV1Inf && isV2Inf) | |
117 | aV = 0; | |
118 | else if (isV1Inf) | |
119 | aV = aVMax - 10.; | |
120 | else if (isV2Inf) | |
121 | aV = aVMin + 10.; | |
122 | else | |
123 | aV = (aVMin + aVMax)/2.; | |
124 | ||
125 | gp_Pnt aCenter = ElSLib::Value(aU, aV, aPlane); | |
126 | ||
127 | return aCenter; | |
128 | } | |
129 | ||
130 | static void TreatInfinitePlane(const gp_Pln &aPlane, | |
131 | const Standard_Real aUMin, | |
132 | const Standard_Real aUMax, | |
133 | const Standard_Real aVMin, | |
134 | const Standard_Real aVMax, | |
135 | const Standard_Real aTol, | |
136 | Bnd_Box &aB) | |
137 | { | |
138 | // Get 3 coordinate axes of the plane. | |
139 | const gp_Dir &aNorm = aPlane.Axis().Direction(); | |
140 | const gp_Dir &aXDir = aPlane.XAxis().Direction(); | |
141 | const gp_Dir &aYDir = aPlane.YAxis().Direction(); | |
142 | const Standard_Real anAngularTol = RealEpsilon(); | |
143 | ||
144 | // Get location of the plane as its barycenter | |
145 | gp_Pnt aLocation = BaryCenter(aPlane, aUMin, aUMax, aVMin, aVMax); | |
146 | ||
147 | if (aNorm.IsParallel(gp::DX(), anAngularTol)) { | |
148 | aB.Add(aLocation); | |
149 | aB.OpenYmin(); | |
150 | aB.OpenYmax(); | |
151 | aB.OpenZmin(); | |
152 | aB.OpenZmax(); | |
153 | } else if (aNorm.IsParallel(gp::DY(), anAngularTol)) { | |
154 | aB.Add(aLocation); | |
155 | aB.OpenXmin(); | |
156 | aB.OpenXmax(); | |
157 | aB.OpenZmin(); | |
158 | aB.OpenZmax(); | |
159 | } else if (aNorm.IsParallel(gp::DZ(), anAngularTol)) { | |
160 | aB.Add(aLocation); | |
161 | aB.OpenXmin(); | |
162 | aB.OpenXmax(); | |
163 | aB.OpenYmin(); | |
164 | aB.OpenYmax(); | |
165 | } else { | |
166 | aB.SetWhole(); | |
167 | return; | |
168 | } | |
169 | ||
170 | aB.Enlarge(aTol); | |
171 | } | |
172 | // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End | |
173 | ||
174 | //======================================================================= | |
175 | //function : Add | |
176 | //purpose : | |
177 | //======================================================================= | |
178 | ||
179 | void BndLib_AddSurface::Add(const Adaptor3d_Surface& S, | |
180 | const Standard_Real UMin, | |
181 | const Standard_Real UMax, | |
182 | const Standard_Real VMin, | |
183 | const Standard_Real VMax, | |
184 | const Standard_Real Tol, | |
185 | Bnd_Box& B ) | |
186 | { | |
187 | GeomAbs_SurfaceType Type = S.GetType(); // skv OCC6503 | |
188 | ||
189 | if (Precision::IsInfinite(VMin) || | |
190 | Precision::IsInfinite(VMax) || | |
191 | Precision::IsInfinite(UMin) || | |
192 | Precision::IsInfinite(UMax) ) { | |
193 | // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 Begin | |
194 | // B.SetWhole(); | |
195 | // return; | |
196 | switch (Type) { | |
197 | case GeomAbs_Plane: | |
198 | { | |
199 | TreatInfinitePlane(S.Plane(), UMin, UMax, VMin, VMax, Tol, B); | |
200 | return; | |
201 | } | |
202 | default: | |
203 | { | |
204 | B.SetWhole(); | |
205 | return; | |
206 | } | |
207 | } | |
208 | // Modified by skv - Fri Aug 27 12:29:04 2004 OCC6503 End | |
209 | } | |
210 | ||
211 | // GeomAbs_SurfaceType Type = S.GetType(); // skv OCC6503 | |
212 | ||
213 | switch (Type) { | |
214 | ||
215 | case GeomAbs_Plane: | |
216 | { | |
217 | gp_Pln Plan = S.Plane(); | |
218 | B.Add(ElSLib::Value(UMin,VMin,Plan)); | |
219 | B.Add(ElSLib::Value(UMin,VMax,Plan)); | |
220 | B.Add(ElSLib::Value(UMax,VMin,Plan)); | |
221 | B.Add(ElSLib::Value(UMax,VMax,Plan)); | |
222 | B.Enlarge(Tol); | |
223 | break; | |
224 | } | |
225 | case GeomAbs_Cylinder: | |
226 | { | |
227 | BndLib::Add(S.Cylinder(),UMin,UMax,VMin,VMax,Tol,B); | |
228 | break; | |
229 | } | |
230 | case GeomAbs_Cone: | |
231 | { | |
232 | BndLib::Add(S.Cone(),UMin,UMax,VMin,VMax,Tol,B); | |
233 | break; | |
234 | } | |
235 | case GeomAbs_Torus: | |
236 | { | |
237 | BndLib::Add(S.Torus(),UMin,UMax,VMin,VMax,Tol,B); | |
238 | break; | |
239 | } | |
240 | case GeomAbs_Sphere: | |
241 | { | |
242 | if (Abs(UMin) < Precision::Angular() && | |
c6541a0c D |
243 | Abs(UMax - 2.*M_PI) < Precision::Angular() && |
244 | Abs(VMin + M_PI/2.) < Precision::Angular() && | |
245 | Abs(VMax - M_PI/2.) < Precision::Angular()) // a whole sphere | |
7fd59977 | 246 | BndLib::Add(S.Sphere(),Tol,B); |
247 | else | |
248 | BndLib::Add(S.Sphere(),UMin,UMax,VMin,VMax,Tol,B); | |
249 | break; | |
250 | } | |
251 | case GeomAbs_OffsetSurface: | |
252 | { | |
253 | Handle(Adaptor3d_HSurface) HS = S.BasisSurface(); | |
254 | Add (HS->Surface(),UMin,UMax,VMin,VMax,Tol,B); | |
255 | B.Enlarge(S.OffsetValue()); | |
256 | B.Enlarge(Tol); | |
257 | break; | |
258 | } | |
259 | case GeomAbs_BezierSurface: | |
260 | case GeomAbs_BSplineSurface: | |
261 | { | |
262 | Standard_Real PTol = Precision::Parametric(Precision::Confusion()); | |
263 | if (Abs(UMin-S.FirstUParameter()) < PTol && | |
264 | Abs(VMin-S.FirstVParameter()) < PTol && | |
265 | Abs(UMax-S.LastUParameter ()) < PTol && | |
266 | Abs(VMax-S.LastVParameter ()) < PTol ) { | |
267 | TColgp_Array2OfPnt Tp(1,S.NbUPoles(),1,S.NbVPoles()); | |
268 | if (Type == GeomAbs_BezierSurface) { | |
269 | S.Bezier()->Poles(Tp); | |
270 | } | |
271 | else { | |
272 | S.BSpline()->Poles(Tp); | |
273 | } | |
274 | for (Standard_Integer i = Tp.LowerRow();i<=Tp.UpperRow();i++) { | |
275 | for (Standard_Integer j = Tp.LowerCol();j<=Tp.UpperCol();j++) { | |
276 | B.Add(Tp(i,j)); | |
277 | } | |
278 | } | |
279 | B.Enlarge(Tol); | |
280 | break; | |
281 | } | |
282 | } | |
283 | default: | |
284 | { | |
285 | Standard_Integer Nu = NbUSamples(S); | |
286 | Standard_Integer Nv = NbVSamples(S); | |
287 | gp_Pnt P; | |
288 | for (Standard_Integer i =1 ;i<=Nu;i++){ | |
289 | Standard_Real U = UMin + ((UMax-UMin)*(i-1)/(Nu-1)); | |
290 | for (Standard_Integer j=1 ;j<=Nv;j++){ | |
291 | Standard_Real V = VMin + ((VMax-VMin)*(j-1)/(Nv-1)); | |
292 | S.D0(U,V,P); | |
293 | B.Add(P); | |
294 | } | |
295 | } | |
296 | B.Enlarge(Tol); | |
297 | } | |
298 | } | |
299 | } |