0030144: Visualization, TKOpenGl - extend OpenGl_FrameStats with frame timers
[occt.git] / src / Bnd / Bnd_OBB.hxx
CommitLineData
1a0339b4 1// Created by: Eugeny MALTCHIKOV
2// Copyright (c) 2017 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#ifndef _Bnd_OBB_HeaderFile
16#define _Bnd_OBB_HeaderFile
17
18#include <Standard.hxx>
19#include <Standard_DefineAlloc.hxx>
20#include <Standard_Handle.hxx>
21#include <Standard_Real.hxx>
22#include <Standard_Boolean.hxx>
23
24#include <Bnd_Box.hxx>
25#include <gp_Dir.hxx>
26#include <gp_Pnt.hxx>
27#include <gp_XYZ.hxx>
28#include <TColgp_Array1OfPnt.hxx>
29#include <TColStd_Array1OfReal.hxx>
30
31//! The class describes the Oriented Bounding Box (OBB),
32//! much tighter enclosing volume for the shape than the
33//! Axis Aligned Bounding Box (AABB).
34//! The OBB is defined by a center of the box, the axes and the halves
35//! of its three dimensions.
36//! The OBB can be used more effectively than AABB as a rejection mechanism
37//! for non-interfering objects.
38class Bnd_OBB
39{
40public:
41
42 DEFINE_STANDARD_ALLOC
43
44 //! Empty constructor
45 Bnd_OBB() :myIsAABox(Standard_False)
46 {
47 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
48 }
49
50 //! Constructor taking all defining parameters
51 Bnd_OBB(const gp_Pnt& theCenter,
52 const gp_Dir& theXDirection,
53 const gp_Dir& theYDirection,
54 const gp_Dir& theZDirection,
55 const Standard_Real theHXSize,
56 const Standard_Real theHYSize,
57 const Standard_Real theHZSize) :myCenter (theCenter.XYZ()),
58 myIsAABox(Standard_False)
59 {
60 myAxes[0] = theXDirection.XYZ();
61 myAxes[1] = theYDirection.XYZ();
62 myAxes[2] = theZDirection.XYZ();
63
64 Standard_ASSERT_VOID(theHXSize >= 0.0, "Negative value of X-size");
65 Standard_ASSERT_VOID(theHYSize >= 0.0, "Negative value of Y-size");
66 Standard_ASSERT_VOID(theHZSize >= 0.0, "Negative value of Z-size");
67
68 myHDims[0] = theHXSize;
69 myHDims[1] = theHYSize;
70 myHDims[2] = theHZSize;
71 }
72
73 //! Constructor to create OBB from AABB.
74 Bnd_OBB(const Bnd_Box& theBox) : myIsAABox(Standard_True)
75 {
1f26f80b 76 if (theBox.IsVoid())
77 {
78 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
79 myIsAABox = Standard_False;
80 return;
81 }
82
1a0339b4 83 Standard_Real aX1, aY1, aZ1, aX2, aY2, aZ2;
84 theBox.Get(aX1, aY1, aZ1, aX2, aY2, aZ2);
85
86 myAxes[0].SetCoord(1.0, 0.0, 0.0);
87 myAxes[1].SetCoord(0.0, 1.0, 0.0);
88 myAxes[2].SetCoord(0.0, 0.0, 1.0);
89
90 myHDims[0] = 0.5*(aX2 - aX1);
91 myHDims[1] = 0.5*(aY2 - aY1);
92 myHDims[2] = 0.5*(aZ2 - aZ1);
93
94 myCenter.SetCoord(0.5*(aX2 + aX1), 0.5*(aY2 + aY1), 0.5*(aZ2 + aZ1));
95 }
96
97 //! Created new OBB covering every point in theListOfPoints.
98 //! Tolerance of every such point is set by *theListOfTolerances array.
99 //! If this array is not void (not null-pointer) then the resulted Bnd_OBB
100 //! will be enlarged using tolerances of points lying on the box surface.
101 Standard_EXPORT void ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
102 const TColStd_Array1OfReal *theListOfTolerances = 0);
103
104 //! Sets the center of OBB
105 void SetCenter(const gp_Pnt& theCenter)
106 {
107 myCenter = theCenter.XYZ();
108 }
109
110 //! Sets the X component of OBB - direction and size
111 void SetXComponent(const gp_Dir& theXDirection,
112 const Standard_Real theHXSize)
113 {
114 Standard_ASSERT_VOID(theHXSize >= 0.0, "Negative value of X-size");
115
116 myAxes[0] = theXDirection.XYZ();
117 myHDims[0] = theHXSize;
118 }
119
120 //! Sets the Y component of OBB - direction and size
121 void SetYComponent(const gp_Dir& theYDirection,
122 const Standard_Real theHYSize)
123 {
124 Standard_ASSERT_VOID(theHYSize >= 0.0, "Negative value of Y-size");
125
126 myAxes[1] = theYDirection.XYZ();
127 myHDims[1] = theHYSize;
128 }
129
130 //! Sets the Z component of OBB - direction and size
131 void SetZComponent(const gp_Dir& theZDirection,
132 const Standard_Real theHZSize)
133 {
134 Standard_ASSERT_VOID(theHZSize >= 0.0, "Negative value of Z-size");
135
136 myAxes[2] = theZDirection.XYZ();
137 myHDims[2] = theHZSize;
138 }
139
140 //! Returns the center of OBB
141 const gp_XYZ& Center() const
142 {
143 return myCenter;
144 }
145
146 //! Returns the X Direction of OBB
147 const gp_XYZ& XDirection() const
148 {
149 return myAxes[0];
150 }
151
152 //! Returns the Y Direction of OBB
153 const gp_XYZ& YDirection() const
154 {
155 return myAxes[1];
156 }
157
158 //! Returns the Z Direction of OBB
159 const gp_XYZ& ZDirection() const
160 {
161 return myAxes[2];
162 }
163
164 //! Returns the X Dimension of OBB
165 Standard_Real XHSize() const
166 {
167 return myHDims[0];
168 }
169
170 //! Returns the Y Dimension of OBB
171 Standard_Real YHSize() const
172 {
173 return myHDims[1];
174 }
175
176 //! Returns the Z Dimension of OBB
177 Standard_Real ZHSize() const
178 {
179 return myHDims[2];
180 }
181
182 //! Checks if the box is empty.
183 Standard_Boolean IsVoid() const
184 {
185 return ((myHDims[0] < 0.0) || (myHDims[1] < 0.0) || (myHDims[2] < 0.0));
186 }
187
188 //! Clears this box
189 void SetVoid()
190 {
191 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
192 myCenter = myAxes[0] = myAxes[1] = myAxes[2] = gp_XYZ();
193 myIsAABox = Standard_False;
194 }
195
196 //! Sets the flag for axes aligned box
197 void SetAABox(const Standard_Boolean& theFlag)
198 {
199 myIsAABox = theFlag;
200 }
201
202 //! Returns TRUE if the box is axes aligned
203 Standard_Boolean IsAABox() const
204 {
205 return myIsAABox;
206 }
207
208 //! Enlarges the box with the given value
209 void Enlarge(const Standard_Real theGapAdd)
210 {
211 const Standard_Real aGap = Abs(theGapAdd);
212 myHDims[0] += aGap;
213 myHDims[1] += aGap;
214 myHDims[2] += aGap;
215 }
216
217 //! Returns the array of vertices in <this>.
218 //! The local coordinate of the vertex depending on the
219 //! index of the array are follow:
220 //! Index == 0: (-XHSize(), -YHSize(), -ZHSize())
221 //! Index == 1: ( XHSize(), -YHSize(), -ZHSize())
222 //! Index == 2: (-XHSize(), YHSize(), -ZHSize())
223 //! Index == 3: ( XHSize(), YHSize(), -ZHSize())
224 //! Index == 4: (-XHSize(), -YHSize(), ZHSize())
225 //! Index == 5: ( XHSize(), -YHSize(), ZHSize())
226 //! Index == 6: (-XHSize(), YHSize(), ZHSize())
227 //! Index == 7: ( XHSize(), YHSize(), ZHSize()).
228 Standard_Boolean GetVertex(gp_Pnt theP[8]) const
229 {
230 if(IsVoid())
231 return Standard_False;
232
233 theP[0].SetXYZ(myCenter - myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
234 theP[1].SetXYZ(myCenter + myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
235 theP[2].SetXYZ(myCenter - myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
236 theP[3].SetXYZ(myCenter + myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
237 theP[4].SetXYZ(myCenter - myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
238 theP[5].SetXYZ(myCenter + myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
239 theP[6].SetXYZ(myCenter - myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
240 theP[7].SetXYZ(myCenter + myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
241
242 return Standard_True;
243 }
244
245 //! Returns square diagonal of this box
246 Standard_Real SquareExtent() const
247 {
248 return (4.0*myHDims[0] * myHDims[0] +
249 myHDims[1] * myHDims[1] +
250 myHDims[1] * myHDims[1]);
251 }
252
253 //! Check if the box do not interfere the other box.
254 Standard_EXPORT Standard_Boolean IsOut(const Bnd_OBB& theOther) const;
255
256 //! Check if the point is inside of <this>.
257 Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& theP) const;
258
259 //! Check if the theOther is completely inside *this.
260 Standard_EXPORT Standard_Boolean IsCompletelyInside(const Bnd_OBB& theOther) const;
261
262 //! Rebuilds this in order to include all previous objects
263 //! (which it was created from) and theOther.
264 Standard_EXPORT void Add(const Bnd_OBB& theOther);
265
266 //! Rebuilds this in order to include all previous objects
267 //! (which it was created from) and theP.
268 Standard_EXPORT void Add(const gp_Pnt& theP);
269
270 protected:
271 void ProcessOnePoint(const gp_Pnt& theP)
272 {
273 myIsAABox = Standard_True;
274 myHDims[0] = myHDims[1] = myHDims[2] = 0.0;
275 myAxes[0].SetCoord(1.0, 0.0, 0.0);
276 myAxes[1].SetCoord(0.0, 1.0, 0.0);
277 myAxes[2].SetCoord(0.0, 0.0, 1.0);
278 myCenter = theP.XYZ();
279 }
280
281private:
282
283 //! Center of the OBB
284 gp_XYZ myCenter;
285
286 //! Directions of the box's axes
287 //! (all vectors are already normalized)
288 gp_XYZ myAxes[3];
289
290 //! Half-size dimensions of the OBB
291 Standard_Real myHDims[3];
292
293 //! To be set if the OBB is axis aligned box;
294 Standard_Boolean myIsAABox;
295};
296
297#endif