just few rearrangements...
This commit is contained in:
parent
f786e138ee
commit
fe32dbea36
|
|
@ -29,12 +29,15 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
#ifdef __glut_h__
|
||||||
#include <vcg/space/color4.h>
|
#include <vcg/space/color4.h>
|
||||||
|
#include <wrap/gl/space.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vcg/space/index/base.h>
|
#include <vcg/space/index/base.h>
|
||||||
#include <vcg/space/index/octree_template.h>
|
#include <vcg/space/index/octree_template.h>
|
||||||
#include <vcg/space/box3.h>
|
#include <vcg/space/box3.h>
|
||||||
#include <wrap/callback.h>
|
#include <wrap/callback.h>
|
||||||
#include <wrap/gl/space.h>
|
|
||||||
|
|
||||||
namespace vcg
|
namespace vcg
|
||||||
{
|
{
|
||||||
|
|
@ -131,25 +134,6 @@ namespace vcg
|
||||||
|
|
||||||
typedef typename std::vector< Neighbour >::iterator NeighbourIterator;
|
typedef typename std::vector< Neighbour >::iterator NeighbourIterator;
|
||||||
|
|
||||||
/*!
|
|
||||||
* Structure which holds the rendering settings
|
|
||||||
*/
|
|
||||||
struct OcreeRenderingSetting
|
|
||||||
{
|
|
||||||
OcreeRenderingSetting()
|
|
||||||
{
|
|
||||||
color = vcg::Color4b(155, 155, 155, 255);
|
|
||||||
isVisible = false;
|
|
||||||
minVisibleDepth = 1;
|
|
||||||
maxVisibleDepth = 4;
|
|
||||||
};
|
|
||||||
|
|
||||||
int isVisible;
|
|
||||||
int minVisibleDepth;
|
|
||||||
int maxVisibleDepth;
|
|
||||||
vcg::Color4b color;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/***********************************************
|
/***********************************************
|
||||||
* INNER DATA STRUCTURES AND PREDICATES *
|
* INNER DATA STRUCTURES AND PREDICATES *
|
||||||
|
|
@ -229,16 +213,6 @@ namespace vcg
|
||||||
ScalarType distance;
|
ScalarType distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
// /*
|
|
||||||
// * The operator used for sorting the items in neighbors based on the distances
|
|
||||||
// */
|
|
||||||
// struct DistanceCompare
|
|
||||||
// {
|
|
||||||
// inline bool operator()( const Neighbour &p1, const Neighbour &p2) const { return p1.distance<p2.distance; }
|
|
||||||
// }; //end of DistanceCompare
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Octree()
|
~Octree()
|
||||||
{
|
{
|
||||||
|
|
@ -277,7 +251,7 @@ public:
|
||||||
TemplatedOctree::boundingBox = resulting_bb;
|
TemplatedOctree::boundingBox = resulting_bb;
|
||||||
|
|
||||||
// Try to find a reasonable octree depth
|
// Try to find a reasonable octree depth
|
||||||
int dataset_dimension = std::distance(bObj, eObj);
|
int dataset_dimension = int(std::distance(bObj, eObj));
|
||||||
|
|
||||||
int primitives_per_voxel;
|
int primitives_per_voxel;
|
||||||
int depth = 4;
|
int depth = 4;
|
||||||
|
|
@ -308,7 +282,7 @@ public:
|
||||||
|
|
||||||
while (object_bb.IsIn(hit_leaf))
|
while (object_bb.IsIn(hit_leaf))
|
||||||
{
|
{
|
||||||
int placeholder_index = placeholders.size();
|
int placeholder_index = int(placeholders.size());
|
||||||
placeholders.push_back( ObjectPlaceholder< NodeType >() );
|
placeholders.push_back( ObjectPlaceholder< NodeType >() );
|
||||||
placeholders[placeholder_index].z_order = BuildRoute(hit_leaf, route);
|
placeholders[placeholder_index].z_order = BuildRoute(hit_leaf, route);
|
||||||
placeholders[placeholder_index].leaf_pointer = route[depth];
|
placeholders[placeholder_index].leaf_pointer = route[depth];
|
||||||
|
|
@ -363,7 +337,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// The octree is built, the dataset is sorted but only the leaves are indexed:
|
// The octree is built, the dataset is sorted but only the leaves are indexed:
|
||||||
// we propaget the indexing information bottom-up to the root
|
// we propagate the indexing information bottom-up to the root
|
||||||
IndexInnerNodes( TemplatedOctree::Root() );
|
IndexInnerNodes( TemplatedOctree::Root() );
|
||||||
} //end of Set
|
} //end of Set
|
||||||
|
|
||||||
|
|
@ -379,7 +353,7 @@ public:
|
||||||
const ScalarType & max_distance,
|
const ScalarType & max_distance,
|
||||||
ScalarType & distance,
|
ScalarType & distance,
|
||||||
CoordType & point,
|
CoordType & point,
|
||||||
bool allow_zero_distance = false
|
bool allow_zero_distance = true
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BoundingBoxType query_bb;
|
BoundingBoxType query_bb;
|
||||||
|
|
@ -389,74 +363,29 @@ public:
|
||||||
|
|
||||||
std::vector< NodePointer > leaves;
|
std::vector< NodePointer > leaves;
|
||||||
|
|
||||||
unsigned int object_count;
|
//unsigned int object_count;
|
||||||
int leaves_count;
|
//int leaves_count;
|
||||||
ScalarType k_distance = TemplatedOctree::leafDiagonal;
|
|
||||||
|
|
||||||
IncrementMark();
|
IncrementMark();
|
||||||
|
AdjustBoundingBox(query_bb, sphere_radius, max_distance, leaves, 1);
|
||||||
do
|
|
||||||
{
|
|
||||||
leaves.clear();
|
|
||||||
object_count = 0;
|
|
||||||
query_bb.Offset(k_distance);
|
|
||||||
sphere_radius += vcg::math::Max<ScalarType>(TemplatedOctree::leafDiagonal, k_distance);
|
|
||||||
|
|
||||||
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
|
||||||
|
|
||||||
leaves_count = int(leaves.size());
|
|
||||||
object_count = 0;
|
|
||||||
for (int i=0; i<leaves_count; i++)
|
|
||||||
object_count += TemplatedOctree::Voxel( leaves[i] )->count;
|
|
||||||
}
|
|
||||||
while (object_count==0 && sphere_radius<max_distance);
|
|
||||||
|
|
||||||
if (sphere_radius>max_distance)
|
if (sphere_radius>max_distance)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
CoordType closest_point;
|
|
||||||
VoxelType *voxel;
|
|
||||||
ObjectReference *ref;
|
|
||||||
int begin;
|
|
||||||
int end;
|
|
||||||
ScalarType dist;
|
|
||||||
|
|
||||||
std::vector< Neighbour > neighbors;
|
std::vector< Neighbour > neighbors;
|
||||||
object_count = 0;
|
RetrieveContainedObjects(query_point, distance_functor, max_distance, allow_zero_distance, leaves, neighbors);
|
||||||
for (int i=0; i<leaves_count; i++)
|
|
||||||
{
|
|
||||||
voxel = TemplatedOctree::Voxel(leaves[i]);
|
|
||||||
begin = voxel->begin;
|
|
||||||
end = voxel->end;
|
|
||||||
for ( ; begin<end; begin++)
|
|
||||||
{
|
|
||||||
ref = &sorted_dataset[begin];
|
|
||||||
if (IsMarked(ref))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dist = max_distance;
|
|
||||||
if (!distance_functor(*ref->pObject, query_point, dist, closest_point))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Mark(ref);
|
|
||||||
if (dist!=ScalarType(0.0) || allow_zero_distance)
|
|
||||||
neighbors.push_back( Neighbour(ref->pObject, closest_point, dist) );
|
|
||||||
|
|
||||||
} //end of for ( ; begin<end; begin++)
|
|
||||||
} // end of for (int i=0; i<leavesCount; i++)
|
|
||||||
|
|
||||||
object_count = int(neighbors.size());
|
|
||||||
typename std::vector< Neighbour >::iterator first = neighbors.begin();
|
typename std::vector< Neighbour >::iterator first = neighbors.begin();
|
||||||
typename std::vector< Neighbour >::iterator last = neighbors.end();
|
typename std::vector< Neighbour >::iterator last = neighbors.end();
|
||||||
std::partial_sort< Neighbour >(first, first+object_count, last/*, DistanceCompare()*/);
|
std::partial_sort(first, first+1, last);
|
||||||
|
|
||||||
distance = neighbors[0].distance;
|
distance = neighbors[0].distance;
|
||||||
point = neighbors[0].point;
|
point = neighbors[0].point;
|
||||||
return neighbors[0].object;
|
return neighbors[0].object;
|
||||||
}; //end of GetClosest
|
}; //end of GetClosest
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Retrive the k closest element to the query point
|
* Retrieve the k closest element to the query point
|
||||||
*/
|
*/
|
||||||
template <class OBJECT_POINT_DISTANCE_FUNCTOR, class OBJECT_MARKER, class OBJECT_POINTER_CONTAINER, class DISTANCE_CONTAINER, class POINT_CONTAINER>
|
template <class OBJECT_POINT_DISTANCE_FUNCTOR, class OBJECT_MARKER, class OBJECT_POINTER_CONTAINER, class DISTANCE_CONTAINER, class POINT_CONTAINER>
|
||||||
unsigned int GetKClosest
|
unsigned int GetKClosest
|
||||||
|
|
@ -482,82 +411,26 @@ public:
|
||||||
std::vector< Neighbour > neighbors;
|
std::vector< Neighbour > neighbors;
|
||||||
|
|
||||||
unsigned int object_count;
|
unsigned int object_count;
|
||||||
int leaves_count;
|
float k_distance;
|
||||||
float k_distance = TemplatedOctree::leafDiagonal;
|
|
||||||
do
|
OBJECT_RETRIEVER:
|
||||||
{
|
|
||||||
IncrementMark();
|
IncrementMark();
|
||||||
|
AdjustBoundingBox(query_bb, sphere_radius, max_distance, leaves, k);
|
||||||
|
object_count = RetrieveContainedObjects(query_point, distance_functor, max_distance, allow_zero_distance, leaves, neighbors);
|
||||||
|
|
||||||
do
|
if (sphere_radius<max_distance && object_count<k)
|
||||||
{
|
goto OBJECT_RETRIEVER;
|
||||||
leaves.clear();
|
|
||||||
object_count = 0;
|
|
||||||
query_bb.Offset(k_distance);
|
|
||||||
sphere_radius += vcg::math::Max<float>(TemplatedOctree::leafDiagonal, k_distance);
|
|
||||||
|
|
||||||
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
|
||||||
|
|
||||||
leaves_count = int(leaves.size());
|
|
||||||
object_count = 0;
|
|
||||||
for (int i=0; i<leaves_count; i++)
|
|
||||||
object_count += TemplatedOctree::Voxel( leaves[i] )->count;
|
|
||||||
}
|
|
||||||
while (object_count<k && sphere_radius<max_distance); // TODO check the termination condintion
|
|
||||||
|
|
||||||
// i punti contenuti nelle foglie sono sufficienti.
|
|
||||||
// seleziono solamente i k punti più vicini.
|
|
||||||
CoordType closest_point;
|
|
||||||
VoxelType *voxel;
|
|
||||||
ObjectReference *ref;
|
|
||||||
int begin;
|
|
||||||
int end;
|
|
||||||
float distance;
|
|
||||||
|
|
||||||
neighbors.clear();
|
|
||||||
object_count = 0;
|
|
||||||
for (int i=0; i<leaves_count; i++)
|
|
||||||
{
|
|
||||||
voxel = TemplatedOctree::Voxel(leaves[i]);
|
|
||||||
begin = voxel->begin;
|
|
||||||
end = voxel->end;
|
|
||||||
for ( ; begin<end; begin++)
|
|
||||||
{
|
|
||||||
ref = &sorted_dataset[begin];
|
|
||||||
if (IsMarked(ref))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
distance = max_distance;
|
|
||||||
if (!distance_functor(*ref->pObject, query_point, distance, closest_point))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Mark(ref);
|
|
||||||
if ((distance!=0.0f || allow_zero_distance))
|
|
||||||
neighbors.push_back( Neighbour(ref->pObject, closest_point, distance) );
|
|
||||||
} //end of for ( ; begin<end; begin++)
|
|
||||||
} // end of for (int i=0; i<leavesCount; i++)
|
|
||||||
|
|
||||||
object_count = int(neighbors.size());
|
|
||||||
if (sphere_radius<max_distance)
|
|
||||||
{
|
|
||||||
if (object_count<k)
|
|
||||||
{
|
|
||||||
k_distance = 2.0f*sphere_radius;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
object_count = k;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
object_count=int(neighbors.size());
|
|
||||||
|
|
||||||
NeighbourIterator first = neighbors.begin();
|
NeighbourIterator first = neighbors.begin();
|
||||||
NeighbourIterator last = neighbors.end();
|
NeighbourIterator last = neighbors.end();
|
||||||
|
|
||||||
if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ );
|
object_count = vcg::math::Min(k, object_count);
|
||||||
else std::nth_element < NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ );
|
if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, first+object_count, last );
|
||||||
|
else std::nth_element < NeighbourIterator >(first, first+object_count, last );
|
||||||
|
|
||||||
k_distance = neighbors[object_count-1].distance;
|
k_distance = neighbors[object_count-1].distance;
|
||||||
}
|
if (k_distance>sphere_radius && sphere_radius<max_distance)
|
||||||
while (k_distance>sphere_radius && sphere_radius<max_distance);
|
goto OBJECT_RETRIEVER;
|
||||||
|
|
||||||
return CopyQueryResults<OBJECT_POINTER_CONTAINER, DISTANCE_CONTAINER, POINT_CONTAINER>(neighbors, object_count, objects, distances, points);
|
return CopyQueryResults<OBJECT_POINTER_CONTAINER, DISTANCE_CONTAINER, POINT_CONTAINER>(neighbors, object_count, objects, distances, points);
|
||||||
}; //end of GetKClosest
|
}; //end of GetKClosest
|
||||||
|
|
@ -590,9 +463,6 @@ public:
|
||||||
std::vector< NodePointer > leaves;
|
std::vector< NodePointer > leaves;
|
||||||
std::vector< Neighbour > neighbors;
|
std::vector< Neighbour > neighbors;
|
||||||
|
|
||||||
unsigned int object_count = 0;
|
|
||||||
//float k_distance = TemplatedOctree::leafDiagonal;
|
|
||||||
|
|
||||||
IncrementMark();
|
IncrementMark();
|
||||||
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
||||||
|
|
||||||
|
|
@ -600,40 +470,12 @@ public:
|
||||||
if (leaves_count==0)
|
if (leaves_count==0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
CoordType closest_point;
|
int object_count = RetrieveContainedObjects(sphere_center, distance_functor, sphere_radius, allow_zero_distance, leaves, neighbors);
|
||||||
VoxelType *voxel;
|
|
||||||
ObjectReference *ref;
|
|
||||||
int begin;
|
|
||||||
int end;
|
|
||||||
float distance;
|
|
||||||
for (int i=0; i<leaves_count; i++)
|
|
||||||
{
|
|
||||||
voxel = TemplatedOctree::Voxel(leaves[i]);
|
|
||||||
begin = voxel->begin;
|
|
||||||
end = voxel->end;
|
|
||||||
for ( ; begin<end; begin++)
|
|
||||||
{
|
|
||||||
ref = &sorted_dataset[begin];
|
|
||||||
if (IsMarked(ref))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
distance = sphere_radius;
|
|
||||||
if (!distance_functor(*ref->pObject, sphere_center, distance, closest_point))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Mark(ref);
|
|
||||||
if ((distance!=0.0f || allow_zero_distance) && distance<sphere_radius)
|
|
||||||
{
|
|
||||||
object_count++;
|
|
||||||
neighbors.push_back( Neighbour(ref->pObject, closest_point, distance) );
|
|
||||||
}
|
|
||||||
} //end of for ( ; begin<end; begin++)
|
|
||||||
} // end of for (int i=0; i<leavesCount; i++)
|
|
||||||
|
|
||||||
NeighbourIterator first = neighbors.begin();
|
NeighbourIterator first = neighbors.begin();
|
||||||
NeighbourIterator last = neighbors.end();
|
NeighbourIterator last = neighbors.end();
|
||||||
if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, last, last /*, DistanceCompare()*/ );
|
if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, first+object_count, last );
|
||||||
else std::nth_element < NeighbourIterator >(first, last, last /*, DistanceCompare()*/ );
|
else std::nth_element < NeighbourIterator >(first, first+object_count, last );
|
||||||
|
|
||||||
return CopyQueryResults<OBJECT_POINTER_CONTAINER, DISTANCE_CONTAINER, POINT_CONTAINER>(neighbors, object_count, objects, distances, points);
|
return CopyQueryResults<OBJECT_POINTER_CONTAINER, DISTANCE_CONTAINER, POINT_CONTAINER>(neighbors, object_count, objects, distances, points);
|
||||||
};//end of GetInSphere
|
};//end of GetInSphere
|
||||||
|
|
@ -661,33 +503,23 @@ public:
|
||||||
unsigned int object_count;
|
unsigned int object_count;
|
||||||
int leaves_count;
|
int leaves_count;
|
||||||
|
|
||||||
ContainedLeaves(query_bounding_box, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
TemplatedOctree::ContainedLeaves(query_bounding_box, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
||||||
leaves_count = int(leaves.size());
|
leaves_count = int(leaves.size());
|
||||||
if (leaves_count==0)
|
if (leaves_count==0)
|
||||||
{
|
|
||||||
objects.clear();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
IncrementMark();
|
IncrementMark();
|
||||||
|
|
||||||
VoxelType *voxel;
|
|
||||||
ObjectReference *ref;
|
|
||||||
int begin;
|
|
||||||
int end;
|
|
||||||
object_count = 0;
|
|
||||||
for (int i=0; i<leaves_count; i++)
|
for (int i=0; i<leaves_count; i++)
|
||||||
{
|
{
|
||||||
voxel = TemplatedOctree::Voxel(leaves[i]);
|
VoxelType *voxel = TemplatedOctree::Voxel(leaves[i]);
|
||||||
begin = voxel->begin;
|
int begin = voxel->begin;
|
||||||
end = voxel->end;
|
int end = voxel->end;
|
||||||
for ( ; begin<end; begin++)
|
for ( ; begin<end; begin++)
|
||||||
{
|
{
|
||||||
ref = &sorted_dataset[begin];
|
ObjectReference *ref = &sorted_dataset[begin];
|
||||||
if (IsMarked(ref))
|
if (IsMarked(ref))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
object_count++;
|
|
||||||
Mark(ref);
|
Mark(ref);
|
||||||
objects.push_back(ref->pObject);
|
objects.push_back(ref->pObject);
|
||||||
} //end of for ( ; begin<end; begin++)
|
} //end of for ( ; begin<end; begin++)
|
||||||
|
|
@ -696,29 +528,6 @@ public:
|
||||||
return int(objects.size());
|
return int(objects.size());
|
||||||
}; //end of GetInBox
|
}; //end of GetInBox
|
||||||
|
|
||||||
/*
|
|
||||||
* Draw the octree in a valid OpenGL context according to the rendering settings
|
|
||||||
*/
|
|
||||||
void DrawOctree(vcg::Box3f &boundingBox, NodePointer n)
|
|
||||||
{
|
|
||||||
char level = TemplatedOctree::Level(n);
|
|
||||||
NodePointer son;
|
|
||||||
if (rendering_settings.minVisibleDepth>level)
|
|
||||||
{
|
|
||||||
for (int s=0; s<8; s++)
|
|
||||||
if ((son=Son(n, s))!=0)
|
|
||||||
DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vcg::glBoxWire(boundingBox);
|
|
||||||
if (level<rendering_settings.maxVisibleDepth)
|
|
||||||
for (int s=0; s<8; s++)
|
|
||||||
if ((son=Son(n, s))!=0)
|
|
||||||
DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
* Contains pointer to the objects in the dataset.
|
* Contains pointer to the objects in the dataset.
|
||||||
|
|
@ -732,8 +541,17 @@ public:
|
||||||
unsigned char *marks;
|
unsigned char *marks;
|
||||||
unsigned char global_mark;
|
unsigned char global_mark;
|
||||||
|
|
||||||
public:
|
/*!
|
||||||
OcreeRenderingSetting rendering_settings;
|
* The expansion factor used to solve the spatial queries
|
||||||
|
* The current expansion factor is computed on the basis of the last expansion factor
|
||||||
|
* and on the history of these values, through the following heuristic:
|
||||||
|
* current_expansion_factor = alpha*last_expansion_factor + (1.0f-alpha)*mean_expansion_factor
|
||||||
|
* where alpha = 1.0/3.0;
|
||||||
|
*/
|
||||||
|
//float last_expansion_factor;
|
||||||
|
//float mean_expansion_factor;
|
||||||
|
//float ALPHA;
|
||||||
|
//float ONE_MINUS_ALPHA;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -770,10 +588,10 @@ public:
|
||||||
// Altrimenti espando il bounding box.
|
// Altrimenti espando il bounding box.
|
||||||
query_bb.Set(query_point);
|
query_bb.Set(query_point);
|
||||||
|
|
||||||
// Il raggio della sfera centrata nel punto query
|
// the radius of the sphere centered in query
|
||||||
sphere_radius = 0.0f;
|
sphere_radius = 0.0f;
|
||||||
|
|
||||||
// se il bounding-box non interseca il bounding-box dell'octree, lo espando subito
|
// if the bounding-box doesn't intersect the bounding-box of the octree, then it must be immediately expanded
|
||||||
if (!query_bb.IsIn(query_point))
|
if (!query_bb.IsIn(query_point))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
|
@ -781,11 +599,86 @@ public:
|
||||||
query_bb.Offset(TemplatedOctree::leafDiagonal);
|
query_bb.Offset(TemplatedOctree::leafDiagonal);
|
||||||
sphere_radius += TemplatedOctree::leafDiagonal;
|
sphere_radius += TemplatedOctree::leafDiagonal;
|
||||||
}
|
}
|
||||||
while ( !TemplatedOctree::boundingBox.Collide(query_bb) || sphere_radius>max_distance); // TODO check the termination condintion
|
while ( !TemplatedOctree::boundingBox.Collide(query_bb) || sphere_radius>max_distance);
|
||||||
}
|
}
|
||||||
return (sphere_radius<=max_distance);
|
return (sphere_radius<=max_distance);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Modify the bounding-box used during the query until either at least k points
|
||||||
|
* are contained inside the box or the box radius became greater than the threshold distance
|
||||||
|
* Return the number of leaves contained inside the bounding-box
|
||||||
|
*/
|
||||||
|
inline int AdjustBoundingBox
|
||||||
|
(
|
||||||
|
BoundingBoxType & query_bb,
|
||||||
|
ScalarType & sphere_radius,
|
||||||
|
const ScalarType max_allowed_distance,
|
||||||
|
std::vector< NodePointer > & leaves,
|
||||||
|
const int required_object_count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int leaves_count;
|
||||||
|
int object_count;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
leaves.clear();
|
||||||
|
|
||||||
|
query_bb.Offset(TemplatedOctree::leafDiagonal);
|
||||||
|
sphere_radius+= TemplatedOctree::leafDiagonal;
|
||||||
|
|
||||||
|
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
|
||||||
|
|
||||||
|
leaves_count = int(leaves.size());
|
||||||
|
object_count = 0;
|
||||||
|
for (int i=0; i<leaves_count; i++)
|
||||||
|
object_count += TemplatedOctree::Voxel( leaves[i] )->count;
|
||||||
|
}
|
||||||
|
while (object_count<required_object_count && sphere_radius<max_allowed_distance);
|
||||||
|
|
||||||
|
return leaves_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Retrieves the objects contained inside the leaves whose distance isn't greater than max_distance.
|
||||||
|
* Returns the number of valid objects
|
||||||
|
*/
|
||||||
|
template < class OBJECT_POINT_DISTANCE_FUNCTOR >
|
||||||
|
inline int RetrieveContainedObjects
|
||||||
|
(
|
||||||
|
const CoordType query_point,
|
||||||
|
OBJECT_POINT_DISTANCE_FUNCTOR & distance_functor,
|
||||||
|
const ScalarType max_allowed_distance,
|
||||||
|
bool allow_zero_distance,
|
||||||
|
std::vector< NodePointer > & leaves,
|
||||||
|
std::vector< Neighbour > & neighbors
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CoordType closest_point;
|
||||||
|
neighbors.clear();
|
||||||
|
for (int i=0, leaves_count=int(leaves.size()); i<leaves_count; i++)
|
||||||
|
{
|
||||||
|
VoxelType *voxel = TemplatedOctree::Voxel(leaves[i]);
|
||||||
|
int begin = voxel->begin;
|
||||||
|
int end = voxel->end;
|
||||||
|
for ( ; begin<end; begin++)
|
||||||
|
{
|
||||||
|
ObjectReference * ref = &sorted_dataset[begin];
|
||||||
|
if (IsMarked(ref))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ScalarType distance = max_allowed_distance;
|
||||||
|
if (!distance_functor(*ref->pObject, query_point, distance, closest_point))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Mark(ref);
|
||||||
|
if ((distance!=ScalarType(0.0) || allow_zero_distance))
|
||||||
|
neighbors.push_back( Neighbour(ref->pObject, closest_point, distance) );
|
||||||
|
} //end of for ( ; begin<end; begin++)
|
||||||
|
} // end of for (int i=0; i<leavesCount; i++)
|
||||||
|
return int(neighbors.size());
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Copy the results of a query
|
* Copy the results of a query
|
||||||
*/
|
*/
|
||||||
|
|
@ -839,6 +732,57 @@ public:
|
||||||
}
|
}
|
||||||
}; // end of IndexInnerNodes
|
}; // end of IndexInnerNodes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __glut_h__
|
||||||
|
/************************************************************************/
|
||||||
|
/* Rendering */
|
||||||
|
/************************************************************************/
|
||||||
|
protected:
|
||||||
|
/*!
|
||||||
|
* Structure which holds the rendering settings
|
||||||
|
*/
|
||||||
|
struct OcreeRenderingSetting
|
||||||
|
{
|
||||||
|
OcreeRenderingSetting()
|
||||||
|
{
|
||||||
|
color = vcg::Color4b(155, 155, 155, 255);
|
||||||
|
isVisible = false;
|
||||||
|
minVisibleDepth = 1;
|
||||||
|
maxVisibleDepth = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
int isVisible;
|
||||||
|
int minVisibleDepth;
|
||||||
|
int maxVisibleDepth;
|
||||||
|
vcg::Color4b color;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Draw the octree in a valid OpenGL context according to the rendering settings
|
||||||
|
*/
|
||||||
|
void DrawOctree(vcg::Box3f &boundingBox, NodePointer n)
|
||||||
|
{
|
||||||
|
char level = TemplatedOctree::Level(n);
|
||||||
|
NodePointer son;
|
||||||
|
if (rendering_settings.minVisibleDepth>level)
|
||||||
|
{
|
||||||
|
for (int s=0; s<8; s++)
|
||||||
|
if ((son=Son(n, s))!=0)
|
||||||
|
DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vcg::glBoxWire(boundingBox);
|
||||||
|
if (level<rendering_settings.maxVisibleDepth)
|
||||||
|
for (int s=0; s<8; s++)
|
||||||
|
if ((son=Son(n, s))!=0)
|
||||||
|
DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OcreeRenderingSetting rendering_settings;
|
||||||
|
#endif
|
||||||
} //end of namespace vcg
|
} //end of namespace vcg
|
||||||
|
|
||||||
#endif //VCG_SPACE_INDEX_OCTREE_H
|
#endif //VCG_SPACE_INDEX_OCTREE_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue