diff --git a/vcg/space/index/octree.h b/vcg/space/index/octree.h index 4076f312..4330e154 100644 --- a/vcg/space/index/octree.h +++ b/vcg/space/index/octree.h @@ -29,12 +29,15 @@ #include #include +#ifdef __glut_h__ #include +#include +#endif + #include #include #include #include -#include namespace vcg { @@ -131,25 +134,6 @@ namespace vcg 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: /*********************************************** * INNER DATA STRUCTURES AND PREDICATES * @@ -229,16 +213,6 @@ namespace vcg 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() ); placeholders[placeholder_index].z_order = BuildRoute(hit_leaf, route); 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: - // we propaget the indexing information bottom-up to the root + // we propagate the indexing information bottom-up to the root IndexInnerNodes( TemplatedOctree::Root() ); } //end of Set @@ -379,7 +353,7 @@ public: const ScalarType & max_distance, ScalarType & distance, CoordType & point, - bool allow_zero_distance = false + bool allow_zero_distance = true ) { BoundingBoxType query_bb; @@ -389,81 +363,36 @@ public: std::vector< NodePointer > leaves; - unsigned int object_count; - int leaves_count; - ScalarType k_distance = TemplatedOctree::leafDiagonal; + //unsigned int object_count; + //int leaves_count; IncrementMark(); - - do - { - leaves.clear(); - object_count = 0; - query_bb.Offset(k_distance); - sphere_radius += vcg::math::Max(TemplatedOctree::leafDiagonal, k_distance); - - ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox); - - leaves_count = int(leaves.size()); - object_count = 0; - for (int i=0; icount; - } - while (object_count==0 && sphere_radiusmax_distance) return NULL; - - - CoordType closest_point; - VoxelType *voxel; - ObjectReference *ref; - int begin; - int end; - ScalarType dist; std::vector< Neighbour > neighbors; - object_count = 0; - for (int i=0; ibegin; - end = voxel->end; - for ( ; beginpObject, 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::iterator first = neighbors.begin(); - typename std::vector< Neighbour >::iterator last = neighbors.end(); - std::partial_sort< Neighbour >(first, first+object_count, last/*, DistanceCompare()*/); + typename std::vector< Neighbour >::iterator last = neighbors.end(); + std::partial_sort(first, first+1, last); + distance = neighbors[0].distance; point = neighbors[0].point; return neighbors[0].object; }; //end of GetClosest /*! - * Retrive the k closest element to the query point + * Retrieve the k closest element to the query point */ template unsigned int GetKClosest ( OBJECT_POINT_DISTANCE_FUNCTOR & distance_functor, OBJECT_MARKER & /*marker*/, - unsigned int k, + unsigned int k, const CoordType & query_point, const ScalarType & max_distance, OBJECT_POINTER_CONTAINER & objects, @@ -482,82 +411,26 @@ public: std::vector< Neighbour > neighbors; unsigned int object_count; - int leaves_count; - float k_distance = TemplatedOctree::leafDiagonal; - do - { - IncrementMark(); + float k_distance; - do - { - leaves.clear(); - object_count = 0; - query_bb.Offset(k_distance); - sphere_radius += vcg::math::Max(TemplatedOctree::leafDiagonal, k_distance); +OBJECT_RETRIEVER: + IncrementMark(); + AdjustBoundingBox(query_bb, sphere_radius, max_distance, leaves, k); + object_count = RetrieveContainedObjects(query_point, distance_functor, max_distance, allow_zero_distance, leaves, neighbors); - ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox); + if (sphere_radiuscount; - } - while (object_countbegin; - end = voxel->end; - for ( ; beginpObject, 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(first, first+object_count, last /*, DistanceCompare()*/ ); - else std::nth_element < NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ ); - k_distance = neighbors[object_count-1].distance; - } - while (k_distance>sphere_radius && sphere_radius(first, first+object_count, last ); + else std::nth_element < NeighbourIterator >(first, first+object_count, last ); + + k_distance = neighbors[object_count-1].distance; + if (k_distance>sphere_radius && sphere_radius(neighbors, object_count, objects, distances, points); }; //end of GetKClosest @@ -590,9 +463,6 @@ public: std::vector< NodePointer > leaves; std::vector< Neighbour > neighbors; - unsigned int object_count = 0; - //float k_distance = TemplatedOctree::leafDiagonal; - IncrementMark(); ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox); @@ -600,40 +470,12 @@ public: if (leaves_count==0) return 0; - CoordType closest_point; - VoxelType *voxel; - ObjectReference *ref; - int begin; - int end; - float distance; - for (int i=0; ibegin; - end = voxel->end; - for ( ; beginpObject, sphere_center, distance, closest_point)) - continue; - - Mark(ref); - if ((distance!=0.0f || allow_zero_distance) && distancepObject, closest_point, distance) ); - } - } //end of for ( ; begin(first, last, last /*, DistanceCompare()*/ ); - else std::nth_element < NeighbourIterator >(first, last, last /*, DistanceCompare()*/ ); + NeighbourIterator last = neighbors.end(); + if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, first+object_count, last ); + else std::nth_element < NeighbourIterator >(first, first+object_count, last ); return CopyQueryResults(neighbors, object_count, objects, distances, points); };//end of GetInSphere @@ -661,33 +503,23 @@ public: unsigned int object_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()); if (leaves_count==0) - { - objects.clear(); return 0; - } IncrementMark(); - - VoxelType *voxel; - ObjectReference *ref; - int begin; - int end; - object_count = 0; for (int i=0; ibegin; - end = voxel->end; + VoxelType *voxel = TemplatedOctree::Voxel(leaves[i]); + int begin = voxel->begin; + int end = voxel->end; for ( ; beginpObject); } //end of for ( ; beginlevel) - { - for (int s=0; s<8; s++) - if ((son=Son(n, s))!=0) - DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son); - } - else - { - vcg::glBoxWire(boundingBox); - if (levelmax_distance); // TODO check the termination condintion + while ( !TemplatedOctree::boundingBox.Collide(query_bb) || 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; icount; + } + while (object_count + 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()); ibegin; + int end = voxel->end; + for ( ; beginpObject, 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 ( ; beginlevel) + { + 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