mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-05 14:39:41 +08:00
Co-authored-by: Andrew Le Bihan <andy@mcneel.com> Co-authored-by: Dale Fugier <dale@mcneel.com> Co-authored-by: Dale Lear <dalelear@mcneel.com> Co-authored-by: Greg Arden <greg@mcneel.com> Co-authored-by: Jussi <jussi@mcneel.com> Co-authored-by: Lowell <lowell@mcneel.com> Co-authored-by: Rajaa Issa <rajaa@mcneel.com> Co-authored-by: Steve Baer <steve@mcneel.com> Co-authored-by: alain <alain@mcneel.com> Co-authored-by: chuck <chuck@mcneel.com> Co-authored-by: piac <giulio@mcneel.com>
915 lines
26 KiB
C++
915 lines
26 KiB
C++
/* $NoKeywords: $ */
|
|
/*
|
|
//
|
|
// Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
|
|
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
|
// McNeel & Associates.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
|
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
|
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
|
//
|
|
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
#if !defined(ON_BOUNDING_BOX_INC_)
|
|
#define ON_BOUNDING_BOX_INC_
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_BoundingBox - axis aligned bounding box
|
|
//
|
|
|
|
class ON_CLASS ON_BoundingBox
|
|
{
|
|
public:
|
|
static const ON_BoundingBox EmptyBoundingBox; // ((1.0,0.0,0.0),(-1.0,0.0,0.0))
|
|
static const ON_BoundingBox UnsetBoundingBox; // all coordinates are ON_UNSET_VALUE
|
|
static const ON_BoundingBox NanBoundingBox; // all coordinates are ON_DBL_QNAN
|
|
|
|
ON_BoundingBox() ON_NOEXCEPT; // creates EmptyBoundingBox
|
|
~ON_BoundingBox() = default;
|
|
ON_BoundingBox(const ON_BoundingBox&) = default;
|
|
ON_BoundingBox& operator=(const ON_BoundingBox&) = default;
|
|
|
|
explicit ON_BoundingBox(
|
|
const ON_3dPoint&, // min corner of axis aligned bounding box
|
|
const ON_3dPoint& // max corner of axis aligned bounding box
|
|
);
|
|
|
|
|
|
// OBSOLETE
|
|
// temporary - use ON_ClippingRegion - this function will be removed soon.
|
|
int IsVisible(
|
|
const ON_Xform& bbox2c
|
|
) const;
|
|
|
|
|
|
// OBSOLETE
|
|
void Destroy(); // set this = ON_BoundingBox::EmptyBoundingBox
|
|
|
|
// operator[] returns min if index <= 0 and max if indes >= 1
|
|
ON_3dPoint& operator[](int);
|
|
const ON_3dPoint& operator[](int) const;
|
|
|
|
ON_3dPoint Min() const;
|
|
ON_3dPoint Max() const;
|
|
ON_3dVector Diagonal() const; // max corner - min corner
|
|
ON_3dPoint Center() const;
|
|
ON_3dPoint Corner( // 8 corners of box
|
|
int, // x_index 0 = Min().x, 1 = Max().x
|
|
int, // y_index 0 = Min().y, 1 = Max().y
|
|
int // z_index 0 = Min().z, 1 = Max().z
|
|
) const;
|
|
bool GetCorners(
|
|
ON_3dPointArray& box_corners // returns list of 8 corner points
|
|
) const;
|
|
bool GetCorners(
|
|
ON_3dPoint box_corners[8] // returns list of 8 corner points
|
|
) const;
|
|
|
|
/*
|
|
Parameters:
|
|
edges[] - out
|
|
12 edge lines. If the bounding box has no height, width or depth,
|
|
then the corresponding edges will have the same "from" and "to"
|
|
points.
|
|
Returns:
|
|
If the bounding box is valid, then true is returned and
|
|
12 line segments, some possibly a single point, are returned.
|
|
Otherwise false is returned and 12 line segments with "from"
|
|
and "to" points set to ON_3dPoint::UnsetPoint are returned.
|
|
*/
|
|
bool GetEdges(
|
|
ON_Line edges[12] // returns list of 12 edge segments
|
|
) const;
|
|
|
|
// OBSOLETE IsValid() = IsNotEmpty()
|
|
bool IsValid() const; // empty boxes are not valid
|
|
|
|
bool IsSet() const; // every coordinate is a finite, valid double, not ON_UNSET_VALUE and not ON_UNSET_POSITIVE_VALUE
|
|
bool IsUnset() const; // some coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
bool IsNan() const; // some coordinate is a NAN
|
|
bool IsUnsetOrNan() const; // = IsUnset() or IsNan()
|
|
|
|
bool IsEmpty() const; // (m_min.x > m_max.x || m_min.y > m_max.y || m_min.z > m_max.z) && IsSet();
|
|
bool IsNotEmpty() const; // (m_min.x <= m_max.x && m_min.y <= m_max.y && m_min.z <= m_max.z) && IsSet()
|
|
bool IsPoint() const; // (m_min.x == m_max.x && m_min.y == m_max.y && m_min.z == m_max.z) && IsSet()
|
|
|
|
void Dump(class ON_TextLog&) const;
|
|
|
|
/*
|
|
Description:
|
|
Test a bounding box to see if it is degenerate (flat)
|
|
in one or more directions.
|
|
Parameters:
|
|
tolerance - [in] Distances <= tolerance will be considered
|
|
to be zero. If tolerance is negative (default), then
|
|
a scale invarient tolerance is used.
|
|
Returns:
|
|
@untitled table
|
|
0 box is not degenerate
|
|
1 box is a rectangle (degenerate in one direction)
|
|
2 box is a line (degenerate in two directions)
|
|
3 box is a point (degenerate in three directions)
|
|
4 box is not valid
|
|
*/
|
|
int IsDegenerate(
|
|
double tolerance = ON_UNSET_VALUE
|
|
) const;
|
|
|
|
|
|
//////////
|
|
// ON_BoundingBox::Transform() updates the bounding box
|
|
// to be the smallest axis aligned bounding box that contains
|
|
// the transform of the eight corner points of the input
|
|
// bounding box.
|
|
bool Transform( const ON_Xform& );
|
|
|
|
double Tolerance() const; // rough guess at a tolerance to use for comparing
|
|
// objects in this bounding box
|
|
|
|
|
|
// All of these Set() functions set or expand a box to enclose the points in the arguments
|
|
// If bGrowBox is true, the existing box is expanded, otherwise it is only set to the current point list
|
|
bool Set(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const double* point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_3dPoint& point,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_2dPoint& point,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_SimpleArray<ON_4dPoint>& point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_SimpleArray<ON_3dPoint>& point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_SimpleArray<ON_2dPoint>& point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const float* point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_3fPoint& point,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_2fPoint& point,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_SimpleArray<ON_4fPoint>& point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_SimpleArray<ON_3fPoint>& point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool Set(
|
|
const ON_SimpleArray<ON_2fPoint>& point_array,
|
|
int bGrowBox = false
|
|
);
|
|
|
|
bool IsPointIn(
|
|
const ON_3dPoint& test_point, // point to test
|
|
int bStrictlyIn = false
|
|
// true to test for strict ( min < point < max )
|
|
// false to test for (min <= point <= max)
|
|
//
|
|
) const;
|
|
|
|
//////////
|
|
// Point on or in the box that is closest to test_point.
|
|
// If test_point is in or on the box, the test_point is returned.
|
|
ON_3dPoint ClosestPoint(
|
|
const ON_3dPoint& test_point
|
|
) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Quickly find a lower bound on the distance
|
|
between the point and this bounding box.
|
|
Parameters:
|
|
P - [in]
|
|
Returns:
|
|
A distance that is less than or equal to the shortest
|
|
distance from the line to this bounding box.
|
|
Put another way, if Q is any point in this bounding box,
|
|
then P.DistanceTo(Q) >= MinimumDistanceTo(bbox).
|
|
*/
|
|
double MinimumDistanceTo( const ON_3dPoint& P ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly find an upper bound on the distance
|
|
between the point and this bounding box.
|
|
Parameters:
|
|
P - [in]
|
|
Returns:
|
|
A distance that is greater than or equal to the
|
|
longest distance from the point P to this bounding box.
|
|
Put another way, if Q is any point in this bounding box,
|
|
then P.DistanceTo(Q) <= MaximumDistanceTo(bbox).
|
|
*/
|
|
double MaximumDistanceTo( const ON_3dPoint& P ) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Quickly find a lower bound on the distance
|
|
between this and the other bounding box.
|
|
Parameters:
|
|
other - [in]
|
|
Returns:
|
|
A distance that is less than or equal to the shortest
|
|
distance between the bounding boxes.
|
|
Put another way, if Q is any point in this bounding box
|
|
and P is any point in the other bounding box,
|
|
then P.DistanceTo(Q) >= MinimumDistanceTo(bbox).
|
|
*/
|
|
double MinimumDistanceTo( const ON_BoundingBox& other ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly find an upper bound on the distance
|
|
between this and the other bounding box.
|
|
Parameters:
|
|
other - [in]
|
|
Returns:
|
|
A distance that is greater than or equal to the longest
|
|
distance between the bounding boxes.
|
|
Put another way, if Q is any point in this bounding box
|
|
and P is any point in the other bounding box,
|
|
then P.DistanceTo(Q) <= MaximumDistanceTo(bbox).
|
|
*/
|
|
double MaximumDistanceTo( const ON_BoundingBox& other ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly find a lower bound on the distance
|
|
between the line segment and this bounding box.
|
|
Parameters:
|
|
line - [in]
|
|
Returns:
|
|
A distance that is less than or equal to the shortest
|
|
distance from the line to this bounding box.
|
|
Put another way, if Q is any point on line
|
|
and P is any point in this bounding box, then
|
|
P.DistanceTo(Q) >= MinimumDistanceTo(bbox).
|
|
*/
|
|
double MinimumDistanceTo( const ON_Line& line ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly find a tight lower bound on the distance
|
|
between the plane and this bounding box.
|
|
Parameters:
|
|
plane - [in]
|
|
Returns:
|
|
The minimum distance between a point on the plane
|
|
and a point on the bounding box.
|
|
See Also:
|
|
ON_PlaneEquation::MimimumValueAt
|
|
ON_PlaneEquation::MaximumValueAt
|
|
*/
|
|
double MinimumDistanceTo( const ON_Plane& plane ) const;
|
|
double MinimumDistanceTo( const ON_PlaneEquation& plane_equation ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly find an upper bound on the distance
|
|
between the line segment and this bounding box.
|
|
Parameters:
|
|
line - [in]
|
|
Returns:
|
|
A distance that is greater than or equal to the
|
|
longest distance from the line to this bounding box.
|
|
Put another way, if Q is any point on the line
|
|
and P is any point in this bounding box, then
|
|
P.DistanceTo(Q) <= MaximumDistanceTo(bbox).
|
|
*/
|
|
double MaximumDistanceTo( const ON_Line& line ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly find a tight upper bound on the distance
|
|
between the plane and this bounding box.
|
|
Parameters:
|
|
plane - [in]
|
|
Returns:
|
|
A distance that is equal to the longest distance from
|
|
the plane to this bounding box. Put another way,
|
|
if Q is any point on the plane and P is any point
|
|
in this bounding box, then
|
|
P.DistanceTo(Q) <= MaximumDistanceTo(bbox) and there
|
|
is at least one point on the bounding box where the
|
|
distance is equal to the returned value.
|
|
See Also:
|
|
ON_PlaneEquation::MaximumValueAt
|
|
*/
|
|
double MaximumDistanceTo( const ON_Plane& plane ) const;
|
|
double MaximumDistanceTo( const ON_PlaneEquation& plane_equation ) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Quickly determine if the shortest distance from
|
|
the point P to the bounding box is greater than d.
|
|
Parameters:
|
|
d - [in] distance (> 0.0)
|
|
P - [in]
|
|
Returns:
|
|
True if if the shortest distance from the point P
|
|
to the bounding box is greater than d.
|
|
*/
|
|
bool IsFartherThan( double d, const ON_3dPoint& P ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly determine if the shortest distance from the line
|
|
to the bounding box is greater than d.
|
|
Parameters:
|
|
d - [in] distance (> 0.0)
|
|
line - [in]
|
|
Returns:
|
|
True if the shortest distance from the line
|
|
to the bounding box is greater than d. It is not the
|
|
case that false means that the shortest distance
|
|
is less than or equal to d.
|
|
*/
|
|
bool IsFartherThan( double d, const ON_Line& line ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly determine if the shortest distance from the plane
|
|
to the bounding box is greater than d.
|
|
Parameters:
|
|
d - [in] distance (> 0.0)
|
|
plane - [in]
|
|
Returns:
|
|
True if the shortest distance from the plane
|
|
to the bounding box is greater than d, and false
|
|
if the shortest distance is less than or equal to d.
|
|
*/
|
|
bool IsFartherThan( double d, const ON_Plane& plane ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly determine if the shortest distance from the plane
|
|
to the bounding box is greater than d.
|
|
Parameters:
|
|
d - [in] distance (> 0.0)
|
|
plane_equation - [in] (the first three coefficients
|
|
are assumed to be a unit vector.
|
|
If not, adjust your d accordingly.)
|
|
Returns:
|
|
True if the shortest distance from the plane
|
|
to the bounding box is greater than d, and false
|
|
if the shortest distance is less than or equal to d.
|
|
*/
|
|
bool IsFartherThan( double d, const ON_PlaneEquation& plane_equation ) const;
|
|
|
|
/*
|
|
Description:
|
|
Quickly determine if the shortest distance this bounding
|
|
box to another bounding box is greater than d.
|
|
Parameters:
|
|
d - [in] distance (> 0.0)
|
|
other - [in] other bounding box
|
|
Returns:
|
|
True if if the shortest distance from this bounding
|
|
box to the other bounding box is greater than d.
|
|
*/
|
|
bool IsFartherThan( double d, const ON_BoundingBox& other ) const;
|
|
|
|
|
|
// Description:
|
|
// Get point in a bounding box that is closest to a line
|
|
// segment.
|
|
// Parameters:
|
|
// line - [in] line segment
|
|
// box_point - [out] point in box that is closest to line
|
|
// segment point at t0.
|
|
// t0 - [out] parameter of point on line that is closest to
|
|
// the box.
|
|
// t1 - [out] parameter of point on line that is closest to
|
|
// the box.
|
|
// Returns:
|
|
// 3 success - line segments intersects box in a segment
|
|
// from line(t0) to line(t1) (t0 < t1)
|
|
// 2 success - line segments intersects box in a single point
|
|
// at line(t0) (t0==t1)
|
|
// 1 success - line segment does not intersect box. Closest
|
|
// point on the line is at line(t0) (t0==t1)
|
|
// 0 failure - box is invalid.
|
|
// Remarks:
|
|
// The box is treated as a solid box. If the intersection
|
|
// of the line segment, then 3 is returned.
|
|
int GetClosestPoint(
|
|
const ON_Line&, // line
|
|
ON_3dPoint&, // box_point
|
|
double*, // t0
|
|
double* // t1
|
|
) const;
|
|
|
|
//////////
|
|
// Get points on bounding boxes that are closest to each other.
|
|
// If the boxes intersect, then the point at the centroid of the
|
|
// intersection is returned for both points.
|
|
bool GetClosestPoint(
|
|
const ON_BoundingBox&, // "other" bounding box
|
|
ON_3dPoint&, // point on "this" box that is closest to "other" box
|
|
ON_3dPoint& // point on "other" box that is closest to "this" box
|
|
) const;
|
|
|
|
//////////
|
|
// Point on the box that is farthest from the test_point.
|
|
ON_3dPoint FarPoint(
|
|
const ON_3dPoint& // test_point
|
|
) const;
|
|
|
|
//////////
|
|
// Get points on bounding boxes that are farthest from each other.
|
|
bool GetFarPoint(
|
|
const ON_BoundingBox&, // "other" bounding box
|
|
ON_3dPoint&, // point on "this" box that is farthest from "other" box
|
|
ON_3dPoint& // point on "other" box that is farthest from "this" box
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Intersect this with other_bbox and save intersection in this.
|
|
Parameters:
|
|
other_bbox - [in]
|
|
Returns:
|
|
True if this-intesect-other_bbox is a non-empty valid bounding box
|
|
and this is set. False if the intersection is empty, in which case
|
|
"this" is set to an invalid bounding box.
|
|
Remarks:
|
|
If "this" or other_bbox is invalid, they are treated as
|
|
the empty set, and false is returned.
|
|
*/
|
|
bool Intersection(
|
|
const ON_BoundingBox& other_bbox
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Set "this" to the intersection of bbox_A and bbox_B.
|
|
Parameters:
|
|
bbox_A - [in]
|
|
bbox_B - [in]
|
|
Returns:
|
|
True if the "this" is a non-empty valid bounding box.
|
|
False if the intersection is empty, in which case
|
|
"this" is set to an invalid bounding box.
|
|
Remarks:
|
|
If bbox_A or bbox_B is invalid, they are treated as
|
|
the empty set, and false is returned.
|
|
*/
|
|
bool Intersection( // this = intersection of two args
|
|
const ON_BoundingBox& bbox_A,
|
|
const ON_BoundingBox& bbox_B
|
|
);
|
|
|
|
bool Intersection( //Returns true when intersect is non-empty.
|
|
const ON_Line&, //Infinite Line segment to intersect with
|
|
double* =nullptr , // t0 parameter of first intersection point
|
|
double* =nullptr // t1 parameter of last intersection point (t0<=t1)
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Test a box to see if it is contained in this box.
|
|
Parameters:
|
|
other - [in] box to test
|
|
bProperSubSet - [in] if true, then the test is for a proper inclusion.
|
|
Returns:
|
|
If bProperSubSet is false, then the result is true when
|
|
this->m_min[i] <= other.m_min[i] and other.m_max[i] <= this->m_max[i].
|
|
for i=0,1 and 2.
|
|
If bProperSubSet is true, then the result is true when
|
|
the above condition is true and at least one of the inequalities is strict.
|
|
*/
|
|
bool Includes(
|
|
const ON_BoundingBox& other,
|
|
bool bProperSubSet = false
|
|
) const;
|
|
|
|
double Volume() const;
|
|
|
|
double Area() const;
|
|
|
|
// Union() returns true if union is not empty.
|
|
// Invalid boxes are treated as the empty set.
|
|
bool Union( // this = this union arg
|
|
const ON_BoundingBox&
|
|
);
|
|
|
|
bool Union( // this = union of two args
|
|
const ON_BoundingBox&,
|
|
const ON_BoundingBox&
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Test to see if "this" and other_bbox are disjoint (do not intersect).
|
|
Parameters:
|
|
other_bbox - [in]
|
|
Returns:
|
|
True if "this" and other_bbox are disjoint.
|
|
Remarks:
|
|
If "this" or other_bbox is invalid, then true is returned.
|
|
*/
|
|
bool IsDisjoint(
|
|
const ON_BoundingBox& other_bbox
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Test to see if "this" and line are disjoint (do not intersect or line is included).
|
|
Parameters:
|
|
line - [in]
|
|
infinite - [in] if false or not provided, then the line is considered bounded by start and end points.
|
|
Returns:
|
|
True if "this" and line are disjoint.
|
|
*/
|
|
bool IsDisjoint(const ON_Line& line) const;
|
|
bool IsDisjoint(const ON_Line& line, bool infinite) const;
|
|
|
|
bool SwapCoordinates( int, int );
|
|
|
|
/*
|
|
Description:
|
|
Expand the box by adding delta to m_max and subtracting
|
|
it from m_min. So, when delta is positive and the interval is
|
|
increasing this function expands the box on each side.
|
|
Returns:
|
|
true if the result is Valid.
|
|
*/
|
|
bool Expand(ON_3dVector delta);
|
|
|
|
ON_3dPoint m_min;
|
|
ON_3dPoint m_max;
|
|
};
|
|
|
|
/*
|
|
Returns:
|
|
True if lhs and rhs are identical.
|
|
*/
|
|
ON_DECL
|
|
bool operator==( const ON_BoundingBox& lhs, const ON_BoundingBox& rhs );
|
|
|
|
/*
|
|
Returns:
|
|
True if lhs and rhs are not equal.
|
|
*/
|
|
ON_DECL
|
|
bool operator!=( const ON_BoundingBox& lhs, const ON_BoundingBox& rhs );
|
|
|
|
class ON_CLASS ON_BoundingBoxAndHash
|
|
{
|
|
public:
|
|
ON_BoundingBoxAndHash() = default;
|
|
~ON_BoundingBoxAndHash() = default;
|
|
ON_BoundingBoxAndHash(const ON_BoundingBoxAndHash&) = default;
|
|
ON_BoundingBoxAndHash& operator=(const ON_BoundingBoxAndHash&) = default;
|
|
|
|
public:
|
|
// This hash depends on the context and is a hash
|
|
// of the information used to calculte the bounding box.
|
|
// It is not the hash of the box values
|
|
|
|
void Set(
|
|
const ON_BoundingBox& bbox,
|
|
const ON_SHA1_Hash& hash
|
|
);
|
|
|
|
const ON_BoundingBox& BoundingBox() const;
|
|
|
|
const ON_SHA1_Hash& Hash() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if bounding box IsSet() is true and hash is not EmptyContentHash.
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
bool Write(
|
|
class ON_BinaryArchive& archive
|
|
) const;
|
|
|
|
bool Read(
|
|
class ON_BinaryArchive& archive
|
|
);
|
|
|
|
private:
|
|
ON_BoundingBox m_bbox = ON_BoundingBox::UnsetBoundingBox;
|
|
ON_SHA1_Hash m_hash = ON_SHA1_Hash::EmptyContentHash;
|
|
};
|
|
|
|
/*
|
|
A class that caches 8 bounding box - hash pairs and keeps the most frequently
|
|
used bounding boxes.
|
|
*/
|
|
class ON_CLASS ON_BoundingBoxCache
|
|
{
|
|
public:
|
|
ON_BoundingBoxCache() = default;
|
|
~ON_BoundingBoxCache() = default;
|
|
ON_BoundingBoxCache(const ON_BoundingBoxCache&) = default;
|
|
ON_BoundingBoxCache& operator=(const ON_BoundingBoxCache&) = default;
|
|
|
|
public:
|
|
/*
|
|
Description:
|
|
Add a bounding box that can be found from a hash value.
|
|
Parameters:
|
|
bbox - [in]
|
|
hash - [in]
|
|
A hash of the information needed to create this bounding box.
|
|
*/
|
|
void AddBoundingBox(
|
|
const ON_BoundingBox& bbox,
|
|
const ON_SHA1_Hash& hash
|
|
);
|
|
|
|
void AddBoundingBox(
|
|
const ON_BoundingBoxAndHash& bbox_and_hash
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Get a cached bounding box.
|
|
Parameters:
|
|
hash - [in]
|
|
bbox - [out]
|
|
If the hash identifies a bounding box in the cache, then
|
|
that bounding box is returned. Otherwise ON_BoundingBox::NanBoundingBox
|
|
is returned.
|
|
Returns:
|
|
true - cached bounding box returned
|
|
false - bounding box not in cache.
|
|
*/
|
|
bool GetBoundingBox(
|
|
const ON_SHA1_Hash& hash,
|
|
ON_BoundingBox& bbox
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Remove a bounding box that can be found from a hash value.
|
|
Parameters:
|
|
hash - [in]
|
|
Returns:
|
|
true - hash was in the cache and removed.
|
|
false - hash was not in the cache.
|
|
Remarks:
|
|
If the hash values you are using are correctly computed and include
|
|
all information that the bouding box depends on, then
|
|
you never need to remove bounding boxes. Unused ones will get
|
|
removed as new ones are added.
|
|
*/
|
|
bool RemoveBoundingBox(
|
|
const ON_SHA1_Hash& hash
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Removes all bounding boxes.
|
|
Remarks:
|
|
If the hash values you are using are correctly computed and include
|
|
all information that the bouding box depends on, then
|
|
you never need to remove bounding boxes. Unused ones will get
|
|
removed as new ones are added.
|
|
If the hash does not include all information required to compute
|
|
the bounding boxes, then call RemoveAllBoundingBoxes() when the
|
|
non-hashed information changes.
|
|
*/
|
|
void RemoveAllBoundingBoxes();
|
|
|
|
/*
|
|
Returns:
|
|
Number of cached boxes.
|
|
*/
|
|
unsigned int BoundingBoxCount() const;
|
|
|
|
bool Write(
|
|
class ON_BinaryArchive& archive
|
|
) const;
|
|
|
|
bool Read(
|
|
class ON_BinaryArchive& archive
|
|
);
|
|
|
|
private:
|
|
// number of boxes set in m_cache[]
|
|
unsigned int m_count = 0;
|
|
|
|
// capacity of m_cache[] - set when needed
|
|
unsigned int m_capacity = 0;
|
|
|
|
// Bounding box cache. Most recently used boxes are first.
|
|
mutable ON_BoundingBoxAndHash m_cache[8];
|
|
|
|
/*
|
|
Returns:
|
|
m_cache[] array index of box with the hash.
|
|
ON_UNSET_UINT_INDEX if hash is not present in m_cache[] array.
|
|
*/
|
|
unsigned int Internal_CacheIndex(const ON_SHA1_Hash& hash) const;
|
|
};
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BoundingBox>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BoundingBoxAndHash>;
|
|
|
|
#endif
|
|
|
|
/*
|
|
Description:
|
|
Get a tight bounding box that contains the points.
|
|
Parameters:
|
|
dim - [in] (>=1)
|
|
is_rat - [in] true if points are rational
|
|
count - [in] number of points
|
|
stride - [in] stride between points
|
|
point_list - [in]
|
|
bbox - [in/out]
|
|
bGrowBox - [in] (default = false)
|
|
If the input bbox is valid and bGrowBox is true,
|
|
then the output bbox is the union of the input
|
|
bbox and the bounding box of the point list.
|
|
xform - [in] (default = nullptr)
|
|
If not null, the bounding box of the transformed
|
|
points is calculated. The points are not modified.
|
|
Returns:
|
|
True if the output bbox is valid.
|
|
*/
|
|
ON_DECL
|
|
bool ON_GetPointListBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const double* point_list,
|
|
ON_BoundingBox& bbox,
|
|
int bGrowBox = false,
|
|
const ON_Xform* xform = 0
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_GetPointListBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const float* point_list,
|
|
ON_BoundingBox& bbox,
|
|
int bGrowBox = false,
|
|
const ON_Xform* xform = 0
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_GetPointListBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const double* point_list,
|
|
double* boxmin, // min[dim]
|
|
double* boxmax, // max[dim]
|
|
int bGrowBox
|
|
);
|
|
|
|
ON_DECL
|
|
ON_BoundingBox ON_PointListBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const double* point_list
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_GetPointListBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const float* point_list,
|
|
float* boxmin, // min[dim]
|
|
float* boxmax, // max[dim]
|
|
int bGrowBox
|
|
);
|
|
|
|
ON_DECL
|
|
ON_BoundingBox ON_PointListBoundingBox( // low level workhorse function
|
|
int dim,
|
|
bool is_rat,
|
|
int count,
|
|
int stride,
|
|
const float* point_list
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_GetPointGridBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int point_count0, int point_count1,
|
|
int point_stride0, int point_stride1,
|
|
const double* point_grid,
|
|
double* boxmin, // min[dim]
|
|
double* boxmax, // max[dim]
|
|
int bGrowBox
|
|
);
|
|
|
|
ON_DECL
|
|
ON_BoundingBox ON_PointGridBoundingBox(
|
|
int dim,
|
|
bool is_rat,
|
|
int point_count0, int point_count1,
|
|
int point_stride0, int point_stride1,
|
|
const double* point_grid
|
|
);
|
|
|
|
ON_DECL
|
|
double ON_BoundingBoxTolerance(
|
|
int dim,
|
|
const double* bboxmin,
|
|
const double* bboxmax
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Determine if an object is too large or too far
|
|
from the origin for single precision coordinates
|
|
to be useful.
|
|
Parameters:
|
|
bbox - [in]
|
|
Bounding box of an object with single precision
|
|
coordinates. An ON_Mesh is an example of an
|
|
object with single precision coordinates.
|
|
xform - [out]
|
|
If this function returns false and xform is not
|
|
null, then the identity transform is returned.
|
|
If this function returns true and xform is not
|
|
null, then the transform moves the region
|
|
contained in bbox to a location where single
|
|
precision coordinates will have enough
|
|
information for the object to be useful.
|
|
Returns:
|
|
true:
|
|
The region contained in bbox is too large
|
|
or too far from the origin for single
|
|
precision coordinates to be useful.
|
|
false:
|
|
A single precision object contained in bbox
|
|
will be satisfactory for common calculations.
|
|
*/
|
|
ON_DECL
|
|
bool ON_BeyondSinglePrecision( const ON_BoundingBox& bbox, ON_Xform* xform );
|
|
|
|
ON_DECL
|
|
bool ON_WorldBBoxIsInTightBBox(
|
|
const ON_BoundingBox& tight_bbox,
|
|
const ON_BoundingBox& world_bbox,
|
|
const ON_Xform* xform
|
|
);
|
|
|
|
#endif
|