Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1991-03-08 |
2 | // Created by: Christophe MARION | |
3 | // Copyright (c) 1991-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
aa396061 | 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. | |
b311480e | 16 | |
42cf5bc1 | 17 | #include <Bnd_Box.hxx> |
18 | #include <gp_Dir.hxx> | |
19 | #include <gp_Lin.hxx> | |
20 | #include <gp_Pln.hxx> | |
21 | #include <gp_Pnt.hxx> | |
22 | #include <gp_Trsf.hxx> | |
23 | #include <Standard_ConstructionError.hxx> | |
7fd59977 | 24 | |
7fd59977 | 25 | // set the flag to one |
7fd59977 | 26 | #define ClearVoidFlag() ( Flags &= ~VoidMask ) |
27 | ||
28 | #include <Standard_Stream.hxx> | |
29 | #include <gp.hxx> | |
30 | // #include <Precision.hxx> | |
31 | #define Bnd_Precision_Infinite 1e+100 | |
32 | ||
33 | //======================================================================= | |
34 | //function : Bnd_Box | |
35 | //purpose : | |
36 | //======================================================================= | |
37 | ||
38 | Bnd_Box::Bnd_Box() | |
39 | : Xmin(0.), Xmax(0.), Ymin(0.), Ymax(0.), Zmin(0.), Zmax(0.), Gap(0.) | |
40 | { | |
41 | SetVoid(); | |
42 | } | |
43 | ||
7fd59977 | 44 | //======================================================================= |
45 | //function : Set | |
46 | //purpose : | |
47 | //======================================================================= | |
48 | ||
49 | void Bnd_Box::Set(const gp_Pnt& P) | |
50 | { | |
51 | SetVoid(); | |
52 | Add(P); | |
53 | } | |
54 | ||
55 | //======================================================================= | |
56 | //function : Set | |
57 | //purpose : | |
58 | //======================================================================= | |
59 | ||
60 | void Bnd_Box::Set(const gp_Pnt& P, const gp_Dir& D) | |
61 | { | |
62 | SetVoid(); | |
63 | Add(P,D); | |
64 | } | |
65 | ||
66 | ||
67 | //======================================================================= | |
68 | //function : Update | |
69 | //purpose : | |
70 | //======================================================================= | |
71 | ||
72 | void Bnd_Box::Update (const Standard_Real x, | |
73 | const Standard_Real y, | |
74 | const Standard_Real z, | |
75 | const Standard_Real X, | |
76 | const Standard_Real Y, | |
77 | const Standard_Real Z) | |
78 | { | |
dde68833 | 79 | if (IsVoid()) |
80 | { | |
7fd59977 | 81 | Xmin = x; |
82 | Ymin = y; | |
83 | Zmin = z; | |
84 | Xmax = X; | |
85 | Ymax = Y; | |
86 | Zmax = Z; | |
87 | ClearVoidFlag(); | |
88 | } | |
89 | else { | |
dde68833 | 90 | if (!IsOpenXmin() && (x < Xmin)) Xmin = x; |
91 | if (!IsOpenXmax() && (X > Xmax)) Xmax = X; | |
92 | if (!IsOpenYmin() && (y < Ymin)) Ymin = y; | |
93 | if (!IsOpenYmax() && (Y > Ymax)) Ymax = Y; | |
94 | if (!IsOpenZmin() && (z < Zmin)) Zmin = z; | |
95 | if (!IsOpenZmax() && (Z > Zmax)) Zmax = Z; | |
7fd59977 | 96 | } |
97 | } | |
98 | ||
99 | //======================================================================= | |
100 | //function : Update | |
101 | //purpose : | |
102 | //======================================================================= | |
103 | ||
104 | void Bnd_Box::Update (const Standard_Real X, | |
105 | const Standard_Real Y, | |
106 | const Standard_Real Z) | |
107 | { | |
dde68833 | 108 | if (IsVoid()) |
109 | { | |
7fd59977 | 110 | Xmin = X; |
111 | Ymin = Y; | |
112 | Zmin = Z; | |
113 | Xmax = X; | |
114 | Ymax = Y; | |
115 | Zmax = Z; | |
116 | ClearVoidFlag(); | |
117 | } | |
118 | else { | |
dde68833 | 119 | if (!IsOpenXmin() && (X < Xmin)) Xmin = X; |
120 | else if (!IsOpenXmax() && (X > Xmax)) Xmax = X; | |
121 | if (!IsOpenYmin() && (Y < Ymin)) Ymin = Y; | |
122 | else if (!IsOpenYmax() && (Y > Ymax)) Ymax = Y; | |
123 | if (!IsOpenZmin() && (Z < Zmin)) Zmin = Z; | |
124 | else if (!IsOpenZmax() && (Z > Zmax)) Zmax = Z; | |
7fd59977 | 125 | } |
126 | } | |
127 | ||
128 | //======================================================================= | |
129 | //function : GetGap | |
130 | //purpose : | |
131 | //======================================================================= | |
132 | ||
133 | Standard_Real Bnd_Box::GetGap () const | |
134 | { | |
135 | return Gap; | |
136 | } | |
137 | ||
138 | //======================================================================= | |
139 | //function : SetGap | |
140 | //purpose : | |
141 | //======================================================================= | |
142 | ||
143 | void Bnd_Box::SetGap (const Standard_Real Tol) | |
144 | { | |
145 | Gap = Tol; | |
146 | } | |
147 | ||
148 | //======================================================================= | |
149 | //function : Enlarge | |
150 | //purpose : | |
151 | //======================================================================= | |
152 | ||
153 | void Bnd_Box::Enlarge (const Standard_Real Tol) | |
154 | { | |
155 | Gap=Max(Gap, Abs(Tol)); | |
156 | } | |
157 | ||
158 | //======================================================================= | |
159 | //function : Get | |
160 | //purpose : | |
161 | //======================================================================= | |
162 | ||
ed063270 | 163 | void Bnd_Box::Get (Standard_Real& theXmin, |
164 | Standard_Real& theYmin, | |
165 | Standard_Real& theZmin, | |
166 | Standard_Real& theXmax, | |
167 | Standard_Real& theYmax, | |
168 | Standard_Real& theZmax) const | |
7fd59977 | 169 | { |
dde68833 | 170 | if (IsVoid()) |
ed063270 | 171 | { |
9775fa61 | 172 | throw Standard_ConstructionError("Bnd_Box is void"); |
ed063270 | 173 | } |
174 | ||
dde68833 | 175 | if (IsOpenXmin()) theXmin = -Bnd_Precision_Infinite; |
176 | else theXmin = Xmin - Gap; | |
177 | if (IsOpenXmax()) theXmax = Bnd_Precision_Infinite; | |
178 | else theXmax = Xmax + Gap; | |
179 | if (IsOpenYmin()) theYmin = -Bnd_Precision_Infinite; | |
180 | else theYmin = Ymin - Gap; | |
181 | if (IsOpenYmax()) theYmax = Bnd_Precision_Infinite; | |
182 | else theYmax = Ymax + Gap; | |
183 | if (IsOpenZmin()) theZmin = -Bnd_Precision_Infinite; | |
184 | else theZmin = Zmin - Gap; | |
185 | if (IsOpenZmax()) theZmax = Bnd_Precision_Infinite; | |
186 | else theZmax = Zmax + Gap; | |
ed063270 | 187 | } |
188 | ||
189 | //======================================================================= | |
190 | //function : CornerMin | |
191 | //purpose : | |
192 | //======================================================================= | |
193 | ||
194 | gp_Pnt Bnd_Box::CornerMin() const | |
195 | { | |
196 | gp_Pnt aCornerMin; | |
dde68833 | 197 | if (IsVoid()) |
ed063270 | 198 | { |
9775fa61 | 199 | throw Standard_ConstructionError("Bnd_Box is void"); |
ed063270 | 200 | } |
dde68833 | 201 | if (IsOpenXmin()) aCornerMin.SetX (-Bnd_Precision_Infinite); |
202 | else aCornerMin.SetX (Xmin - Gap); | |
203 | if (IsOpenYmin()) aCornerMin.SetY (-Bnd_Precision_Infinite); | |
204 | else aCornerMin.SetY (Ymin - Gap); | |
205 | if (IsOpenZmin()) aCornerMin.SetZ (-Bnd_Precision_Infinite); | |
206 | else aCornerMin.SetZ (Zmin - Gap); | |
ed063270 | 207 | return aCornerMin; |
208 | } | |
209 | ||
210 | //======================================================================= | |
211 | //function : CornerMax | |
212 | //purpose : | |
213 | //======================================================================= | |
214 | ||
215 | gp_Pnt Bnd_Box::CornerMax() const | |
216 | { | |
217 | gp_Pnt aCornerMax; | |
dde68833 | 218 | if (IsVoid()) |
ed063270 | 219 | { |
9775fa61 | 220 | throw Standard_ConstructionError("Bnd_Box is void"); |
ed063270 | 221 | } |
dde68833 | 222 | if (IsOpenXmax()) aCornerMax.SetX (Bnd_Precision_Infinite); |
223 | else aCornerMax.SetX (Xmax + Gap); | |
224 | if (IsOpenYmin()) aCornerMax.SetY (Bnd_Precision_Infinite); | |
225 | else aCornerMax.SetY (Ymax + Gap); | |
226 | if (IsOpenZmin()) aCornerMax.SetZ (Bnd_Precision_Infinite); | |
227 | else aCornerMax.SetZ (Zmax + Gap); | |
ed063270 | 228 | return aCornerMax; |
7fd59977 | 229 | } |
230 | ||
7fd59977 | 231 | //======================================================================= |
232 | //function : IsXThin | |
233 | //purpose : | |
234 | //======================================================================= | |
235 | ||
236 | Standard_Boolean Bnd_Box::IsXThin (const Standard_Real tol) const | |
237 | { | |
238 | if (IsWhole()) return Standard_False; | |
239 | if (IsVoid()) return Standard_True; | |
dde68833 | 240 | if (IsOpenXmin()) return Standard_False; |
241 | if (IsOpenXmax()) return Standard_False; | |
7fd59977 | 242 | if (Xmax-Xmin < tol) return Standard_True; |
243 | return Standard_False; | |
244 | } | |
245 | ||
246 | //======================================================================= | |
247 | //function : IsYThin | |
248 | //purpose : | |
249 | //======================================================================= | |
250 | ||
251 | Standard_Boolean Bnd_Box::IsYThin (const Standard_Real tol) const | |
252 | { | |
253 | if (IsWhole()) return Standard_False; | |
254 | if (IsVoid()) return Standard_True; | |
dde68833 | 255 | if (IsOpenYmin()) return Standard_False; |
256 | if (IsOpenYmax()) return Standard_False; | |
7fd59977 | 257 | if (Ymax-Ymin < tol) return Standard_True; |
258 | return Standard_False; | |
259 | } | |
260 | ||
261 | //======================================================================= | |
262 | //function : IsZThin | |
263 | //purpose : | |
264 | //======================================================================= | |
265 | ||
266 | Standard_Boolean Bnd_Box::IsZThin (const Standard_Real tol) const | |
267 | { | |
268 | if (IsWhole()) return Standard_False; | |
269 | if (IsVoid()) return Standard_True; | |
dde68833 | 270 | if (IsOpenZmin()) return Standard_False; |
271 | if (IsOpenZmax()) return Standard_False; | |
7fd59977 | 272 | if (Zmax-Zmin < tol) return Standard_True; |
273 | return Standard_False; | |
274 | } | |
275 | ||
276 | //======================================================================= | |
277 | //function : IsThin | |
278 | //purpose : | |
279 | //======================================================================= | |
280 | ||
281 | Standard_Boolean Bnd_Box::IsThin (const Standard_Real tol) const | |
282 | { | |
283 | if (!IsXThin(tol)) return Standard_False; | |
284 | if (!IsYThin(tol)) return Standard_False; | |
285 | if (!IsZThin(tol)) return Standard_False; | |
286 | return Standard_True; | |
287 | } | |
288 | ||
289 | //======================================================================= | |
290 | //function : Transformed | |
291 | //purpose : | |
292 | //======================================================================= | |
293 | ||
294 | Bnd_Box Bnd_Box::Transformed (const gp_Trsf& T) const | |
295 | { | |
296 | gp_TrsfForm F = T.Form(); | |
297 | Bnd_Box newb(*this); | |
298 | if ( IsVoid() ) return newb; | |
299 | ||
300 | if (F == gp_Identity) {} | |
301 | else if (F == gp_Translation) { | |
302 | Standard_Real DX,DY,DZ; | |
303 | (T.TranslationPart()).Coord(DX,DY,DZ); | |
dde68833 | 304 | if (!IsOpenXmin()) newb.Xmin += DX; |
305 | if (!IsOpenXmax()) newb.Xmax += DX; | |
306 | if (!IsOpenYmin()) newb.Ymin += DY; | |
307 | if (!IsOpenYmax()) newb.Ymax += DY; | |
308 | if (!IsOpenZmin()) newb.Zmin += DZ; | |
309 | if (!IsOpenZmax()) newb.Zmax += DZ; | |
7fd59977 | 310 | } |
311 | else { | |
312 | gp_Pnt P[8]; | |
313 | Standard_Boolean Vertex[8]; | |
314 | Standard_Integer i; | |
315 | for (i=0;i<8;i++) Vertex[i] = Standard_True; | |
316 | gp_Dir D[6]; | |
317 | // Standard_Integer vertices = 0; | |
318 | Standard_Integer directions = 0; | |
319 | ||
dde68833 | 320 | if (IsOpenXmin()) |
321 | { | |
7fd59977 | 322 | directions++; |
323 | D[directions-1].SetCoord(-1., 0., 0.); | |
324 | Vertex[0] = Vertex[2] = Vertex[4] = Vertex[6] = Standard_False; | |
325 | } | |
dde68833 | 326 | if (IsOpenXmax()) |
327 | { | |
7fd59977 | 328 | directions++; |
329 | D[directions-1].SetCoord( 1., 0., 0.); | |
330 | Vertex[1] = Vertex[3] = Vertex[5] = Vertex[7] = Standard_False; | |
331 | } | |
dde68833 | 332 | if (IsOpenYmin()) |
333 | { | |
7fd59977 | 334 | directions++; |
335 | D[directions-1].SetCoord( 0.,-1., 0.); | |
336 | Vertex[0] = Vertex[1] = Vertex[4] = Vertex[5] = Standard_False; | |
337 | } | |
dde68833 | 338 | if (IsOpenYmax()) |
339 | { | |
7fd59977 | 340 | directions++; |
341 | D[directions-1].SetCoord( 0., 1., 0.); | |
342 | Vertex[2] = Vertex[3] = Vertex[6] = Vertex[7] = Standard_False; | |
343 | } | |
dde68833 | 344 | if (IsOpenZmin()) |
345 | { | |
7fd59977 | 346 | directions++; |
347 | D[directions-1].SetCoord( 0., 0.,-1.); | |
348 | Vertex[0] = Vertex[1] = Vertex[2] = Vertex[3] = Standard_False; | |
349 | } | |
dde68833 | 350 | if (IsOpenZmax()) |
351 | { | |
7fd59977 | 352 | directions++; |
353 | D[directions-1].SetCoord( 0., 0., 1.); | |
354 | Vertex[4] = Vertex[5] = Vertex[6] = Vertex[7] = Standard_False; | |
355 | } | |
356 | ||
357 | newb.SetVoid(); | |
358 | for (i=0;i<directions;i++) { | |
359 | D[i].Transform(T); | |
360 | newb.Add(D[i]); | |
361 | } | |
362 | P[0].SetCoord(Xmin,Ymin,Zmin); | |
363 | P[1].SetCoord(Xmax,Ymin,Zmin); | |
364 | P[2].SetCoord(Xmin,Ymax,Zmin); | |
365 | P[3].SetCoord(Xmax,Ymax,Zmin); | |
366 | P[4].SetCoord(Xmin,Ymin,Zmax); | |
367 | P[5].SetCoord(Xmax,Ymin,Zmax); | |
368 | P[6].SetCoord(Xmin,Ymax,Zmax); | |
369 | P[7].SetCoord(Xmax,Ymax,Zmax); | |
370 | for (i=0;i<8;i++) { | |
371 | if (Vertex[i]) { | |
372 | P[i].Transform(T); | |
373 | newb.Add(P[i]); | |
374 | } | |
375 | } | |
376 | newb.Gap=Gap; | |
377 | } | |
378 | return newb; | |
379 | } | |
380 | ||
381 | //======================================================================= | |
382 | //function : Add | |
383 | //purpose : | |
384 | //======================================================================= | |
385 | ||
386 | void Bnd_Box::Add (const Bnd_Box& Other) | |
387 | { | |
388 | if (IsWhole()) return; | |
389 | else if (Other.IsVoid()) return; | |
390 | else if (Other.IsWhole()) SetWhole(); | |
391 | else if (IsVoid()) (*this) = Other; | |
392 | else | |
393 | { | |
394 | if ( ! IsOpenXmin() ) | |
395 | { | |
396 | if (Other.IsOpenXmin()) OpenXmin(); | |
397 | else if (Xmin > Other.Xmin) Xmin = Other.Xmin; | |
398 | } | |
399 | if ( ! IsOpenXmax() ) | |
400 | { | |
401 | if (Other.IsOpenXmax()) OpenXmax(); | |
402 | else if (Xmax < Other.Xmax) Xmax = Other.Xmax; | |
403 | } | |
404 | if ( ! IsOpenYmin() ) | |
405 | { | |
406 | if (Other.IsOpenYmin()) OpenYmin(); | |
407 | else if (Ymin > Other.Ymin) Ymin = Other.Ymin; | |
408 | } | |
409 | if ( ! IsOpenYmax() ) | |
410 | { | |
411 | if (Other.IsOpenYmax()) OpenYmax(); | |
412 | else if (Ymax < Other.Ymax) Ymax = Other.Ymax; | |
413 | } | |
414 | if ( ! IsOpenZmin() ) | |
415 | { | |
416 | if (Other.IsOpenZmin()) OpenZmin(); | |
417 | else if (Zmin > Other.Zmin) Zmin = Other.Zmin; | |
418 | } | |
419 | if ( ! IsOpenZmax() ) | |
420 | { | |
421 | if (Other.IsOpenZmax()) OpenZmax(); | |
422 | else if (Zmax < Other.Zmax) Zmax = Other.Zmax; | |
423 | } | |
424 | Gap = Max (Gap, Other.Gap); | |
425 | } | |
426 | } | |
427 | ||
428 | //======================================================================= | |
429 | //function : Add | |
430 | //purpose : | |
431 | //======================================================================= | |
432 | ||
433 | void Bnd_Box::Add (const gp_Pnt& P) | |
434 | { | |
435 | Standard_Real X,Y,Z; | |
436 | P.Coord(X,Y,Z); | |
437 | Update(X,Y,Z); | |
438 | } | |
439 | ||
440 | //======================================================================= | |
441 | //function : Add | |
442 | //purpose : | |
443 | //======================================================================= | |
444 | ||
445 | void Bnd_Box::Add (const gp_Pnt& P, const gp_Dir& D) | |
446 | { | |
447 | Add(P); | |
448 | Add(D); | |
449 | } | |
450 | ||
451 | ||
452 | //======================================================================= | |
453 | //function : Add | |
454 | //purpose : | |
455 | //======================================================================= | |
456 | ||
457 | void Bnd_Box::Add (const gp_Dir& D) | |
458 | { | |
459 | Standard_Real DX,DY,DZ; | |
460 | D.Coord(DX,DY,DZ); | |
44d9ae89 A |
461 | |
462 | if (DX < -RealEpsilon()) | |
463 | OpenXmin(); | |
464 | else if (DX > RealEpsilon()) | |
465 | OpenXmax(); | |
466 | ||
467 | if (DY < -RealEpsilon()) | |
468 | OpenYmin(); | |
469 | else if (DY > RealEpsilon()) | |
470 | OpenYmax(); | |
471 | ||
472 | if (DZ < -RealEpsilon()) | |
473 | OpenZmin(); | |
474 | else if (DZ > RealEpsilon()) | |
475 | OpenZmax(); | |
7fd59977 | 476 | } |
477 | ||
478 | //======================================================================= | |
479 | //function : IsOut | |
480 | //purpose : | |
481 | //======================================================================= | |
482 | ||
483 | Standard_Boolean Bnd_Box::IsOut (const gp_Pnt& P) const | |
484 | { | |
485 | if (IsWhole()) return Standard_False; | |
486 | else if (IsVoid()) return Standard_True; | |
487 | else { | |
488 | Standard_Real X,Y,Z; | |
489 | P.Coord(X,Y,Z); | |
dde68833 | 490 | if (!IsOpenXmin() && (X < (Xmin-Gap))) return Standard_True; |
491 | else if (!IsOpenXmax() && (X > (Xmax+Gap))) return Standard_True; | |
492 | else if (!IsOpenYmin() && (Y < (Ymin-Gap))) return Standard_True; | |
493 | else if (!IsOpenYmax() && (Y > (Ymax+Gap))) return Standard_True; | |
494 | else if (!IsOpenZmin() && (Z < (Zmin-Gap))) return Standard_True; | |
495 | else if (!IsOpenZmax() && (Z > (Zmax+Gap))) return Standard_True; | |
7fd59977 | 496 | else return Standard_False; |
497 | } | |
498 | } | |
499 | ||
500 | ||
501 | //======================================================================= | |
502 | //function : IsOut | |
503 | //purpose : | |
504 | //======================================================================= | |
505 | ||
506 | Standard_Boolean Bnd_Box::IsOut (const gp_Pln& P) const | |
507 | { | |
508 | if (IsWhole()) return Standard_False; | |
509 | else if (IsVoid()) return Standard_True; | |
510 | else { | |
511 | Standard_Real A,B,C,D; | |
512 | P.Coefficients (A, B ,C ,D); | |
513 | Standard_Real d = A * (Xmin-Gap) + B * (Ymin-Gap) + C * (Zmin-Gap) + D; | |
514 | // Standard_Boolean plus = d > 0; | |
515 | Standard_Integer plus = d > 0; | |
516 | if (plus != ((A*(Xmin-Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0)) | |
517 | return Standard_False; | |
518 | if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0)) | |
519 | return Standard_False; | |
520 | if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0)) | |
521 | return Standard_False; | |
522 | if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmin-Gap) + D) > 0)) | |
523 | return Standard_False; | |
524 | if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0)) | |
525 | return Standard_False; | |
526 | if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0)) | |
527 | return Standard_False; | |
528 | if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0)) | |
529 | return Standard_False; | |
530 | else return Standard_True; | |
531 | } | |
532 | } | |
533 | ||
534 | //======================================================================= | |
535 | //function : IsOut | |
536 | //purpose : | |
537 | //======================================================================= | |
538 | ||
539 | Standard_Boolean Bnd_Box::IsOut (const gp_Lin& L) const | |
540 | { | |
541 | if (IsWhole()) return Standard_False; | |
542 | else if (IsVoid()) return Standard_True; | |
543 | else { | |
544 | Standard_Real xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin, zmax; | |
545 | Standard_Real parmin, parmax, par1, par2; | |
546 | Standard_Boolean xToSet, yToSet; | |
547 | Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax; | |
548 | Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax); | |
549 | ||
550 | if (Abs(L.Direction().XYZ().X())>0.) { | |
551 | par1=(myXmin-L.Location().XYZ().X())/L.Direction().XYZ().X(); | |
552 | par2=(myXmax-L.Location().XYZ().X())/L.Direction().XYZ().X(); | |
553 | parmin=Min(par1, par2); | |
554 | parmax=Max(par1, par2); | |
555 | xToSet=Standard_True; | |
556 | } | |
557 | else { | |
558 | if (L.Location().XYZ().X()<myXmin || myXmax<L.Location().XYZ().X()) { | |
559 | return Standard_True; | |
560 | } | |
561 | xmin=L.Location().XYZ().X(); | |
562 | xmax=L.Location().XYZ().X(); | |
563 | parmin=-Bnd_Precision_Infinite; | |
564 | parmax=Bnd_Precision_Infinite; | |
565 | xToSet=Standard_False; | |
566 | } | |
567 | ||
568 | if (Abs(L.Direction().XYZ().Y())>0.) { | |
569 | par1=(myYmin-L.Location().XYZ().Y())/L.Direction().XYZ().Y(); | |
570 | par2=(myYmax-L.Location().XYZ().Y())/L.Direction().XYZ().Y(); | |
571 | //=================DET change 06/03/01==================== | |
572 | if(parmax < Min(par1,par2) || parmin > Max(par1,par2)) | |
573 | return Standard_True; | |
574 | //======================================================== | |
575 | parmin=Max(parmin, Min(par1,par2)); | |
576 | parmax=Min(parmax, Max(par1,par2)); | |
577 | yToSet=Standard_True; | |
578 | } | |
579 | else { | |
580 | if (L.Location().XYZ().Y()<myYmin || myYmax<L.Location().XYZ().Y()) { | |
581 | return Standard_True; | |
582 | } | |
583 | ymin=L.Location().XYZ().Y(); | |
584 | ymax=L.Location().XYZ().Y(); | |
585 | yToSet=Standard_False; | |
586 | } | |
587 | ||
588 | if (Abs(L.Direction().XYZ().Z())>0.) { | |
589 | par1=(myZmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z(); | |
590 | par2=(myZmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z(); | |
591 | //=================DET change 06/03/01==================== | |
592 | if(parmax < Min(par1,par2) || parmin > Max(par1,par2)) | |
593 | return Standard_True; | |
594 | //======================================================== | |
595 | parmin=Max(parmin, Min(par1,par2)); | |
596 | parmax=Min(parmax, Max(par1,par2)); | |
597 | par1=L.Location().XYZ().Z()+parmin*L.Direction().XYZ().Z(); | |
598 | par2=L.Location().XYZ().Z()+parmax*L.Direction().XYZ().Z(); | |
599 | zmin=Min(par1, par2); | |
600 | zmax=Max(par1, par2); | |
601 | } | |
602 | else { | |
603 | if (L.Location().XYZ().Z()<myZmin || myZmax<L.Location().XYZ().Z()) | |
604 | return Standard_True; | |
605 | zmin=L.Location().XYZ().Z(); | |
606 | zmax=L.Location().XYZ().Z(); | |
607 | } | |
608 | if (zmax<myZmin || myZmax<zmin) return Standard_True; | |
609 | ||
610 | if (xToSet) { | |
611 | par1=L.Location().XYZ().X()+parmin*L.Direction().XYZ().X(); | |
612 | par2=L.Location().XYZ().X()+parmax*L.Direction().XYZ().X(); | |
613 | xmin=Min(par1, par2); | |
614 | xmax=Max(par1, par2); | |
615 | } | |
616 | if (xmax<myXmin || myXmax<xmin) return Standard_True; | |
617 | ||
618 | if (yToSet) { | |
619 | par1=L.Location().XYZ().Y()+parmin*L.Direction().XYZ().Y(); | |
620 | par2=L.Location().XYZ().Y()+parmax*L.Direction().XYZ().Y(); | |
621 | ymin=Min(par1, par2); | |
622 | ymax=Max(par1, par2); | |
623 | } | |
624 | if (ymax<myYmin || myYmax<ymin) return Standard_True; | |
625 | } | |
626 | return Standard_False; | |
627 | } | |
628 | ||
629 | //======================================================================= | |
630 | //function : IsOut | |
631 | //purpose : | |
632 | //======================================================================= | |
633 | ||
634 | Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other) const | |
aa396061 P |
635 | { |
636 | //modified by NIZNHY-PKV Fri Jul 08 11:03:43 2011f | |
637 | if (!Flags && !Other.Flags) { | |
638 | Standard_Boolean bRet; | |
639 | Standard_Real delta; | |
640 | // | |
641 | delta = Other.Gap + Gap; | |
642 | bRet=((Xmin - Other.Xmax > delta) || | |
643 | (Other.Xmin - Xmax > delta) || | |
644 | (Ymin - Other.Ymax > delta) || | |
645 | (Other.Ymin - Ymax > delta) || | |
646 | (Zmin - Other.Zmax > delta) || | |
647 | (Other.Zmin - Zmax > delta)); | |
648 | return bRet; | |
649 | } | |
650 | //modified by NIZNHY-PKV Fri Jul 08 11:03:46 2011t | |
7fd59977 | 651 | if (IsVoid()) return Standard_True; |
652 | if (Other.IsVoid()) return Standard_True; | |
653 | if (IsWhole()) return Standard_False; | |
654 | if (Other.IsWhole()) return Standard_False; | |
655 | ||
656 | Standard_Real delta = Other.Gap + Gap; | |
657 | ||
dde68833 | 658 | if (!IsOpenXmin() && !Other.IsOpenXmax()) |
7fd59977 | 659 | if (Xmin - Other.Xmax > delta) return Standard_True; |
dde68833 | 660 | if (!IsOpenXmax() && !Other.IsOpenXmin()) |
7fd59977 | 661 | if (Other.Xmin - Xmax > delta) return Standard_True; |
662 | ||
dde68833 | 663 | if (!IsOpenYmin() && !Other.IsOpenYmax()) |
7fd59977 | 664 | if (Ymin - Other.Ymax > delta) return Standard_True; |
dde68833 | 665 | if (!IsOpenYmax() && !Other.IsOpenYmin()) |
7fd59977 | 666 | if (Other.Ymin - Ymax > delta) return Standard_True; |
667 | ||
dde68833 | 668 | if (!IsOpenZmin() && !Other.IsOpenZmax()) |
7fd59977 | 669 | if (Zmin - Other.Zmax > delta) return Standard_True; |
dde68833 | 670 | if (!IsOpenZmax() && !Other.IsOpenZmin()) |
7fd59977 | 671 | if (Other.Zmin - Zmax > delta) return Standard_True; |
672 | ||
673 | return Standard_False; | |
674 | } | |
675 | ||
676 | //======================================================================= | |
677 | //function : IsOut | |
678 | //purpose : | |
679 | //======================================================================= | |
680 | ||
681 | Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other, | |
682 | const gp_Trsf& T) const | |
683 | { | |
684 | return IsOut(Other.Transformed(T)); | |
685 | } | |
686 | ||
687 | //======================================================================= | |
688 | //function : IsOut | |
689 | //purpose : | |
690 | //======================================================================= | |
691 | ||
692 | Standard_Boolean Bnd_Box::IsOut (const gp_Trsf& T1, | |
693 | const Bnd_Box& Other, | |
694 | const gp_Trsf& T2) const | |
695 | { | |
696 | return Transformed(T1).IsOut(Other.Transformed(T2)); | |
697 | } | |
698 | ||
699 | ||
700 | //======================================================================= | |
0ebaa4db | 701 | //function : IsSegmentOut |
7fd59977 | 702 | //purpose : |
703 | //======================================================================= | |
704 | ||
705 | static Standard_Boolean IsSegmentOut(Standard_Real x1,Standard_Real y1, | |
706 | Standard_Real x2,Standard_Real y2, | |
707 | Standard_Real xs1,Standard_Real ys1, | |
708 | Standard_Real xs2,Standard_Real ys2) | |
709 | { | |
710 | Standard_Real eps = RealSmall(); | |
711 | Standard_Real xsmin = Min (xs1, xs2); | |
712 | Standard_Real xsmax = Max (xs1, xs2); | |
713 | Standard_Real ysmin = Min (ys1, ys2); | |
714 | Standard_Real ysmax = Max (ys1, ys2); | |
715 | ||
716 | if (ysmax-ysmin < eps && (y1-ys1 < eps && ys1-y2 < eps) && | |
0ebaa4db | 717 | ((xsmin-x1 < eps && x1-xsmax < eps) || |
718 | (xsmin-x2 < eps && x2-xsmax < eps) || | |
719 | (x1-xs1 < eps && xs1-x2 < eps))) | |
7fd59977 | 720 | return Standard_False; |
721 | if (xsmax-xsmin < eps && (x1-xs1 < eps && xs1-x2 < eps) && | |
0ebaa4db | 722 | ((ysmin-y1 < eps && y1-ysmax < eps) || |
723 | (ysmin-y2 < eps && y2-ysmax < eps) || | |
724 | (y1-ys1 < eps && ys1-y2 < eps))) | |
7fd59977 | 725 | return Standard_False; |
726 | ||
727 | if ((xs1 < x1 && xs2 < x1) || (xs1 > x2 && xs2 > x2) || | |
728 | (ys1 < y1 && ys2 < y1) || (ys1 > y2 && ys2 > y2) ) | |
729 | return Standard_True; | |
730 | ||
731 | if (Abs(xs2-xs1) > eps) | |
732 | { | |
733 | Standard_Real ya = ( Min(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1; | |
734 | Standard_Real yb = ( Max(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1; | |
735 | if ( (ya < y1 && yb < y1) || (ya > y2 && yb > y2) ) return Standard_True; | |
736 | } | |
737 | else if (Abs(ys2-ys1) > eps) | |
738 | { | |
739 | Standard_Real xa = ( Min(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1; | |
740 | Standard_Real xb = ( Max(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1; | |
741 | if ( (xa < x1 && xb < x1) || (xa > x2 && xb > x2) ) return Standard_True; | |
742 | } | |
743 | else | |
744 | return Standard_True; | |
745 | ||
746 | return Standard_False; | |
747 | } | |
748 | ||
749 | Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const | |
750 | { | |
751 | ||
752 | if (IsWhole()) return Standard_False; | |
753 | else if (IsVoid()) return Standard_True; | |
754 | ||
755 | Standard_Real eps = RealSmall(); | |
756 | Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax; | |
757 | Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax); | |
758 | ||
759 | if(Abs(D.X()) < eps && Abs(D.Y()) < eps) | |
760 | return IsSegmentOut(myXmin, myYmin, myXmax, myYmax, P1.X(), P1.Y(), P2.X(), P2.Y()); | |
761 | ||
762 | if(Abs(D.X()) < eps && Abs(D.Z()) < eps) | |
763 | return IsSegmentOut(myXmin, myZmin, myXmax, myZmax, P1.X(), P1.Z(), P2.X(), P2.Z()); | |
764 | ||
765 | if(Abs(D.Y()) < eps && Abs(D.Z()) < eps) | |
766 | return IsSegmentOut(myYmin, myZmin, myYmax, myZmax, P1.Y(), P1.Z(), P2.Y(), P2.Z()); | |
767 | ||
768 | if(Abs(D.X()) < eps) | |
769 | { | |
770 | if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax, | |
771 | P1.X(),(myYmin-P1.Y())*D.Z()/D.Y()+P1.Z(), | |
772 | P2.X(),(myYmin-P2.Y())*D.Z()/D.Y()+P2.Z())) | |
773 | return Standard_False; | |
774 | ||
775 | if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax, | |
776 | P1.X(),(myYmax-P1.Y())*D.Z()/D.Y()+P1.Z(), | |
777 | P2.X(),(myYmax-P2.Y())*D.Z()/D.Y()+P2.Z())) | |
778 | return Standard_False; | |
779 | ||
780 | if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax, | |
781 | P1.X(),(myZmin-P1.Z())*D.Y()/D.Z()+P1.Y(), | |
782 | P2.X(),(myZmin-P2.Z())*D.Y()/D.Z()+P2.Y())) | |
783 | return Standard_False; | |
784 | ||
785 | if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax, | |
786 | P1.X(),(myZmax-P1.Z())*D.Y()/D.Z()+P1.Y(), | |
787 | P2.X(),(myZmax-P2.Z())*D.Y()/D.Z()+P2.Y())) | |
788 | return Standard_False; | |
789 | ||
790 | return Standard_True; | |
791 | }//if(D.X() == 0) | |
792 | ||
793 | if(Abs(D.Y()) < eps) | |
794 | { | |
795 | if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax, | |
796 | P1.Y(),(myXmin-P1.X())*D.Z()/D.X()+P1.Z(), | |
797 | P2.Y(),(myXmin-P2.X())*D.Z()/D.X()+P2.Z())) | |
798 | return Standard_False; | |
799 | ||
800 | if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax, | |
801 | P1.Y(),(myXmax-P1.X())*D.Z()/D.X()+P1.Z(), | |
802 | P2.Y(),(myXmax-P2.X())*D.Z()/D.X()+P2.Z())) | |
803 | return Standard_False; | |
804 | ||
805 | if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax, | |
806 | P1.Y(),(myZmin-P1.Z())*D.X()/D.Z()+P1.X(), | |
807 | P2.Y(),(myZmin-P2.Z())*D.X()/D.Z()+P2.X())) | |
808 | return Standard_False; | |
809 | ||
810 | if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax, | |
811 | P1.Y(),(myZmax-P1.Z())*D.X()/D.Z()+P1.X(), | |
812 | P2.Y(),(myZmax-P2.Z())*D.X()/D.Z()+P2.X())) | |
813 | return Standard_False; | |
814 | ||
815 | return Standard_True; | |
816 | }//if(D.Y() == 0) | |
817 | ||
818 | if(Abs(D.Z()) < eps) | |
819 | { | |
820 | if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax, | |
821 | P1.Z(),(myYmax-P1.Y())*D.X()/D.Y()+P1.X(), | |
822 | P2.Z(),(myYmax-P2.Y())*D.X()/D.Y()+P2.X())) | |
823 | return Standard_False; | |
824 | ||
825 | if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax, | |
826 | P1.Z(),(myYmin-P1.Y())*D.X()/D.Y()+P1.X(), | |
827 | P2.Z(),(myYmin-P2.Y())*D.X()/D.Y()+P2.X())) | |
828 | return Standard_False; | |
829 | ||
830 | if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax, | |
831 | P1.Z(),(myXmax-P1.X())*D.Y()/D.X()+P1.Y(), | |
832 | P2.Z(),(myXmax-P2.X())*D.Y()/D.X()+P2.Y())) | |
833 | return Standard_False; | |
834 | ||
835 | if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax, | |
836 | P1.Z(),(myXmin-P1.X())*D.Y()/D.X()+P1.Y(), | |
837 | P2.Z(),(myXmin-P2.X())*D.Y()/D.X()+P2.Y())) | |
838 | return Standard_False; | |
839 | ||
840 | return Standard_True; | |
841 | }//if(D.Z() == 0) | |
842 | ||
843 | if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax, | |
844 | (myYmin - P1.Y())/D.Y()*D.X() + P1.X(), | |
845 | (myYmin - P1.Y())/D.Y()*D.Z() + P1.Z(), | |
846 | (myYmin - P2.Y())/D.Y()*D.X() + P2.X(), | |
847 | (myYmin - P2.Y())/D.Y()*D.Z() + P2.Z())) | |
848 | return Standard_False; | |
849 | ||
850 | if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax, | |
851 | (myYmax - P1.Y())/D.Y()*D.X() + P1.X(), | |
852 | (myYmax - P1.Y())/D.Y()*D.Z() + P1.Z(), | |
853 | (myYmax - P2.Y())/D.Y()*D.X() + P2.X(), | |
854 | (myYmax - P2.Y())/D.Y()*D.Z() + P2.Z())) | |
855 | return Standard_False; | |
856 | ||
857 | if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax, | |
858 | (myZmin - P1.Z())/D.Z()*D.X() + P1.X(), | |
859 | (myZmin - P1.Z())/D.Z()*D.Y() + P1.Y(), | |
860 | (myZmin - P2.Z())/D.Z()*D.X() + P2.X(), | |
861 | (myZmin - P2.Z())/D.Z()*D.Y() + P2.Y())) | |
862 | return Standard_False; | |
863 | ||
864 | if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax, | |
865 | (myZmax - P1.Z())/D.Z()*D.X() + P1.X(), | |
866 | (myZmax - P1.Z())/D.Z()*D.Y() + P1.Y(), | |
867 | (myZmax - P2.Z())/D.Z()*D.X() + P2.X(), | |
868 | (myZmax - P2.Z())/D.Z()*D.Y() + P2.Y())) | |
869 | return Standard_False; | |
870 | ||
871 | if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax, | |
872 | (myXmin - P1.X())/D.X()*D.Z() + P1.Z(), | |
873 | (myXmin - P1.X())/D.X()*D.Y() + P1.Y(), | |
874 | (myXmin - P2.X())/D.X()*D.Z() + P2.Z(), | |
875 | (myXmin - P2.X())/D.X()*D.Y() + P2.Y())) | |
876 | return Standard_False; | |
877 | ||
878 | if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax, | |
879 | (myXmax - P1.X())/D.X()*D.Z() + P1.Z(), | |
880 | (myXmax - P1.X())/D.X()*D.Y() + P1.Y(), | |
881 | (myXmax - P2.X())/D.X()*D.Z() + P2.Z(), | |
882 | (myXmax - P2.X())/D.X()*D.Y() + P2.Y())) | |
883 | return Standard_False; | |
884 | ||
885 | return Standard_True; | |
886 | ||
887 | } | |
888 | ||
889 | //======================================================================= | |
890 | //function : Distance | |
891 | //purpose : computes the minimum distance between two boxes | |
892 | //======================================================================= | |
893 | ||
894 | static Standard_Real DistMini2Box( const Standard_Real r1min, const Standard_Real r1max, const Standard_Real r2min, const Standard_Real r2max) | |
895 | { Standard_Real r1, r2; | |
896 | ||
897 | r1 = Square(r1min - r2max); | |
898 | r2 = Square(r1max - r2min); | |
899 | return (Min( r1, r2 )); | |
900 | } | |
901 | ||
902 | ||
903 | ||
904 | Standard_Real Bnd_Box::Distance(const Bnd_Box& Other) const | |
905 | { Standard_Real xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1; | |
906 | Standard_Real xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2; | |
907 | Standard_Real dist_x, dist_y, dist_z, dist_t; | |
908 | ||
909 | Get( xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1); | |
910 | Other.Get( xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2); | |
911 | ||
912 | if ( ((xminB1<= xminB2)&&( xminB2 <= xmaxB1)) || ((xminB2<= xminB1)&&( xminB1 <= xmaxB2)) ) | |
913 | { dist_x=0; } | |
914 | else { dist_x= DistMini2Box(xminB1, xmaxB1, xminB2, xmaxB2);} | |
915 | if ( ((yminB1<= yminB2)&&( yminB2 <= ymaxB1)) || ((yminB2<= yminB1)&&( yminB1 <= ymaxB2)) ) | |
916 | { dist_y=0; } | |
917 | else { dist_y= DistMini2Box(yminB1, ymaxB1, yminB2, ymaxB2);} | |
918 | if ( ((zminB1<= zminB2)&&( zminB2 <= zmaxB1)) || ((zminB2<= zminB1)&&( zminB1 <= zmaxB2)) ) | |
919 | { dist_z=0; } | |
920 | else { dist_z= DistMini2Box(zminB1, zmaxB1, zminB2, zmaxB2);} | |
921 | dist_t = dist_x+ dist_y+ dist_z; | |
922 | return( Sqrt ( dist_t)); | |
923 | } | |
924 | ||
925 | //======================================================================= | |
926 | //function : Dump | |
927 | //purpose : | |
928 | //======================================================================= | |
929 | ||
930 | void Bnd_Box::Dump () const | |
931 | { | |
932 | cout << "Box3D : "; | |
933 | if (IsVoid()) cout << "Void"; | |
934 | else if (IsWhole()) cout << "Whole"; | |
935 | else { | |
936 | cout << "\n Xmin : "; | |
937 | if (IsOpenXmin()) cout << "Infinite"; | |
938 | else cout << Xmin; | |
939 | cout << "\n Xmax : "; | |
940 | if (IsOpenXmax()) cout << "Infinite"; | |
941 | else cout << Xmax; | |
942 | cout << "\n Ymin : "; | |
943 | if (IsOpenYmin()) cout << "Infinite"; | |
944 | else cout << Ymin; | |
945 | cout << "\n Ymax : "; | |
946 | if (IsOpenYmax()) cout << "Infinite"; | |
947 | else cout << Ymax; | |
948 | cout << "\n Zmin : "; | |
949 | if (IsOpenZmin()) cout << "Infinite"; | |
950 | else cout << Zmin; | |
951 | cout << "\n Zmax : "; | |
952 | if (IsOpenZmax()) cout << "Infinite"; | |
953 | else cout << Zmax; | |
954 | } | |
955 | cout << "\n Gap : " << Gap; | |
956 | cout << "\n"; | |
957 | } |