AABB tree: some more cleanup.

This commit is contained in:
Pierre Alliez 2009-07-01 20:49:03 +00:00
parent bc80ee2e5c
commit 1d6e776431
6 changed files with 89 additions and 224 deletions

View File

@ -4,194 +4,102 @@
class Color_ramp
{
private :
unsigned char m_colors[4][256];
int m_nodes[256];
int m_nodes[256];
unsigned char m_colors[4][256];
public :
// life cycle
Color_ramp()
{
build_thermal();
}
~Color_ramp() {}
Color_ramp()
{
build_thermal();
}
~Color_ramp() {}
public :
unsigned char* color(unsigned int index) { return m_colors[index%256]; }
const unsigned char r(unsigned int index) const { return m_colors[0][index%256]; }
const unsigned char g(unsigned int index) const { return m_colors[1][index%256]; }
const unsigned char b(unsigned int index) const { return m_colors[2][index%256]; }
const unsigned char r(unsigned int index) const { return m_colors[0][index%256]; }
const unsigned char g(unsigned int index) const { return m_colors[1][index%256]; }
const unsigned char b(unsigned int index) const { return m_colors[2][index%256]; }
private:
void rebuild()
{
// build nodes
m_colors[3][0] = 1;
m_colors[3][255] = 1;
unsigned int nb_nodes = 0;
for(int i=0;i<256;i++)
if(m_colors[3][i])
{
m_nodes[nb_nodes] = i;
nb_nodes++;
}
// build Color_ramp
for(int k=0;k<3;k++)
for(unsigned int i=0;i<(nb_nodes-1);i++)
{
int x1 = m_nodes[i];
int x2 = m_nodes[i+1];
int y1 = m_colors[k][x1];
int y2 = m_colors[k][x2];
float a = (float)(y2-y1) / (float)(x2-x1);
float b = (float)y1 - a*(float)x1;
for(int j=x1;j<x2;j++)
m_colors[k][j] = (unsigned char)(a*(float)j+b);
}
}
void rebuild()
{
// build nodes
m_colors[3][0] = 1;
m_colors[3][255] = 1;
unsigned int nb_nodes = 0;
for(int i=0;i<256;i++)
{
if(m_colors[3][i])
{
m_nodes[nb_nodes] = i;
nb_nodes++;
}
}
void reset()
{
for(int i=1;i<=254;i++)
m_colors[3][i] = 0;
m_colors[3][0] = 1;
m_colors[3][255] = 1;
}
// build color_ramp
for(int k=0;k<3;k++)
for(unsigned int i=0;i<(nb_nodes-1);i++)
{
int x1 = m_nodes[i];
int x2 = m_nodes[i+1];
int y1 = m_colors[k][x1];
int y2 = m_colors[k][x2];
float a = (float)(y2-y1) / (float)(x2-x1);
float b = (float)y1 - a*(float)x1;
for(int j=x1;j<x2;j++)
m_colors[k][j] = (unsigned char)(a*(float)j+b);
}
}
void reset()
{
for(int i=1;i<=254;i++)
m_colors[3][i] = 0;
m_colors[3][0] = 1;
m_colors[3][255] = 1;
}
public:
// predefined
void build_default()
{
reset();
add_node(0,0,0,0);
add_node(255,255,255,255);
rebuild();
}
void add_node(unsigned int index,
unsigned char r,
unsigned char g,
unsigned char b)
{
m_colors[3][index] = 1;
m_colors[0][index] = r;
m_colors[1][index] = g;
m_colors[2][index] = b;
}
void build_menthol()
{
reset();
add_node(0,0,0,128);
add_node(48,0,0,254);
add_node(176,0,255,255);
add_node(208,128,255,255);
add_node(255,255,255,255);
rebuild();
}
void add_node(unsigned int index,
unsigned char r,
unsigned char g,
unsigned char b)
{
m_colors[3][index] = 1;
m_colors[0][index] = r;
m_colors[1][index] = g;
m_colors[2][index] = b;
}
void build_red()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 128;m_colors[1][0] = 0;m_colors[2][0] = 0;
m_colors[3][80] = 1;m_colors[0][80] = 255;m_colors[1][80] = 0;m_colors[2][80] = 0;
m_colors[3][160] = 1;m_colors[0][160] = 255;m_colors[1][160] = 128;m_colors[2][160] = 0;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 255;
rebuild();
}
void build_red()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 128;m_colors[1][0] = 0;m_colors[2][0] = 0;
m_colors[3][80] = 1;m_colors[0][80] = 255;m_colors[1][80] = 0;m_colors[2][80] = 0;
m_colors[3][160] = 1;m_colors[0][160] = 255;m_colors[1][160] = 128;m_colors[2][160] = 0;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 255;
rebuild();
}
void build_blue()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 0;m_colors[1][0] = 0;m_colors[2][0] = 128;
m_colors[3][80] = 1;m_colors[0][80] = 0;m_colors[1][80] = 0;m_colors[2][80] = 255;
m_colors[3][160] = 1;m_colors[0][160] = 0;m_colors[1][160] = 255;m_colors[2][160] = 255;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 255;
rebuild();
}
void build_thermal()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 0;m_colors[1][0] = 0;m_colors[2][0] = 0;
m_colors[3][70] = 1;m_colors[0][70] = 128;m_colors[1][70] = 0;m_colors[2][70] = 0;
m_colors[3][165] = 1;m_colors[0][165] = 255;m_colors[1][165] = 128;m_colors[2][165] = 0;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 255;
rebuild();
}
void build_fire()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 0;m_colors[1][0] = 0;m_colors[2][0] = 0;
m_colors[3][92] = 1;m_colors[0][92] = 255;m_colors[1][92] = 0;m_colors[2][92] = 0;
m_colors[3][185] = 1;m_colors[0][185] = 255;m_colors[1][185] = 255;m_colors[2][185] = 0;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 0;
rebuild();
}
void build_rainbow()
{
reset();
add_node(0,0,0,0);
add_node(32,128,0,255);
add_node(80,0,0,255);
add_node(112,0,255,255);
add_node(144,0,255,0);
add_node(176,255,255,0);
add_node(208,255,128,0);
add_node(240,255,0,0);
add_node(255,255,255,255);
rebuild();
}
void build_infrared()
{
reset();
add_node(0,0,0,0);
add_node(32,0,0,128);
add_node(64,128,0,255);
add_node(112,255,0,255);
add_node(160,255,128,0);
add_node(176,255,128,0);
add_node(208,255,255,0);
add_node(255,255,255,255);
rebuild();
}
void build_light_rainbow()
{
reset();
m_colors[3][0] = 1; m_colors[0][0] = 128; m_colors[1][0] = 255; m_colors[2][0] = 255;
m_colors[3][64] = 1; m_colors[0][64] = 168; m_colors[1][64] = 255; m_colors[2][64] = 168;
m_colors[3][128] = 1; m_colors[0][128] = 255; m_colors[1][128] = 255; m_colors[2][128] = 179;
m_colors[3][192] = 1; m_colors[0][192] = 255; m_colors[1][192] = 175; m_colors[2][192] = 175;
m_colors[3][255] = 1; m_colors[0][255] = 255; m_colors[1][255] = 255; m_colors[2][255] = 255;
rebuild();
}
void build_thermal()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 0;m_colors[1][0] = 0;m_colors[2][0] = 0;
m_colors[3][70] = 1;m_colors[0][70] = 128;m_colors[1][70] = 0;m_colors[2][70] = 0;
m_colors[3][165] = 1;m_colors[0][165] = 255;m_colors[1][165] = 128;m_colors[2][165] = 0;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 255;
rebuild();
}
void build_multicolor()
{
reset();
m_colors[3][0] = 1; m_colors[0][0] = 255; m_colors[1][0] = 128; m_colors[2][0] = 192;
m_colors[3][32] = 1; m_colors[0][32] = 0; m_colors[1][32] = 0; m_colors[2][32] = 255;
m_colors[3][64] = 1; m_colors[0][64] = 0; m_colors[1][64] = 255; m_colors[2][64] = 255;
m_colors[3][96] = 1; m_colors[0][96] = 0; m_colors[1][96] = 252; m_colors[2][96] = 0;
m_colors[3][128] = 1; m_colors[0][128] = 255; m_colors[1][128] = 254; m_colors[2][128] = 0;
m_colors[3][176] = 1; m_colors[0][176] = 255; m_colors[1][176] = 128; m_colors[2][176] = 0;
m_colors[3][208] = 1; m_colors[0][208] = 255; m_colors[1][208] = 0; m_colors[2][208] = 0;
m_colors[3][240] = 1; m_colors[0][240] = 192; m_colors[1][240] = 192; m_colors[2][240] = 192;
m_colors[3][255] = 1; m_colors[0][255] = 255; m_colors[1][255] = 255; m_colors[2][255] = 255;
rebuild();
}
void build_random_pastel()
{
reset();
for(int i=0;i<256;i++)
{
m_colors[3][i] = 1;
m_colors[1][i] = 128 + (unsigned char) ((double)rand() / (double)RAND_MAX * 127.0);
m_colors[2][i] = 128 + (unsigned char) ((double)rand() / (double)RAND_MAX * 127.0);
m_colors[3][i] = 128 + (unsigned char) ((double)rand() / (double)RAND_MAX * 127.0);
}
}
void build_blue()
{
reset();
m_colors[3][0] = 1;m_colors[0][0] = 0;m_colors[1][0] = 0;m_colors[2][0] = 128;
m_colors[3][80] = 1;m_colors[0][80] = 0;m_colors[1][80] = 0;m_colors[2][80] = 255;
m_colors[3][160] = 1;m_colors[0][160] = 0;m_colors[1][160] = 255;m_colors[2][160] = 255;
m_colors[3][255] = 1;m_colors[0][255] = 255;m_colors[1][255] = 255;m_colors[2][255] = 255;
rebuild();
}
};
#endif // _COLOR_RAMP_H

View File

@ -41,21 +41,16 @@ The concept \ccRefName\ provides the geometric primitive types and methods for t
\ccTypedef{typedef std::pair<Object, Primitive::Id> Object_and_primitive_id;}{}
During the construction of the \ccc{AABB_tree}, the primitives are sorted according to some comparison functions related to the $x$, $y$ or $z$ coordinate axis:
%\ccMethod{bool less_x(const Primitive & pr1, const Primitive & pr2);}{}
%\ccGlue
%\ccMethod{bool less_y(const Primitive & pr1, const Primitive & pr2);}{}
%\ccGlue
%\ccMethod{bool less_z(const Primitive & pr1, const Primitive & pr2);}{}
\ccNestedType{Split_primitives_along_x_axis}
{A functor object to split a range of primitives into two sub-ranges, along the X-axis. Provides the operator:
{A functor object to split a range of primitives into two sub-ranges along the X-axis. Provides the operator:
\ccc{void operator()(InputIterator first, InputIterator beyond);} Iterator \ccc{InputIterator} must be a model of RandomAccessIterator and have \ccc{Primitive} as value type. The operator is used for determining the primitives assigned to the two children nodes of a given node, assuming that the goal is to split the X-dimension of the bounding box of the node. The primitives assigned to this node are passed as argument to the operator. It should modify the iterator range in such a way that its first half and its second half correspond to the two children nodes.}
\ccNestedType{Split_primitives_along_y_axis}
{A functor object to split a range of primitives into two sub-ranges, along the Y-axis. See \ccc{Split_primitives_along_x_axis} for the detailed description.}
{A functor object to split a range of primitives into two sub-ranges along the Y-axis. See \ccc{Split_primitives_along_x_axis} for the detailed description.}
\ccNestedType{Split_primitives_along_z_axis}
{A functor object to split a range of primitives into two sub-ranges, along the Z-axis. See \ccc{Split_primitives_along_x_axis} for the detailed description.}
{A functor object to split a range of primitives into two sub-ranges along the Z-axis. See \ccc{Split_primitives_along_x_axis} for the detailed description.}
\ccNestedType{Compute_bbox}
{A functor object to compute the bounding box of a set of primitives. Provides the operator:
@ -68,22 +63,10 @@ During the construction of the \ccc{AABB_tree}, the primitives are sorted accord
The following predicates are required for each type \ccc{Query}
for which the class \ccc{AABB_tree<AT>} may receive an intersection detection or computation query.
%\ccMethod{bool do_intersect(const Query & q, const Bounding_box & box);}
%{Returns \ccc{true} iff the query intersects the bounding box.}
%\ccGlue
%\ccMethod{bool do_intersect(const Query & q, const Primitive& primitive);}
%{Returns \ccc{true} iff the query intersects the primitive.}
%\ccGlue
\ccNestedType{Do_intersect}
{A functor object to compute intersection predicates between the query and the nodes of the tree. Provides the operators:
\ccc{bool operator()(const Query & q, const Bounding_box & box);} which returns \ccc{true} iff the query intersects the bounding box, and \ccc{bool operator()(const Query & q, const Primitive & primitive);} which returns \ccc{true} iff the query intersects the primitive.}
% \ccMethod{int do_transversally_intersect(const Query & q, const Primitive& primitive);}
%{Returns 1 iff the query intersects the primitive transversally, returns 0 iff the query does not intersect the primitive and returns a negative error code in case of a non-transversal intersection.}
%\ccGlue
%\ccMethod{boost::optional<Object_and_primitive_id> intersection(const Query & q, const Primitive& primitive);}
%{Returns the intersection as a pair composed of an object and a primitive id, iff the query intersects the primitive.}
%\ccGlue
\ccNestedType{Intersect}
{A functor object to compute the intersection of a query and a primitive. Provides the operator:
\ccc{boost::optional<Object_and_primitive_id> operator()(const Query & q, const Primitive& primitive);} which returns the intersection as a pair composed of an object and a primitive id, iff the query intersects the primitive.}
@ -91,33 +74,20 @@ for which the class \ccc{AABB_tree<AT>} may receive an intersection detection or
The following predicates are required for each type \ccc{Query}
for which the class \ccc{AABB_tree<AT>} may receive a distance query.
%\ccMethod{bool is_closer(const Point & p, const Bounding_box& box, const Point & q);}
%{Returns true, iff the primitive is closer to \ccc{p} than \ccc{q} is.}
%\ccGlue
%\ccMethod{bool is_closer(const Point & p, const Primitive& primitive, const Point & q);}
%{Returns true, iff the primitive is closer to \ccc{p} than \ccc{q} is.}
%\ccGlue
\ccNestedType{Compare_distance}
{A functor object to compute distance comparisons between the query and the nodes of the tree. Provides the operators:
\ccc{bool operator()(const Query & query, const Bounding_box& box, const Point & closest);} which returns \ccc{true} iff the bounding box is closer to \ccc{query} than \ccc{closest} is, and \ccc{bool operator()(const Query & query, const Primitive & primitive, const Point & closest);} which returns \ccc{true} iff \ccc{primitive} is closer to the \ccc{query} than \ccc{closest} is.}
%\ccMethod{Point_3 closest_point(const Point_3 & p, const Primitive& primitive, const Point_3 & q);}
%{Returns the closest point to \ccc{p}, among \ccc{q} and all points of the primitive.}
%\ccGlue
\ccNestedType{Closest_point}
{A functor object to compute closest point from the query on a primitive. Provides the operator:
\ccc{Point_3 operator()(const Query& query, const Primitive& primitive, const Point_3 & closest);} which returns the closest point to \ccc{query}, among \ccc{closest} and all points of the primitive.}
%\ccMethod{FT squared_distance(const Point_3 & p, const Point_3 & q);}
%{Returns the squared distance between \ccc{p} and \ccc{q}.}
\ccNestedType{Squared_distance}
{A functor object to compute the squared distance between the query and a point. Provides the operator:
\ccc{FT operator()(const Query& query, const Point_3 & p);} which returns the squared distance between \ccc{query} and \ccc{p}.}
%\ccCreation
\ccCreationVariable{traits} %% choose variable name
\ccOperations
\ccMethod{Split_primitives_along_x_axis split_primitives_along_x_axis_object();}
@ -144,8 +114,6 @@ for which the class \ccc{AABB_tree<AT>} may receive a distance query.
\ccMethod{Closest_point closest_point_object();}
{Returns the closest point constructor.}
\ccHasModels
\ccc{AABB_traits<GeomTraits,TrianglePrimitive>}.

View File

@ -19,7 +19,7 @@
\ccDefinition
Class \ccRefName\ is a static data structure for efficient intersection and distance computations in 3D. It builds a hierarchy of axis-aligned bounding boxes from a set of 3D geometric objects, and can receive intersection and distance queries, provided that the corresponding predicates are implemented in the traits class \ccc{AT}. The template parameter \ccc{AT} stands for a traits class which must be a model of the concept \ccc{AABBTraits}.
Class \ccRefName\ is a static data structure for efficient intersection and distance computations in 3D. It builds a hierarchy of axis-aligned bounding boxes (a AABB tree) from a set of 3D geometric objects, and can receive intersection and distance queries, provided that the corresponding predicates are implemented in the traits class \ccc{AT}. The template parameter \ccc{AT} stands for a traits class which must be a model of the concept \ccc{AABBTraits}.
\ccInclude{CGAL/AABB_tree.h}
@ -46,10 +46,8 @@ Class \ccRefName\ is a static data structure for efficient intersection and dist
\ccTypedef{std::pair<CGAL::Object, Primitive::Id> Object_and_primitive_id;}
{}
%\ccNestedType{}{some nested types}
\ccCreation
\ccCreationVariable{tree} %% variable name
\ccCreationVariable{tree}
\ccConstructor{AABB_tree(AT at = AT());}{Constructs an empty tree.}
\ccConstructor{template < class InputIterator>

View File

@ -30,11 +30,6 @@
#include <CGAL/number_utils.h>
#include "Bbox_3_plane_3_do_intersect.h"
// Turn off Visual C++ warning
//#ifdef _MSC_VER
//#pragma warning ( disable : 4003 )
//#endif
CGAL_BEGIN_NAMESPACE
namespace CGALi {

View File

@ -1 +1 @@
This component implements a hierarchy of axis-aligned bounding boxes (AABBs) for efficient intersection and distance computations between 3D queries and sets of bounded 3D input geometric objects.
This component implements a hierarchy of axis-aligned bounding boxes (a AABB tree) for efficient intersection and distance computations between 3D queries and sets of input 3D geometric objects.

View File

@ -529,8 +529,6 @@ private:
}
timer.stop();
// std::cerr << "\t" << nb_test << " loops in "
// << timer.time() << "s" << std::endl;
m_naive_time += test.naive_timer.time();
m_tree_time += test.tree_timer.time();
}
@ -750,7 +748,6 @@ private:
FT dist_naive = CGAL::squared_distance(query, point_naive);
FT dist_tree = CGAL::squared_distance(query, point_tree);
//assert( dist_tree >= dist_naive );
const FT epsilon = (FT)1e-6;
assert( (dist_naive - dist_tree) <= (epsilon * dist_tree) );
assert( (dist_naive - dist_tree) >= (-1. * epsilon * dist_tree) );
@ -786,7 +783,6 @@ private:
FT dist_naive = CGAL::squared_distance(query, point_naive.first);
FT dist_tree = CGAL::squared_distance(query, point_tree.first);
//assert( dist_tree >= dist_naive );
const FT epsilon = (FT)1e-6;
assert( (dist_naive - dist_tree) <= (epsilon * dist_tree) );
assert( (dist_naive - dist_tree) >= (-1 * epsilon * dist_tree) );