f06127f88fd6f08156449a4f80bdcf166891d503
[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-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public 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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Bnd_Box2d.ixx>
18 #include <Standard_Stream.hxx>
19 #include <gp.hxx>
20 //-- #include <Precision.hxx> Precision::Infinite() -> 1e+100
21
22 //=======================================================================
23 //function : Update
24 //purpose  : 
25 //=======================================================================
26
27 void Bnd_Box2d::Update (const Standard_Real x, const Standard_Real y, 
28                         const Standard_Real X, const Standard_Real Y)
29 {
30   if (Flags & VoidMask) {
31     Xmin = x;
32     Ymin = y;
33     Xmax = X;
34     Ymax = Y;
35     Flags &= ~VoidMask;
36   }
37   else {
38     if (!(Flags & XminMask) && (x < Xmin)) Xmin = x;
39     if (!(Flags & XmaxMask) && (X > Xmax)) Xmax = X;
40     if (!(Flags & YminMask) && (y < Ymin)) Ymin = y;
41     if (!(Flags & YmaxMask) && (Y > Ymax)) Ymax = Y;
42   }
43 }
44
45 //=======================================================================
46 //function : Update
47 //purpose  : 
48 //=======================================================================
49
50 void Bnd_Box2d::Update (const Standard_Real X, const Standard_Real Y)
51 {
52   if (Flags & VoidMask) {
53     Xmin = X;
54     Ymin = Y;
55     Xmax = X;
56     Ymax = Y;
57     Flags &= ~VoidMask;
58   }
59   else {
60     if      (!(Flags & XminMask) && (X < Xmin)) Xmin = X;
61     else if (!(Flags & XmaxMask) && (X > Xmax)) Xmax = X;
62     if      (!(Flags & YminMask) && (Y < Ymin)) Ymin = Y;
63     else if (!(Flags & YmaxMask) && (Y > Ymax)) Ymax = Y;
64   }
65 }
66
67 //=======================================================================
68 //function : Get
69 //purpose  : 
70 //=======================================================================
71
72 void Bnd_Box2d::Get (Standard_Real& x, Standard_Real& y,
73                      Standard_Real& Xm, Standard_Real& Ym) const
74 {
75   if(Flags & VoidMask)
76     Standard_ConstructionError::Raise("Bnd_Box is void");
77   Standard_Real pinf = 1e+100; //-- Precision::Infinite();
78   if (Flags & XminMask) x = -pinf;
79   else                  x =  Xmin-Gap;
80   if (Flags & XmaxMask) Xm =  pinf;
81   else                  Xm =  Xmax+Gap;
82   if (Flags & YminMask) y = -pinf;
83   else                  y =  Ymin-Gap;
84   if (Flags & YmaxMask) Ym =  pinf;
85   else                  Ym =  Ymax+Gap;
86 }
87
88 //=======================================================================
89 //function : Transformed
90 //purpose  : 
91 //=======================================================================
92
93 Bnd_Box2d Bnd_Box2d::Transformed (const gp_Trsf2d& T) const
94 {
95   gp_TrsfForm F = T.Form();
96   Bnd_Box2d newb(*this);
97   if ( IsVoid() ) return newb;
98
99   if      (F == gp_Identity) {}
100   else if (F == gp_Translation) {
101     Standard_Real DX,DY;
102     (T.TranslationPart()).Coord(DX,DY);
103     if (!(Flags & XminMask))  newb.Xmin += DX;
104     if (!(Flags & XmaxMask))  newb.Xmax += DX;
105     if (!(Flags & YminMask))  newb.Ymin += DY;
106     if (!(Flags & YmaxMask))  newb.Ymax += DY;
107   }
108   else {
109     gp_Pnt2d P[4];
110     Standard_Boolean Vertex[4];
111     Standard_Integer i;
112     Vertex[0] = Standard_True;
113     Vertex[1] = Standard_True;
114     Vertex[2] = Standard_True;
115     Vertex[3] = Standard_True;
116     gp_Dir2d D[6];
117 //    Standard_Integer vertices = 0;
118     Standard_Integer directions = 0;
119
120     if (Flags & XminMask) {
121       D[directions].SetCoord(-1., 0.);
122       directions++;
123       Vertex[0] = Vertex[2] = Standard_False;
124     }
125     if (Flags & XmaxMask) {
126       D[directions].SetCoord( 1., 0.);
127       directions++;
128       Vertex[1] = Vertex[3] = Standard_False;
129     }
130     if (Flags & YminMask) {
131       D[directions].SetCoord( 0.,-1.);
132       directions++;
133       Vertex[0] = Vertex[1] = Standard_False;
134     }
135     if (Flags & YmaxMask) {
136       D[directions].SetCoord( 0., 1.);
137       directions++;
138       Vertex[2] = Vertex[3] = Standard_False;
139     }
140
141     newb.SetVoid();
142
143     for (i = 0; i < directions; i++) {
144       D[i].Transform(T);
145       newb.Add(D[i]);
146     }
147     P[0].SetCoord(Xmin,Ymin);
148     P[1].SetCoord(Xmax,Ymin);
149     P[2].SetCoord(Xmin,Ymax);
150     P[3].SetCoord(Xmax,Ymax);
151     if (Vertex[0]) {
152       P[0].Transform(T);
153       newb.Add(P[0]);
154     }
155     if (Vertex[1]) {
156       P[1].Transform(T);
157       newb.Add(P[1]);
158     }
159     if (Vertex[2]) {
160       P[2].Transform(T);
161       newb.Add(P[2]);
162     }
163     if (Vertex[3]) {
164       P[3].Transform(T);
165       newb.Add(P[3]);
166     }
167     newb.Gap=Gap;
168   }
169   return newb;
170 }
171
172 //=======================================================================
173 //function : Add
174 //purpose  : 
175 //=======================================================================
176
177 void Bnd_Box2d::Add (const Bnd_Box2d& Other)
178 {
179   if (IsWhole()) return;
180   else if (Other.IsVoid()) return; 
181   else if (Other.IsWhole()) SetWhole();
182   else if (IsVoid()) (*this) = Other;
183   else
184   {
185     if ( ! IsOpenXmin() )
186     {
187       if (Other.IsOpenXmin()) OpenXmin();
188       else if (Xmin > Other.Xmin) Xmin = Other.Xmin;
189     }
190     if ( ! IsOpenXmax() )
191     {
192       if (Other.IsOpenXmax()) OpenXmax();
193       else if (Xmax < Other.Xmax) Xmax = Other.Xmax;
194     }
195     if ( ! IsOpenYmin() )
196     {
197       if (Other.IsOpenYmin()) OpenYmin();
198       else if (Ymin > Other.Ymin) Ymin = Other.Ymin;
199     }
200     if ( ! IsOpenYmax() )
201     {
202       if (Other.IsOpenYmax()) OpenYmax();
203       else if (Ymax < Other.Ymax) Ymax = Other.Ymax;
204     }
205     Gap = Max (Gap, Other.Gap);
206   }
207 }
208
209 //=======================================================================
210 //function : Add
211 //purpose  : 
212 //=======================================================================
213
214 void Bnd_Box2d::Add (const gp_Dir2d& D)
215 {
216   Standard_Real DX = D.X();
217   Standard_Real DY = D.Y();
218
219   if (DX < -RealEpsilon()) 
220     OpenXmin();
221   else if (DX > RealEpsilon()) 
222     OpenXmax();
223
224   if (DY < -RealEpsilon())
225     OpenYmin();
226   else if (DY > RealEpsilon())
227     OpenYmax();
228 }
229
230 //=======================================================================
231 //function : IsOut
232 //purpose  : 
233 //=======================================================================
234
235 Standard_Boolean Bnd_Box2d::IsOut (const gp_Pnt2d& P) const
236 {
237   if        (IsWhole())  return Standard_False;
238   else if   (IsVoid())   return Standard_True;
239   else {
240     Standard_Real X = P.X();
241     Standard_Real Y = P.Y();
242     if      (!(Flags & XminMask) && (X < (Xmin-Gap))) return Standard_True;
243     else if (!(Flags & XmaxMask) && (X > (Xmax+Gap))) return Standard_True;
244     else if (!(Flags & YminMask) && (Y < (Ymin-Gap))) return Standard_True;
245     else if (!(Flags & YmaxMask) && (Y > (Ymax+Gap))) return Standard_True;
246     else return Standard_False;
247   }
248 }
249
250 //=======================================================================
251 //function : IsOut
252 //purpose  : 
253 //=======================================================================
254
255 Standard_Boolean Bnd_Box2d::IsOut (const Bnd_Box2d& Other) const
256 {
257   if        (IsWhole())  return Standard_False;
258   else if   (IsVoid())   return Standard_True;
259   else if   (Other.IsWhole())  return Standard_False;
260   else if   (Other.IsVoid())   return Standard_True;
261   else {
262     Standard_Real OXmin,OXmax,OYmin,OYmax;
263     Other.Get(OXmin,OYmin,OXmax,OYmax);
264     if      (!(Flags & XminMask) && (OXmax < (Xmin-Gap))) return Standard_True;
265     else if (!(Flags & XmaxMask) && (OXmin > (Xmax+Gap))) return Standard_True;
266     else if (!(Flags & YminMask) && (OYmax < (Ymin-Gap))) return Standard_True;
267     else if (!(Flags & YmaxMask) && (OYmin > (Ymax+Gap))) return Standard_True;
268   }
269   return Standard_False;
270 }
271
272 //=======================================================================
273 //function : Dump
274 //purpose  : 
275 //=======================================================================
276
277 void Bnd_Box2d::Dump () const
278 {
279   cout << "Box2d : ";
280   if      (IsVoid())  cout << "Void";
281   else if (IsWhole()) cout << "Whole";
282   else {
283     cout << "\n Xmin : ";
284     if (IsOpenXmin()) cout << "Infinite";
285     else              cout << Xmin;
286     cout << "\n Xmax : ";
287     if (IsOpenXmax()) cout << "Infinite";
288     else              cout << Xmax;
289     cout << "\n Ymin : ";
290     if (IsOpenYmin()) cout << "Infinite";
291     else              cout << Ymin;
292     cout << "\n Ymax : ";
293     if (IsOpenYmax()) cout << "Infinite";
294     else              cout << Ymax;
295   }
296   cout << "\n Gap : " << Gap;
297   cout << "\n";
298 }