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