d443d3cb90e79cfc56a7c218f569f5e538e6f5a9
[occt.git] / src / Bnd / Bnd_Box2d.cxx
1 // Created on: 1991-10-30
2 // Created by: Modelisation
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <Bnd_Box2d.ixx>
23 #include <Standard_Stream.hxx>
24 #include <gp.hxx>
25 //-- #include <Precision.hxx> Precision::Infinite() -> 1e+100
26
27 //=======================================================================
28 //function : Update
29 //purpose  : 
30 //=======================================================================
31
32 void Bnd_Box2d::Update (const Standard_Real x, const Standard_Real y, 
33                         const Standard_Real X, const Standard_Real Y)
34 {
35   if (Flags & VoidMask) {
36     Xmin = x;
37     Ymin = y;
38     Xmax = X;
39     Ymax = Y;
40     Flags &= ~VoidMask;
41   }
42   else {
43     if (!(Flags & XminMask) && (x < Xmin)) Xmin = x;
44     if (!(Flags & XmaxMask) && (X > Xmax)) Xmax = X;
45     if (!(Flags & YminMask) && (y < Ymin)) Ymin = y;
46     if (!(Flags & YmaxMask) && (Y > Ymax)) Ymax = Y;
47   }
48 }
49
50 //=======================================================================
51 //function : Update
52 //purpose  : 
53 //=======================================================================
54
55 void Bnd_Box2d::Update (const Standard_Real X, const Standard_Real Y)
56 {
57   if (Flags & VoidMask) {
58     Xmin = X;
59     Ymin = Y;
60     Xmax = X;
61     Ymax = Y;
62     Flags &= ~VoidMask;
63   }
64   else {
65     if      (!(Flags & XminMask) && (X < Xmin)) Xmin = X;
66     else if (!(Flags & XmaxMask) && (X > Xmax)) Xmax = X;
67     if      (!(Flags & YminMask) && (Y < Ymin)) Ymin = Y;
68     else if (!(Flags & YmaxMask) && (Y > Ymax)) Ymax = Y;
69   }
70 }
71
72 //=======================================================================
73 //function : Get
74 //purpose  : 
75 //=======================================================================
76
77 void Bnd_Box2d::Get (Standard_Real& x, Standard_Real& y,
78                      Standard_Real& Xm, Standard_Real& Ym) const
79 {
80   if(Flags & VoidMask)
81     Standard_ConstructionError::Raise("Bnd_Box is void");
82   Standard_Real pinf = 1e+100; //-- Precision::Infinite();
83   if (Flags & XminMask) x = -pinf;
84   else                  x =  Xmin-Gap;
85   if (Flags & XmaxMask) Xm =  pinf;
86   else                  Xm =  Xmax+Gap;
87   if (Flags & YminMask) y = -pinf;
88   else                  y =  Ymin-Gap;
89   if (Flags & YmaxMask) Ym =  pinf;
90   else                  Ym =  Ymax+Gap;
91 }
92
93 //=======================================================================
94 //function : Transformed
95 //purpose  : 
96 //=======================================================================
97
98 Bnd_Box2d Bnd_Box2d::Transformed (const gp_Trsf2d& T) const
99 {
100   gp_TrsfForm F = T.Form();
101   Bnd_Box2d newb(*this);
102   if ( IsVoid() ) return newb;
103
104   if      (F == gp_Identity) {}
105   else if (F == gp_Translation) {
106     Standard_Real DX,DY;
107     (T.TranslationPart()).Coord(DX,DY);
108     if (!(Flags & XminMask))  newb.Xmin += DX;
109     if (!(Flags & XmaxMask))  newb.Xmax += DX;
110     if (!(Flags & YminMask))  newb.Ymin += DY;
111     if (!(Flags & YmaxMask))  newb.Ymax += DY;
112   }
113   else {
114     gp_Pnt2d P[4];
115     Standard_Boolean Vertex[4];
116     Standard_Integer i;
117     Vertex[0] = Standard_True;
118     Vertex[1] = Standard_True;
119     Vertex[2] = Standard_True;
120     Vertex[3] = Standard_True;
121     gp_Dir2d D[6];
122 //    Standard_Integer vertices = 0;
123     Standard_Integer directions = 0;
124
125     if (Flags & XminMask) {
126       D[directions].SetCoord(-1., 0.);
127       directions++;
128       Vertex[0] = Vertex[2] = Standard_False;
129     }
130     if (Flags & XmaxMask) {
131       D[directions].SetCoord( 1., 0.);
132       directions++;
133       Vertex[1] = Vertex[3] = Standard_False;
134     }
135     if (Flags & YminMask) {
136       D[directions].SetCoord( 0.,-1.);
137       directions++;
138       Vertex[0] = Vertex[1] = Standard_False;
139     }
140     if (Flags & YmaxMask) {
141       D[directions].SetCoord( 0., 1.);
142       directions++;
143       Vertex[2] = Vertex[3] = Standard_False;
144     }
145
146     newb.SetVoid();
147
148     for (i = 0; i < directions; i++) {
149       D[i].Transform(T);
150       newb.Add(D[i]);
151     }
152     P[0].SetCoord(Xmin,Ymin);
153     P[1].SetCoord(Xmax,Ymin);
154     P[2].SetCoord(Xmin,Ymax);
155     P[3].SetCoord(Xmax,Ymax);
156     if (Vertex[0]) {
157       P[0].Transform(T);
158       newb.Add(P[0]);
159     }
160     if (Vertex[1]) {
161       P[1].Transform(T);
162       newb.Add(P[1]);
163     }
164     if (Vertex[2]) {
165       P[2].Transform(T);
166       newb.Add(P[2]);
167     }
168     if (Vertex[3]) {
169       P[3].Transform(T);
170       newb.Add(P[3]);
171     }
172     newb.Gap=Gap;
173   }
174   return newb;
175 }
176
177 //=======================================================================
178 //function : Add
179 //purpose  : 
180 //=======================================================================
181
182 void Bnd_Box2d::Add (const Bnd_Box2d& Other)
183 {
184   if (IsWhole()) return;
185   else if (Other.IsVoid()) return; 
186   else if (Other.IsWhole()) SetWhole();
187   else if (IsVoid()) (*this) = Other;
188   else
189   {
190     if ( ! IsOpenXmin() )
191     {
192       if (Other.IsOpenXmin()) OpenXmin();
193       else if (Xmin > Other.Xmin) Xmin = Other.Xmin;
194     }
195     if ( ! IsOpenXmax() )
196     {
197       if (Other.IsOpenXmax()) OpenXmax();
198       else if (Xmax < Other.Xmax) Xmax = Other.Xmax;
199     }
200     if ( ! IsOpenYmin() )
201     {
202       if (Other.IsOpenYmin()) OpenYmin();
203       else if (Ymin > Other.Ymin) Ymin = Other.Ymin;
204     }
205     if ( ! IsOpenYmax() )
206     {
207       if (Other.IsOpenYmax()) OpenYmax();
208       else if (Ymax < Other.Ymax) Ymax = Other.Ymax;
209     }
210     Gap = Max (Gap, Other.Gap);
211   }
212 }
213
214 //=======================================================================
215 //function : Add
216 //purpose  : 
217 //=======================================================================
218
219 void Bnd_Box2d::Add (const gp_Dir2d& D)
220 {
221   Standard_Real DX = D.X();
222   Standard_Real DY = D.Y();
223
224   if (DX < -RealEpsilon()) 
225     OpenXmin();
226   else if (DX > RealEpsilon()) 
227     OpenXmax();
228
229   if (DY < -RealEpsilon())
230     OpenYmin();
231   else if (DY > RealEpsilon())
232     OpenYmax();
233 }
234
235 //=======================================================================
236 //function : IsOut
237 //purpose  : 
238 //=======================================================================
239
240 Standard_Boolean Bnd_Box2d::IsOut (const gp_Pnt2d& P) const
241 {
242   if        (IsWhole())  return Standard_False;
243   else if   (IsVoid())   return Standard_True;
244   else {
245     Standard_Real X = P.X();
246     Standard_Real Y = P.Y();
247     if      (!(Flags & XminMask) && (X < (Xmin-Gap))) return Standard_True;
248     else if (!(Flags & XmaxMask) && (X > (Xmax+Gap))) return Standard_True;
249     else if (!(Flags & YminMask) && (Y < (Ymin-Gap))) return Standard_True;
250     else if (!(Flags & YmaxMask) && (Y > (Ymax+Gap))) return Standard_True;
251     else return Standard_False;
252   }
253 }
254
255 //=======================================================================
256 //function : IsOut
257 //purpose  : 
258 //=======================================================================
259
260 Standard_Boolean Bnd_Box2d::IsOut (const Bnd_Box2d& Other) const
261 {
262   if        (IsWhole())  return Standard_False;
263   else if   (IsVoid())   return Standard_True;
264   else if   (Other.IsWhole())  return Standard_False;
265   else if   (Other.IsVoid())   return Standard_True;
266   else {
267     Bnd_Box2d OtherBox2d = Other; // DownEqual
268     Standard_Real OXmin,OXmax,OYmin,OYmax;
269     OtherBox2d.Get(OXmin,OYmin,OXmax,OYmax);
270     if      (!(Flags & XminMask) && (OXmax < (Xmin-Gap))) return Standard_True;
271     else if (!(Flags & XmaxMask) && (OXmin > (Xmax+Gap))) return Standard_True;
272     else if (!(Flags & YminMask) && (OYmax < (Ymin-Gap))) return Standard_True;
273     else if (!(Flags & YmaxMask) && (OYmin > (Ymax+Gap))) return Standard_True;
274   }
275   return Standard_False;
276 }
277
278 //=======================================================================
279 //function : Dump
280 //purpose  : 
281 //=======================================================================
282
283 void Bnd_Box2d::Dump () const
284 {
285   cout << "Box2d : ";
286   if      (IsVoid())  cout << "Void";
287   else if (IsWhole()) cout << "Whole";
288   else {
289     cout << "\n Xmin : ";
290     if (IsOpenXmin()) cout << "Infinite";
291     else              cout << Xmin;
292     cout << "\n Xmax : ";
293     if (IsOpenXmax()) cout << "Infinite";
294     else              cout << Xmax;
295     cout << "\n Ymin : ";
296     if (IsOpenYmin()) cout << "Infinite";
297     else              cout << Ymin;
298     cout << "\n Ymax : ";
299     if (IsOpenYmax()) cout << "Infinite";
300     else              cout << Ymax;
301   }
302   cout << "\n Gap : " << Gap;
303   cout << "\n";
304 }