1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2017 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #ifndef _Bnd_OBB_HeaderFile
16 #define _Bnd_OBB_HeaderFile
18 #include <Standard.hxx>
19 #include <Standard_DefineAlloc.hxx>
20 #include <Standard_Handle.hxx>
21 #include <Standard_Real.hxx>
22 #include <Standard_Boolean.hxx>
24 #include <Bnd_Box.hxx>
29 #include <TColgp_Array1OfPnt.hxx>
30 #include <TColStd_Array1OfReal.hxx>
32 //! The class describes the Oriented Bounding Box (OBB),
33 //! much tighter enclosing volume for the shape than the
34 //! Axis Aligned Bounding Box (AABB).
35 //! The OBB is defined by a center of the box, the axes and the halves
36 //! of its three dimensions.
37 //! The OBB can be used more effectively than AABB as a rejection mechanism
38 //! for non-interfering objects.
46 Bnd_OBB() :myIsAABox(Standard_False)
48 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
51 //! Constructor taking all defining parameters
52 Bnd_OBB(const gp_Pnt& theCenter,
53 const gp_Dir& theXDirection,
54 const gp_Dir& theYDirection,
55 const gp_Dir& theZDirection,
56 const Standard_Real theHXSize,
57 const Standard_Real theHYSize,
58 const Standard_Real theHZSize) :myCenter (theCenter.XYZ()),
59 myIsAABox(Standard_False)
61 myAxes[0] = theXDirection.XYZ();
62 myAxes[1] = theYDirection.XYZ();
63 myAxes[2] = theZDirection.XYZ();
65 Standard_ASSERT_VOID(theHXSize >= 0.0, "Negative value of X-size");
66 Standard_ASSERT_VOID(theHYSize >= 0.0, "Negative value of Y-size");
67 Standard_ASSERT_VOID(theHZSize >= 0.0, "Negative value of Z-size");
69 myHDims[0] = theHXSize;
70 myHDims[1] = theHYSize;
71 myHDims[2] = theHZSize;
74 //! Constructor to create OBB from AABB.
75 Bnd_OBB(const Bnd_Box& theBox) : myIsAABox(Standard_True)
79 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
80 myIsAABox = Standard_False;
84 Standard_Real aX1, aY1, aZ1, aX2, aY2, aZ2;
85 theBox.Get(aX1, aY1, aZ1, aX2, aY2, aZ2);
87 myAxes[0].SetCoord(1.0, 0.0, 0.0);
88 myAxes[1].SetCoord(0.0, 1.0, 0.0);
89 myAxes[2].SetCoord(0.0, 0.0, 1.0);
91 myHDims[0] = 0.5*(aX2 - aX1);
92 myHDims[1] = 0.5*(aY2 - aY1);
93 myHDims[2] = 0.5*(aZ2 - aZ1);
95 myCenter.SetCoord(0.5*(aX2 + aX1), 0.5*(aY2 + aY1), 0.5*(aZ2 + aZ1));
98 //! Created new OBB covering every point in theListOfPoints.
99 //! Tolerance of every such point is set by *theListOfTolerances array.
100 //! If this array is not void (not null-pointer) then the resulted Bnd_OBB
101 //! will be enlarged using tolerances of points lying on the box surface.
102 Standard_EXPORT void ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
103 const TColStd_Array1OfReal *theListOfTolerances = 0);
105 //! Sets the center of OBB
106 void SetCenter(const gp_Pnt& theCenter)
108 myCenter = theCenter.XYZ();
111 //! Sets the X component of OBB - direction and size
112 void SetXComponent(const gp_Dir& theXDirection,
113 const Standard_Real theHXSize)
115 Standard_ASSERT_VOID(theHXSize >= 0.0, "Negative value of X-size");
117 myAxes[0] = theXDirection.XYZ();
118 myHDims[0] = theHXSize;
121 //! Sets the Y component of OBB - direction and size
122 void SetYComponent(const gp_Dir& theYDirection,
123 const Standard_Real theHYSize)
125 Standard_ASSERT_VOID(theHYSize >= 0.0, "Negative value of Y-size");
127 myAxes[1] = theYDirection.XYZ();
128 myHDims[1] = theHYSize;
131 //! Sets the Z component of OBB - direction and size
132 void SetZComponent(const gp_Dir& theZDirection,
133 const Standard_Real theHZSize)
135 Standard_ASSERT_VOID(theHZSize >= 0.0, "Negative value of Z-size");
137 myAxes[2] = theZDirection.XYZ();
138 myHDims[2] = theHZSize;
141 //! Returns the local coordinates system of this oriented box.
142 //! So that applying it to axis-aligned box ((-XHSize, -YHSize, -ZHSize), (XHSize, YHSize, ZHSize)) will produce this oriented box.
145 //! aLoc.SetTransformation (theOBB.Position(), gp::XOY());
147 gp_Ax3 Position() const { return gp_Ax3 (myCenter, ZDirection(), XDirection()); }
149 //! Returns the center of OBB
150 const gp_XYZ& Center() const
155 //! Returns the X Direction of OBB
156 const gp_XYZ& XDirection() const
161 //! Returns the Y Direction of OBB
162 const gp_XYZ& YDirection() const
167 //! Returns the Z Direction of OBB
168 const gp_XYZ& ZDirection() const
173 //! Returns the X Dimension of OBB
174 Standard_Real XHSize() const
179 //! Returns the Y Dimension of OBB
180 Standard_Real YHSize() const
185 //! Returns the Z Dimension of OBB
186 Standard_Real ZHSize() const
191 //! Checks if the box is empty.
192 Standard_Boolean IsVoid() const
194 return ((myHDims[0] < 0.0) || (myHDims[1] < 0.0) || (myHDims[2] < 0.0));
200 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
201 myCenter = myAxes[0] = myAxes[1] = myAxes[2] = gp_XYZ();
202 myIsAABox = Standard_False;
205 //! Sets the flag for axes aligned box
206 void SetAABox(const Standard_Boolean& theFlag)
211 //! Returns TRUE if the box is axes aligned
212 Standard_Boolean IsAABox() const
217 //! Enlarges the box with the given value
218 void Enlarge(const Standard_Real theGapAdd)
220 const Standard_Real aGap = Abs(theGapAdd);
226 //! Returns the array of vertices in <this>.
227 //! The local coordinate of the vertex depending on the
228 //! index of the array are follow:
229 //! Index == 0: (-XHSize(), -YHSize(), -ZHSize())
230 //! Index == 1: ( XHSize(), -YHSize(), -ZHSize())
231 //! Index == 2: (-XHSize(), YHSize(), -ZHSize())
232 //! Index == 3: ( XHSize(), YHSize(), -ZHSize())
233 //! Index == 4: (-XHSize(), -YHSize(), ZHSize())
234 //! Index == 5: ( XHSize(), -YHSize(), ZHSize())
235 //! Index == 6: (-XHSize(), YHSize(), ZHSize())
236 //! Index == 7: ( XHSize(), YHSize(), ZHSize()).
237 Standard_Boolean GetVertex(gp_Pnt theP[8]) const
240 return Standard_False;
242 theP[0].SetXYZ(myCenter - myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
243 theP[1].SetXYZ(myCenter + myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
244 theP[2].SetXYZ(myCenter - myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
245 theP[3].SetXYZ(myCenter + myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] - myHDims[2]*myAxes[2]);
246 theP[4].SetXYZ(myCenter - myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
247 theP[5].SetXYZ(myCenter + myHDims[0]*myAxes[0] - myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
248 theP[6].SetXYZ(myCenter - myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
249 theP[7].SetXYZ(myCenter + myHDims[0]*myAxes[0] + myHDims[1]*myAxes[1] + myHDims[2]*myAxes[2]);
251 return Standard_True;
254 //! Returns square diagonal of this box
255 Standard_Real SquareExtent() const
257 return (4.0*myHDims[0] * myHDims[0] +
258 myHDims[1] * myHDims[1] +
259 myHDims[1] * myHDims[1]);
262 //! Check if the box do not interfere the other box.
263 Standard_EXPORT Standard_Boolean IsOut(const Bnd_OBB& theOther) const;
265 //! Check if the point is inside of <this>.
266 Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& theP) const;
268 //! Check if the theOther is completely inside *this.
269 Standard_EXPORT Standard_Boolean IsCompletelyInside(const Bnd_OBB& theOther) const;
271 //! Rebuilds this in order to include all previous objects
272 //! (which it was created from) and theOther.
273 Standard_EXPORT void Add(const Bnd_OBB& theOther);
275 //! Rebuilds this in order to include all previous objects
276 //! (which it was created from) and theP.
277 Standard_EXPORT void Add(const gp_Pnt& theP);
281 void ProcessOnePoint(const gp_Pnt& theP)
283 myIsAABox = Standard_True;
284 myHDims[0] = myHDims[1] = myHDims[2] = 0.0;
285 myAxes[0].SetCoord(1.0, 0.0, 0.0);
286 myAxes[1].SetCoord(0.0, 1.0, 0.0);
287 myAxes[2].SetCoord(0.0, 0.0, 1.0);
288 myCenter = theP.XYZ();
293 //! Center of the OBB
296 //! Directions of the box's axes
297 //! (all vectors are already normalized)
300 //! Half-size dimensions of the OBB
301 Standard_Real myHDims[3];
303 //! To be set if the OBB is axis aligned box;
304 Standard_Boolean myIsAABox;