changed variable naming in several classes to match CGAL standard

octree now uses size_t instead of singed integers
added missing Plane::d() function to retrieve d parameter from plane equation (= - distance from origin)
changed many variables from int to size_t to remove 64 bit warnings
This commit is contained in:
Sven Oesau 2015-06-17 10:27:14 +02:00
parent 114aa3e6c2
commit dfba7e2ce0
9 changed files with 322 additions and 188 deletions

View File

@ -41,6 +41,7 @@
//boost --------------
#include <boost/iterator/counting_iterator.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
//---------------------
@ -107,8 +108,15 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Shape_range;
#else
typedef
Iterator_range<typename std::vector<boost::shared_ptr<Shape> >::const_iterator> Shape_range;
struct Shape_range : public Iterator_range<
typename std::vector<boost::shared_ptr<Shape> >::const_iterator> {
Shape_range(boost::shared_ptr<std::vector<boost::shared_ptr<Shape> > >
extracted_shapes) : Iterator_range(make_range(extracted_shapes->begin(),
extracted_shapes->end())), m_extracted_shapes(extracted_shapes) {}
private:
boost::shared_ptr<std::vector<boost::shared_ptr<Shape> > >
m_extracted_shapes; // keeps a reference to the shape vector
};
#endif
///< An `Iterator_range` with a bidirectional constant iterator type with value type `boost::shared_ptr<Shape>`.
@ -200,16 +208,16 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
Normal_map normal_map = Normal_map()
///< property map to access the normal of an input point.
) {
clear();
m_extracted_shapes.clear();
m_point_pmap = point_map;
m_normal_pmap = normal_map;
m_inputIterator_first = input_range.begin();
m_inputIterator_beyond = input_range.end();
clear();
m_extracted_shapes = boost::make_shared<std::vector<boost::shared_ptr<Shape> > >();
m_num_available_points = m_inputIterator_beyond - m_inputIterator_first;
m_valid_iterators = true;
@ -245,7 +253,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
m_available_octree_sizes.resize(m_num_subsets);
m_direct_octrees = new Direct_octree *[m_num_subsets];
for (int s = m_num_subsets - 1;s >= 0;--s) {
for (int s = int(m_num_subsets) - 1;s >= 0;--s) {
std::size_t subsetSize = remainingPoints;
std::vector<std::size_t> indices(subsetSize);
if (s) {
@ -258,13 +266,15 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
}
// move points to the end of the point vector
for (int i = subsetSize - 1;i >= 0;i--) {
std::size_t j = subsetSize;
do {
j--;
typename std::iterator_traits<Input_iterator>::value_type
tmp = (*last);
*last = m_inputIterator_first[indices[std::size_t(i)]];
m_inputIterator_first[indices[std::size_t(i)]] = tmp;
*last = m_inputIterator_first[indices[std::size_t(j)]];
m_inputIterator_first[indices[std::size_t(j)]] = tmp;
last--;
}
} while (j > 0);
m_direct_octrees[s] = new Direct_octree(last + 1,
last + subsetSize + 1,
remainingPoints - subsetSize);
@ -335,7 +345,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
std::vector<int>().swap(m_shape_index);
m_extracted_shapes.clear();
m_extracted_shapes = boost::make_shared<std::vector<boost::shared_ptr<Shape> > >();
m_num_available_points = m_inputIterator_beyond - m_inputIterator_first;
@ -367,7 +377,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
}
// Reset data structures possibly used by former search
m_extracted_shapes.clear();
m_extracted_shapes = boost::make_shared<std::vector<boost::shared_ptr<Shape> > >();
m_num_available_points = m_inputIterator_beyond - m_inputIterator_first;
for (std::size_t i = 0;i<m_num_subsets;i++) {
@ -525,7 +535,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
candidates.back() = NULL;
//1. add best candidate to final result.
m_extracted_shapes.push_back(boost::shared_ptr<Shape>(best_Candidate));
m_extracted_shapes->push_back(boost::shared_ptr<Shape>(best_Candidate));
//2. remove the points
//2.1 update boolean
@ -534,7 +544,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
for (std::size_t i = 0;i<indices_points_best_candidate.size();i++) {
m_shape_index[indices_points_best_candidate.at(i)] =
m_extracted_shapes.size() - 1;
int(m_extracted_shapes->size()) - 1;
numInvalid++;
@ -626,8 +636,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
for the detection, the shapes are ordered with decreasing size.
*/
Shape_range shapes() const {
return make_range(m_extracted_shapes.begin(),
m_extracted_shapes.end());
return Shape_range(m_extracted_shapes);
}
/*!
@ -656,11 +665,11 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
private:
int select_random_octree_level() {
return default_random(m_global_octree->maxLevel() + 1);
return (int) default_random(m_global_octree->maxLevel() + 1);
}
Shape* get_best_candidate(std::vector<Shape* >& candidates,
const int _SizeP) {
const std::size_t num_available_points) {
if (candidates.size() == 1)
return candidates.back();
@ -678,13 +687,13 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
//refine the best one
improve_bound(candidates.back(),
_SizeP, m_num_subsets,
num_available_points, m_num_subsets,
m_options.min_points);
int position_stop;
//Take all those intersecting the best one, check for equal ones
for (position_stop = candidates.size() - 1;
for (position_stop = int(candidates.size()) - 1;
position_stop > index_worse_candidate;
position_stop--) {
if (candidates.back()->min_bound() >
@ -699,7 +708,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
// between best one and position_stop
//so request refining bound on position_stop
improved |= improve_bound(candidates.at(position_stop),
_SizeP,
num_available_points,
m_num_subsets,
m_options.min_points);
@ -716,7 +725,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
}
bool improve_bound(Shape *candidate,
const int _SizeP,
std::size_t num_available_points,
std::size_t max_subset,
std::size_t min_points) {
if (candidate->m_nb_subset_used >= max_subset)
@ -732,43 +741,43 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
//what it does is add another subset and recompute lower and upper bound
//the next subset to include is provided by m_nb_subset_used
std::size_t numPointsEvaluated = 0;
std::size_t num_points_evaluated = 0;
for (std::size_t i=0;i<candidate->m_nb_subset_used;i++)
numPointsEvaluated += m_available_octree_sizes[i];
num_points_evaluated += m_available_octree_sizes[i];
// need score of new subset as well as sum of
// the score of the previous considered subset
std::size_t newScore = 0;
std::size_t newSampledPoints = 0;
std::size_t new_score = 0;
std::size_t new_sampled_points = 0;
do {
newScore = m_direct_octrees[candidate->m_nb_subset_used]->score(
new_score = m_direct_octrees[candidate->m_nb_subset_used]->score(
candidate,
m_shape_index,
m_options.epsilon,
m_options.normal_threshold);
candidate->m_score += newScore;
candidate->m_score += new_score;
numPointsEvaluated +=
num_points_evaluated +=
m_available_octree_sizes[candidate->m_nb_subset_used];
newSampledPoints +=
new_sampled_points +=
m_available_octree_sizes[candidate->m_nb_subset_used];
candidate->m_nb_subset_used++;
} while (newSampledPoints < min_points &&
} while (new_sampled_points < min_points &&
candidate->m_nb_subset_used < m_num_subsets);
candidate->m_score = candidate->m_indices.size();
candidate->compute_bound(numPointsEvaluated, _SizeP);
candidate->compute_bound(num_points_evaluated, num_available_points);
return true;
}
inline FT stop_probability(std::size_t largest_candidate, std::size_t num_pts, std::size_t num_candidates, std::size_t octree_depth) const {
return (std::min<FT>)(std::pow((FT) 1.f - (FT) largest_candidate / FT(num_pts * octree_depth * 3), (int) num_candidates), (FT) 1);
return (std::min<FT>)(std::pow((FT) 1.f - (FT) largest_candidate / FT(num_pts * octree_depth * 4), (int) num_candidates), (FT) 1);
}
private:
@ -781,7 +790,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
// sample selection within an octree cell.
Direct_octree **m_direct_octrees;
Indexed_octree *m_global_octree;
std::vector<int> m_available_octree_sizes;
std::vector<std::size_t> m_available_octree_sizes;
std::size_t m_num_subsets;
// maps index into points to assigned extracted primitive
@ -791,7 +800,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}.
//give the index of the subset of point i
std::vector<int> m_index_subsets;
std::vector<boost::shared_ptr<Shape> > m_extracted_shapes;
boost::shared_ptr<std::vector<boost::shared_ptr<Shape> > > m_extracted_shapes;
std::vector<Shape *(*)()> m_shape_factories;

View File

@ -39,6 +39,8 @@ namespace CGAL {
class Efficient_RANSAC;
namespace internal {
const std::size_t size_t_max = std::numeric_limits<std::size_t>::max();
template<class Sdt>
class DirectPointAccessor {
@ -192,7 +194,7 @@ namespace CGAL {
}
std::size_t size() const {
if (first == -1 || last == -1)
if (first == size_t_max || last == size_t_max)
return 0;
else return (last - first + 1);
}
@ -238,7 +240,7 @@ namespace CGAL {
// z max before z min, then y max before y min, then x max before x min
void createTree() {
buildBoundingCube();
int count = 0;
std::size_t count = 0;
m_max_level = 0;
std::stack<Cell *> stack;
@ -252,50 +254,50 @@ namespace CGAL {
if (cell->level == m_set_max_level)
continue;
int zLowYHighXSplit, zLowYLowXSplit, zLowYSplit;
int zHighYSplit, zHighYHighXSplit, zHighYLowXSplit;
std::size_t zLowYHighXSplit, zLowYLowXSplit, zLowYSplit;
std::size_t zHighYSplit, zHighYHighXSplit, zHighYLowXSplit;
int zSplit = split(cell->first, cell->last, 2, cell->center[2]);
std::size_t zSplit = split(cell->first, cell->last, 2, cell->center[2]);
if (zSplit != -1) {
if (zSplit != size_t_max) {
zLowYSplit = split(cell->first, zSplit, 1, cell->center[1]);
if (zLowYSplit != -1) {
if (zLowYSplit != size_t_max) {
zLowYLowXSplit = split(cell->first,
zLowYSplit, 0, cell->center[0]);
zLowYHighXSplit = split(zLowYSplit + 1,
zSplit, 0, cell->center[0]);
}
else {
zLowYLowXSplit = -1;
zLowYLowXSplit = size_t_max;
zLowYHighXSplit = split(cell->first, zSplit, 0, cell->center[0]);
}
zHighYSplit = split(zSplit + 1, cell->last, 1, cell->center[1]);
if (zHighYSplit != -1) {
if (zHighYSplit != size_t_max) {
zHighYHighXSplit = split(zHighYSplit + 1,
cell->last, 0, cell->center[0]);
zHighYLowXSplit = split(zSplit + 1,
zHighYSplit, 0, cell->center[0]);
}
else {
zHighYLowXSplit = -1;
zHighYLowXSplit = size_t_max;
zHighYHighXSplit = split(zSplit + 1,
cell->last, 0, cell->center[0]);
}
}
else {
zLowYSplit = -1;
zLowYLowXSplit = -1;
zLowYHighXSplit = -1;
zLowYSplit = size_t_max;
zLowYLowXSplit = size_t_max;
zLowYHighXSplit = size_t_max;
zHighYSplit = split(cell->first,
cell->last,
1,
cell->center[1]);
if (zHighYSplit != -1) {
if (zHighYSplit != size_t_max) {
zHighYHighXSplit = split(zHighYSplit + 1,
cell->last,
0,
@ -307,7 +309,7 @@ namespace CGAL {
cell->center[0]);
}
else {
zHighYLowXSplit = -1;
zHighYLowXSplit = size_t_max;
zHighYHighXSplit = split(cell->first,
cell->last,
0,
@ -318,9 +320,9 @@ namespace CGAL {
FT width = m_width / (1<<(cell->level + 1));
if (zSplit != -1) {
if (zLowYSplit != -1) {
if (zLowYLowXSplit != -1) {
if (zSplit != size_t_max) {
if (zLowYSplit != size_t_max) {
if (zLowYLowXSplit != size_t_max) {
if ((int)cell->first <= zLowYLowXSplit) {
//---
@ -336,7 +338,7 @@ namespace CGAL {
}
else zLowYLowXSplit = cell->first - 1;
if (zLowYLowXSplit < zLowYSplit) {
if (zLowYLowXSplit < zLowYSplit || zLowYLowXSplit == size_t_max) {
//+--
cell->child[6] = new Cell(zLowYLowXSplit + 1,
zLowYSplit,
@ -350,9 +352,9 @@ namespace CGAL {
}
else zLowYSplit = cell->first - 1;
if (zLowYHighXSplit != -1) {
if (zLowYHighXSplit != size_t_max) {
if (zLowYSplit < zLowYHighXSplit) {
if (zLowYSplit < zLowYHighXSplit || zLowYSplit == size_t_max) {
//-+-
cell->child[5] = new Cell(zLowYSplit + 1,
zLowYHighXSplit,
@ -366,7 +368,7 @@ namespace CGAL {
}
else zLowYHighXSplit = zLowYSplit;
if (zLowYHighXSplit < zSplit) {
if (zLowYHighXSplit < zSplit || zLowYHighXSplit == size_t_max) {
//++-
cell->child[4] = new Cell(zLowYHighXSplit + 1,
zSplit,
@ -380,10 +382,10 @@ namespace CGAL {
}
else zSplit = cell->first - 1;
if (zHighYSplit != -1) {
if (zHighYLowXSplit != -1) {
if (zHighYSplit != size_t_max) {
if (zHighYLowXSplit != size_t_max) {
if (zSplit < zHighYLowXSplit) {
if (zSplit < zHighYLowXSplit || zSplit == size_t_max) {
//--+
cell->child[3] = new Cell(zSplit + 1,
zHighYLowXSplit,
@ -397,7 +399,7 @@ namespace CGAL {
}
else zHighYLowXSplit = zSplit;
if (zHighYLowXSplit < zHighYSplit) {
if (zHighYLowXSplit < zHighYSplit || zHighYLowXSplit == size_t_max) {
//+-+
cell->child[2] = new Cell(zHighYLowXSplit + 1,
zHighYSplit,
@ -412,9 +414,8 @@ namespace CGAL {
}
else zHighYSplit = zSplit;
if (zHighYHighXSplit != -1) {
if (zHighYSplit < zHighYHighXSplit) {
if (zHighYHighXSplit != size_t_max) {
if (zHighYSplit < zHighYHighXSplit || zHighYSplit == size_t_max) {
//-++
cell->child[1] = new Cell(zHighYSplit + 1,
zHighYHighXSplit,
@ -428,8 +429,8 @@ namespace CGAL {
}
else zHighYHighXSplit = zHighYSplit;
if (zHighYHighXSplit <= (int)cell->last) {
if (zHighYHighXSplit < (int)cell->last) {
if (zHighYHighXSplit <= (int)cell->last || zHighYHighXSplit == size_t_max) {
if (zHighYHighXSplit < (int)cell->last || zHighYHighXSplit == size_t_max) {
//+++
cell->child[0] = new Cell(zHighYHighXSplit + 1,
cell->last,
@ -442,7 +443,7 @@ namespace CGAL {
}
}
int sum = 0;
std::size_t sum = 0;
for (std::size_t i = 0;i<8;i++)
sum += (cell->child[i]) ? cell->child[i]->size() : 0;
@ -489,7 +490,7 @@ namespace CGAL {
}
if (enough >= requiredSamples) {
do {
std::size_t p = rand.get_int(0, cur->size() - 1);
std::size_t p = rand.get_int(0, cur->size());
std::size_t j = this->index(cur->first + p);
if (shapeIndex[j] == -1)
indices.insert(j);
@ -611,21 +612,21 @@ namespace CGAL {
}
// returns index of last point below threshold
int split(int first, int last, std::size_t dimension, FT threshold) {
if (last == -1 || first == -1)
return -1;
std::size_t split(std::size_t first, std::size_t last, std::size_t dimension, FT threshold) {
if (last == size_t_max || first == size_t_max)
return size_t_max;
if (first > last)
return first - 1;
int origFirst = first;
std::size_t origFirst = first;
while(first < last) {
// find first above threshold
Point p1 = get(m_point_pmap, *this->at(first));
FT v1 = p1[dimension];
FT v1 = p1[(int) dimension];
while (get(m_point_pmap,
*this->at(first))[dimension] < threshold
*this->at(first))[(int) dimension] < threshold
&& first < last) {
first++;
}
@ -633,15 +634,15 @@ namespace CGAL {
// check if last has been reached
if (first == last) {
return (get(m_point_pmap,
*this->at(first))[dimension] < threshold) ?
first : (first == origFirst) ? -1 : first - 1;
*this->at(first))[(int) dimension] < threshold) ?
first : (first == origFirst) ? size_t_max : first - 1;
}
// find last below threshold
p1 = get(m_point_pmap, *this->at(last));
v1 = p1[dimension];
v1 = p1[(int) dimension];
while (get(m_point_pmap,
*this->at(last))[dimension] >= threshold
*this->at(last))[(int) dimension] >= threshold
&& last > first) {
last--;
}
@ -649,22 +650,22 @@ namespace CGAL {
// check if first has been reached
if (last == first) {
return (get(m_point_pmap,
*this->at(first))[dimension] < threshold) ?
first : (first == origFirst) ? -1 : first - 1;
*this->at(first))[(int) dimension] < threshold) ?
first : (first == origFirst) ? size_t_max : first - 1;
}
this->swap(first, last);
p1 = get(m_point_pmap, *this->at(first));
v1 = p1[dimension];
v1 = p1[(int) dimension];
p1 = get(m_point_pmap, *this->at(last));
v1 = p1[dimension];
v1 = p1[(int) dimension];
first++;
last--;
}
return (get(m_point_pmap,
*this->at(first))[dimension] < threshold) ?
first : (first == origFirst) ? -1 : first - 1;
*this->at(first))[(int) dimension] < threshold) ?
first : (first == origFirst) ? size_t_max : first - 1;
}
Bbox_3 m_bBox;

View File

@ -66,6 +66,13 @@ namespace CGAL {
Vector_3 plane_normal() const {
return m_normal;
}
/*!
Signed distance from the origin.
*/
FT d() const {
return m_d;
}
/// \cond SKIP_IN_MANUAL
/*!

View File

@ -138,53 +138,53 @@ namespace CGAL {
FT min[] = {0,0}, max[] = {0,0};
std::vector<std::pair<FT, FT> > parameterSpace;
parameterSpace.resize(indices.size());
std::vector<std::pair<FT, FT> > parameter_space;
parameter_space.resize(indices.size());
parameters(m_indices, parameterSpace, min, max);
int iMin[2], iMax[2];
iMin[0] = (int) (min[0] / cluster_epsilon);
iMin[1] = (int) (min[1] / cluster_epsilon);
iMax[0] = (int) (max[0] / cluster_epsilon);
iMax[1] = (int) (max[1] / cluster_epsilon);
parameters(m_indices, parameter_space, min, max);
int i_min[2], i_max[2];
i_min[0] = (int) (min[0] / cluster_epsilon);
i_min[1] = (int) (min[1] / cluster_epsilon);
i_max[0] = (int) (max[0] / cluster_epsilon);
i_max[1] = (int) (max[1] / cluster_epsilon);
std::size_t uExtent = abs(iMax[0] - iMin[0]) + 2;
std::size_t vExtent = abs(iMax[1] - iMin[1]) + 2;
std::size_t u_extent = abs(i_max[0] - i_min[0]) + 2;
std::size_t v_extent = abs(i_max[1] - i_min[1]) + 2;
std::vector<std::vector<int> > bitmap;
std::vector<std::vector<std::size_t> > bitmap;
std::vector<bool> visited;
bitmap.resize(uExtent * vExtent);
visited.resize(uExtent * vExtent, false);
bitmap.resize(u_extent * v_extent);
visited.resize(u_extent * v_extent, false);
bool wrapU = wraps_u();
bool wrapV = wraps_v();
bool wrap_u = wraps_u();
bool wrap_v = wraps_v();
for (std::size_t i = 0;i<parameterSpace.size();i++) {
int u = (int)((parameterSpace[i].first - min[0]) / cluster_epsilon);
int v = (int)((parameterSpace[i].second - min[1]) / cluster_epsilon);
if (u < 0 || (std::size_t)u >= uExtent) {
if (wrapU) {
while (u < 0) u += uExtent;
while ((std::size_t)u >= uExtent) u-= uExtent;
for (std::size_t i = 0;i<parameter_space.size();i++) {
int u = (int)((parameter_space[i].first - min[0]) / cluster_epsilon);
int v = (int)((parameter_space[i].second - min[1]) / cluster_epsilon);
if (u < 0 || (std::size_t)u >= u_extent) {
if (wrap_u) {
while (u < 0) u += (int) u_extent;
while (u >= (int) u_extent) u-= (int)u_extent;
}
else {
u = (u < 0) ? 0 : ((std::size_t)u >= uExtent) ? (int)uExtent - 1 : u;
u = (u < 0) ? 0 : (u >= (int) u_extent) ? (int)u_extent - 1 : u;
}
}
if (v < 0 || (std::size_t)v >= vExtent) {
if (wrapV) {
while (v < 0) v += vExtent;
while ((std::size_t)v >= vExtent) v-= vExtent;
if (v < 0 || v >= (int) v_extent) {
if (wrap_v) {
while (v < 0) v += (int) v_extent;
while (v >= (int) v_extent) v-= (int) v_extent;
}
else {
v = (v < 0) ? 0 : ((std::size_t)v >= vExtent) ? (int)vExtent - 1 : v;
v = (v < 0) ? 0 : (v >= (int) v_extent) ? (int) v_extent - 1 : v;
}
}
bitmap[v * uExtent + u].push_back(m_indices[i]);
bitmap[v * int(u_extent) + u].push_back(m_indices[i]);
}
std::vector<std::vector<std::size_t> > cluster;
for (std::size_t i = 0;i<(uExtent * vExtent);i++) {
for (std::size_t i = 0;i<(u_extent * v_extent);i++) {
cluster.push_back(std::vector<std::size_t>());
if (bitmap[i].empty())
continue;
@ -207,61 +207,61 @@ namespace CGAL {
std::back_inserter(cluster.back()));
// grow 8-neighborhood
int vIndex = f / uExtent;
int uIndex = f % uExtent;
bool upperBorder = vIndex == 0;
bool lowerBorder = vIndex == ((int)vExtent - 1);
bool leftBorder = uIndex == 0;
bool rightBorder = uIndex == ((int)uExtent - 1);
int v_index = int(f / u_extent);
int u_index = int(f % u_extent);
bool upper_border = v_index == 0;
bool lower_border = v_index == ((int)v_extent - 1);
bool left_border = u_index == 0;
bool right_border = u_index == ((int)u_extent - 1);
int n;
if (!upperBorder) {
n = f - uExtent;
if (!upper_border) {
n = int(f - u_extent);
if (!visited[n])
fields.push(n);
}
else if (wrapV) {
n = f + (vExtent - 1) * uExtent;
else if (wrap_v) {
n = int((f + v_extent - 1) * u_extent);
if (!visited[n]) fields.push(n);
}
if (!leftBorder) {
n = f - 1;
if (!left_border) {
n = int(f - 1);
if (!visited[n]) fields.push(n);
}
else if (wrapU) {
n = f + uExtent - 1;
else if (wrap_u) {
n = int(f + u_extent - 1);
if (!visited[n]) fields.push(n);
}
if (!lowerBorder) {
n = f + uExtent;
if (!lower_border) {
n = int(f + u_extent);
if (!visited[n]) fields.push(n);
}
else if (wrapV) {
n = f - (vExtent - 1) * uExtent;
else if (wrap_v) {
n = int((f - (v_extent - 1)) * u_extent);
if (!visited[n]) fields.push(n);
}
if (!rightBorder) {
n = f + 1;
if (!right_border) {
n = int(f) + 1;
if (!visited[n]) fields.push(n);
}
else if (wrapU) {
n = f - uExtent + 1;
else if (wrap_u) {
n = int(f - u_extent + 1);
if (!visited[n]) fields.push(n);
}
}
}
int maxCluster = 0;
std::size_t max_cluster = 0;
for (std::size_t i = 1;i<cluster.size();i++) {
if (cluster[i].size() > cluster[maxCluster].size()) {
maxCluster = i;
if (cluster[i].size() > cluster[max_cluster].size()) {
max_cluster = i;
}
}
indices = cluster[maxCluster];
indices = cluster[max_cluster];
return m_score = indices.size();
}
@ -273,9 +273,9 @@ namespace CGAL {
*/
std::size_t connected_component_kdTree(std::vector<std::size_t> &indices,
FT cluster_epsilon) {
typedef boost::tuple<Point_3,int> Point_and_int;
typedef CGAL::Search_traits_adapter<Point_and_int,
CGAL::Nth_of_tuple_property_map<0, Point_and_int>,
typedef boost::tuple<Point_3, std::size_t> Point_and_size_t;
typedef CGAL::Search_traits_adapter<Point_and_size_t,
CGAL::Nth_of_tuple_property_map<0, Point_and_size_t>,
typename Traits::Search_traits> Search_traits_adapter;
typedef CGAL::Kd_tree<Search_traits_adapter> Kd_Tree;
@ -283,47 +283,47 @@ namespace CGAL {
m_has_connected_component = true;
std::vector<Point_and_int> pts;
std::vector<std::size_t> labelMap;
std::vector<Point_and_size_t> pts;
std::vector<std::size_t> label_map;
pts.resize(indices.size());
labelMap.resize(indices.size(), 0);
label_map.resize(indices.size(), 0);
for (std::size_t i = 0;i < indices.size();i++) {
pts[i] = Point_and_int(point(indices[i]), i);
pts[i] = Point_and_size_t(point(indices[i]), i);
}
// construct kd tree
Kd_Tree tree(pts.begin(), pts.end());
std::stack<int> stack;
std::stack<std::size_t> stack;
std::size_t unlabeled = pts.size();
std::size_t label = 1;
std::size_t best = 0;
std::size_t bestSize = 0;
std::size_t best_size = 0;
for (std::size_t i = 0;i<pts.size();i++) {
if (labelMap[i] != 0)
if (label_map[i] != 0)
continue;
std::size_t assigned = 0;
stack.push(i);
while(!stack.empty()) {
std::vector<Point_and_int> nearPoints;
std::vector<Point_and_size_t> near_points;
std::size_t p = stack.top();
stack.pop();
Fuzzy_sphere fs(pts[p], cluster_epsilon, 0);
tree.search(std::back_inserter(nearPoints), fs);
tree.search(std::back_inserter(near_points), fs);
for (std::size_t j = 0;j<nearPoints.size();j++) {
std::size_t index = boost::get<1>(nearPoints[j]);
for (std::size_t j = 0;j<near_points.size();j++) {
std::size_t index = boost::get<1>(near_points[j]);
if (index == p)
continue;
if (labelMap[index] != label) {
labelMap[index] = label;
if (label_map[index] != label) {
label_map[index] = label;
assigned++;
stack.push(index);
}
@ -332,26 +332,26 @@ namespace CGAL {
// Track most prominent label and remaining points
unlabeled -= assigned;
if (assigned > bestSize) {
if (assigned > best_size) {
best = label;
bestSize = assigned;
best_size = assigned;
}
label++;
// Can we stop already?
if (unlabeled <= bestSize)
if (unlabeled <= best_size)
break;
}
std::vector<std::size_t> tmpIndices;
tmpIndices.reserve(bestSize);
std::vector<std::size_t> tmp_indices;
tmp_indices.reserve(best_size);
for (std::size_t i = 0;i<pts.size();i++) {
if (labelMap[i] == best)
tmpIndices.push_back(indices[i]);
if (label_map[i] == best)
tmp_indices.push_back(indices[i]);
}
indices = tmpIndices;
indices = tmp_indices;
return indices.size();
}
@ -434,19 +434,19 @@ namespace CGAL {
return expected_value();
}
void update_points(const std::vector<int> &shapeIndex) {
void update_points(const std::vector<int> &shape_index) {
if (!m_indices.size())
return;
std::size_t start = 0, end = m_indices.size() - 1;
while (start < end) {
while (shapeIndex[m_indices[start]] == -1
while (shape_index[m_indices[start]] == -1
&& start < end) start++;
while (shapeIndex[m_indices[end]] != -1
while (shape_index[m_indices[end]] != -1
&& start < end) end--;
if (shapeIndex[m_indices[start]] != -1
&& shapeIndex[m_indices[end]] == -1
if (shape_index[m_indices[start]] != -1
&& shape_index[m_indices[end]] == -1
&& start < end) {
std::size_t tmp = m_indices[start];
m_indices[start] = m_indices[end];
@ -462,12 +462,12 @@ namespace CGAL {
}
virtual void parameters(const std::vector<std::size_t>& indices,
std::vector<std::pair<FT, FT> >& parameterSpace,
std::vector<std::pair<FT, FT> >& parameter_space,
FT min[2],
FT max[2]) const {
// Avoid compiler warnings about unused parameters.
(void)indices;
(void)parameterSpace;
(void)parameter_space;
(void)min;
(void)max;
}
@ -507,7 +507,7 @@ namespace CGAL {
angles.resize(indices.size());
cos_to_normal(indices, angles);
std::size_t scoreBefore = m_indices.size();
std::size_t score_before = m_indices.size();
FT eps = epsilon * epsilon;
for (std::size_t i = 0;i<indices.size();i++) {
@ -515,7 +515,7 @@ namespace CGAL {
m_indices.push_back(indices[i]);
}
return m_indices.size() - scoreBefore;
return m_indices.size() - score_before;
}
template<typename T> bool is_finite(T arg) {
@ -524,9 +524,9 @@ namespace CGAL {
arg != -std::numeric_limits<T>::infinity();
}
void compute_bound(const int sizeS1, const int sizeP) {
hypergeometrical_dist(-2 - sizeS1,
-2 - sizeP,
void compute_bound(const std::size_t num_evaluated_points, const std::size_t num_available_points) {
hypergeometrical_dist(-2 - num_evaluated_points,
-2 - num_available_points,
-1 - signed(m_indices.size()),
m_lower_bound, m_upper_bound);

View File

@ -80,7 +80,9 @@ void sample_random_sphere_in_box(const std::size_t num_points,
typename K::FT &radius, OutputIterator points) {
typedef typename K::FT FT;
// Generate random parameters
radius = random_float((FT) 0.01, (FT) 5);
if (radius < 0.00001)
radius = random_float<FT>((FT) 0.01, (FT) 5);
else radius = random_float<FT>(radius / (FT) 10.0, (FT) radius);
center = random_point_in<K>(bbox);
sample_sphere(num_points, center, radius, points);
@ -180,7 +182,7 @@ void sample_cone(const std::size_t num_points,
template <typename K, typename OutputIterator>
void sample_random_cone(const std::size_t num_points,
CGAL::Point_3<K> &apex, CGAL::Vector_3<K> &axis,
typename K::FT &angle, OutputIterator points) {
typename K::FT &angle, typename K::FT &mid, OutputIterator points) {
typedef typename K::FT FT;
// Generate random parameters
apex = random_point_in<K>(CGAL::Bbox_3(-5, -5, -5, 5, 5, 5));
@ -189,6 +191,8 @@ void sample_random_cone(const std::size_t num_points,
FT start = random_float((FT) 0, (FT) 2.5);
FT end = start + random_float((FT) 0.5, (FT) 2.5);
mid = (start + end) / (FT) 2.0;
sample_cone(num_points, apex, axis, angle, start, end, points);
}
@ -237,7 +241,7 @@ void sample_random_parallelogram_in_box(const std::size_t num_points,
}
template <typename K, typename OutputIterator>
void generate_points_on_torus(const std::size_t num_points,
void sample_torus(const std::size_t num_points,
const CGAL::Point_3<K> &center,
const CGAL::Vector_3<K> &axis,
typename K::FT major_radius,
@ -282,7 +286,7 @@ void sample_random_torus(const std::size_t num_points, CGAL::Point_3<K> &center,
major_radius = random_float((FT) 1.0, (FT) 5.0);
minor_radius = random_float((FT) 0.1, (FT) 1.0);
generate_points_on_torus(num_points, center, axis, major_radius, minor_radius, points);
sample_torus(num_points, center, axis, major_radius, minor_radius, points);
}
template <typename K, typename P>

View File

@ -36,9 +36,10 @@ bool test_cone_parameters() {
Vector axis;
Point apex;
FT angle = 0;
FT mid = 0;
CGAL::Bbox_3 bbox(-10, -10, -10, 10, 10, 10);
sample_random_cone(NB_POINTS, apex, axis, angle,
sample_random_cone(NB_POINTS, apex, axis, angle, mid,
std::back_inserter(points));
// add outliers in second half of rounds

View File

@ -46,7 +46,7 @@ bool test_plane_connected_component() {
for (std::size_t j = 0;j<4;j++) {
for (std::size_t x = 0;x<=20;x++)
for (std::size_t y = 0;y<=20;y++)
points.push_back(Pwn(Point(FT(x * 0.05), FT(y * 0.05), (FT) 0) + offset[j],
points.push_back(Pwn(Point(FT(x * 0.05), FT(y * 0.05), (FT) 1.0) + offset[j],
Vector((FT) 0, (FT) 0, (FT) 1)));
}
@ -66,7 +66,7 @@ bool test_plane_connected_component() {
parameters.epsilon = 0.002f;
parameters.normal_threshold = 0.9f;
if (i <= NB_ROUNDS/2)
if (i < NB_ROUNDS/2)
parameters.cluster_epsilon = 0.201f;
else
parameters.cluster_epsilon = 0.051f;
@ -77,11 +77,11 @@ bool test_plane_connected_component() {
}
typename Efficient_ransac::Shape_range shapes = ransac.shapes();
if (i <= NB_ROUNDS/2 && shapes.size() != 1)
if (i < NB_ROUNDS/2 && shapes.size() != 1)
continue;
if (i > NB_ROUNDS/2 && shapes.size() != 4)
if (i >= NB_ROUNDS/2 && shapes.size() != 4)
continue;
success++;

View File

@ -76,7 +76,7 @@ bool test_plane_parameters() {
const FT phi = normal * pl->plane_normal();
const FT sign = (phi < 0) ? -1.0f : 1.0f;
const FT dist2 = (CGAL::Plane_3<K>(*pl)).d();
const FT dist2 = pl->d();
if (abs(phi) < 0.98 || abs(dist2 - sign * dist) > 0.02)
continue;

View File

@ -0,0 +1,112 @@
#include "generators.h"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Shape_detection_3.h>
#include <CGAL/Point_with_normal_3.h>
#include <CGAL/property_map.h>
template <class K>
bool test_sphere_connected_component() {
const int NB_ROUNDS = 10;
const int NB_POINTS = 2000;
typedef typename K::FT FT;
typedef typename CGAL::Point_with_normal_3<K> Pwn;
typedef typename CGAL::Point_3<K> Point;
typedef typename CGAL::Vector_3<K> Vector;
typedef std::vector<Pwn> Pwn_vector;
typedef typename CGAL::Identity_property_map<Pwn> Point_map;
typedef typename CGAL::Normal_of_point_with_normal_pmap<K> Normal_map;
typedef CGAL::Shape_detection_3::Efficient_RANSAC_traits<
K, Pwn_vector, Point_map, Normal_map> Traits;
typedef CGAL::Shape_detection_3::Efficient_RANSAC<Traits> Efficient_ransac;
typedef CGAL::Shape_detection_3::Sphere<Traits> Sphere;
std::size_t success = 0;
for (std::size_t i = 0;i<NB_ROUNDS;i++) {
Pwn_vector points;
// generate random points on random sphere
typename FT radius = 1.0;
Point center;
CGAL::Bbox_3 bbox(-10, -10, -10, 10, 10, 10);
sample_random_sphere_in_box(NB_POINTS, bbox, center,
radius, std::back_inserter(points));
CGAL::Vector_3<K> n = random_normal<K>();
CGAL::Plane_3<K> pl(center, n);
FT spacing = radius / K::FT(4);
filter_by_distance(pl, spacing * (K::FT) 0.5, points);
Efficient_ransac ransac;
ransac.template add_shape_factory<Sphere>();
ransac.set_input(points);
// Set cluster epsilon to a high value as just the parameters of
// the extracted primitives are to be tested.
typename Efficient_ransac::Parameters parameters;
parameters.probability = 0.05f;
parameters.min_points = NB_POINTS/10;
parameters.epsilon = 0.002f;
parameters.normal_threshold = 0.9f;
if (i < NB_ROUNDS/2)
parameters.cluster_epsilon = spacing * (K::FT) 1.21;
else
parameters.cluster_epsilon = spacing / (K::FT) 2;
if (!ransac.detect(parameters)) {
std::cout << " aborted" << std::endl;
return false;
}
typename Efficient_ransac::Shape_range shapes = ransac.shapes();
if (i < NB_ROUNDS/2 && shapes.size() != 1)
continue;
if (i >= NB_ROUNDS/2 && shapes.size() != 2)
continue;
success++;
}
if (success >= NB_ROUNDS * 0.8) {
std::cout << " succeeded" << std::endl;
return true;
}
else {
std::cout << " failed" << std::endl;
return false;
}
}
int main() {
bool success = true;
std::cout << "test_sphere_connected_component<CGAL::Simple_cartesian<float>> ";
if (!test_sphere_connected_component<CGAL::Simple_cartesian<float> >())
success = false;
std::cout << "test_sphere_connected_component<CGAL::Simple_cartesian<double>> ";
if (!test_sphere_connected_component<CGAL::Simple_cartesian<double> >())
success = false;
std::cout << "test_sphere_connected_component<CGAL::Exact_predicates_inexact_constructions_kernel> ";
if (!test_sphere_connected_component<CGAL::Exact_predicates_inexact_constructions_kernel>())
success = false;
return (success) ? EXIT_SUCCESS : EXIT_FAILURE;
}