Skip to content

Commit

Permalink
Extended PlanarSegmentation class
Browse files Browse the repository at this point in the history
First attempt for a labelling algorithm -- currently, no tunable
parameters etc., but the principle is sound.
  • Loading branch information
Pseudomanifold committed Feb 19, 2011
1 parent f53b3af commit 06325ea
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 0 deletions.
201 changes: 201 additions & 0 deletions SegmentationAlgorithms/PlanarSegmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @brief Functions for the planar segmentation algorithm
*/

#include <list>
#include "PlanarSegmentation.h"

namespace psalm
Expand All @@ -25,6 +26,41 @@ mesh PlanarSegmentation::apply_to(mesh& input_mesh)
{
mesh res;

this->label_planar_vertices(input_mesh);
this->label_nonplanar_faces(input_mesh);
this->label_regions(input_mesh);

size_t cur_region = 0;
size_t written = 0;
do
{
for(size_t i = 0; i < input_mesh.num_vertices(); i++)
{
if(input_mesh.get_vertex(i)->region != std::numeric_limits<size_t>::max())
{
if(input_mesh.get_vertex(i)->region == cur_region)
{
written++;
std::cout << input_mesh.get_vertex(i)->get_position();
}
}
}

std::cout << "\n\n";

if(written == 0)
break;
else
{
cur_region++;
written = 0;
continue;
}
}
while(true);

return(res);

/*
* FIXME: This assumes that the vertex IDs are numbered
* sequentially. If this is not the case, the function will
Expand Down Expand Up @@ -72,4 +108,169 @@ mesh PlanarSegmentation::apply_to(mesh& input_mesh)
return(res);
}

/*!
* Labels all planar vertices of a given input mesh. The result of this
* function is stored locally within the class.
*
* @param input_mesh Mesh that is going to be labelled
*/

void PlanarSegmentation::label_planar_vertices(mesh& input_mesh)
{
planar_vertices.clear();
for(size_t i = 0; i < input_mesh.num_vertices(); i++)
{
vertex* v = input_mesh.get_vertex(i);
double curvature = v->calc_rms_curvature();

// TODO: This should use a user-definable threshold value for
// determining the necessary curvature...
if(curvature < 0.05)
planar_vertices.push_back(v);
else
nonplanar_vertices.push_back(v);
}
}

/*!
* Labels nonplanar faces of the given input mesh. A face is nonplanar if
* at least one of its vertices is nonplanar.
*
* @param input_mesh Mesh that is going to be labelled
*/

void PlanarSegmentation::label_nonplanar_faces(mesh& input_mesh)
{
nonplanar_faces.clear();
for(size_t i = 0; i < input_mesh.num_faces(); i++)
{
face* f = input_mesh.get_face(i);
for(size_t j = 0; j < f->num_vertices(); j++)
{
vertex* v = f->get_vertex(j);

// TODO: Lookup could be optimized by using maps or
// fixed-size arrays...
if(std::find(planar_vertices.begin(), planar_vertices.end(), v) == planar_vertices.end())
{
nonplanar_faces.push_back(f);
break;
}
}
}
}

/*!
* Labels different regions in the given input mesh. Essentially, this is
* a breadth-first-search that tries to reach vertices of nonplanar faces,
* starting with a given vertex of a nonplanar face. Only edges to other
* nonplanar faces are taken into account. Each face reached from the
* starting vertex gets assigned the same region.
*
* @param input_mesh Mesh whose regions are to be labelled
*/

void PlanarSegmentation::label_regions(mesh& input_mesh)
{
size_t cur_region = 0;
while(nonplanar_vertices.size() > 0)
{
std::list<vertex*> unprocessed_vertices;

vertex* v = nonplanar_vertices.front();
if(v->region != std::numeric_limits<size_t>::max())
{
nonplanar_vertices.erase(nonplanar_vertices.begin());
continue;
}

unprocessed_vertices.push_back(v);
while(unprocessed_vertices.size() > 0)
{
vertex* v = unprocessed_vertices.front();
v->region = cur_region;
std::vector<const vertex*> neighbours = v->get_neighbours();
for(size_t i = 0; i < neighbours.size(); i++)
{
vertex* w = const_cast<vertex*>(neighbours[i]);

// TODO: Optimize
if(std::find(planar_vertices.begin(), planar_vertices.end(), w) != planar_vertices.end())
{
// skip planar vertices -- only the
// nonplanar regions should be labelled
continue;
}

if(w->region == std::numeric_limits<size_t>::max())
{
w->region = cur_region;
unprocessed_vertices.push_back(w);
}
}

unprocessed_vertices.pop_front();
}

cur_region++;
nonplanar_vertices.erase(nonplanar_vertices.begin());
}
/*
std::list<vertex*> unprocessed_vertices;
while(nonplanar_faces.size() > 0)
{
face* f = nonplanar_faces.front();
for(size_t i = 0; i < f->num_vertices(); i++)
{
vertex* v = f->get_vertex(i);
// TODO: Optimize
if(std::find(planar_vertices.begin(), planar_vertices.end(), v) != planar_vertices.end())
{
// skip planar vertices -- only nonplanar
// regions should be labelled
continue;
}
// Check if vertex has been visited already
if(v->region == std::numeric_limits<size_t>::max())
{
v->region = cur_region;
unprocessed_vertices.push_back(v);
}
}
nonplanar_faces.erase(nonplanar_faces.begin());
while(unprocessed_vertices.size() > 0)
{
vertex* v = unprocessed_vertices.front();
std::vector<const vertex*> neighbours = v->get_neighbours();
for(size_t i = 0; i < neighbours.size(); i++)
{
vertex* w = const_cast<vertex*>(neighbours[i]);
// TODO: Optimize
if(std::find(planar_vertices.begin(), planar_vertices.end(), w) != planar_vertices.end())
{
// skip planar vertices -- only the
// nonplanar regions should be labelled
continue;
}
if(w->region == std::numeric_limits<size_t>::max())
{
w->region = cur_region;
unprocessed_vertices.push_back(w);
}
}
unprocessed_vertices.pop_front();
}
cur_region++;
}
*/
}

} // end of namespace "psalm"
9 changes: 9 additions & 0 deletions SegmentationAlgorithms/PlanarSegmentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ class PlanarSegmentation : public SegmentationAlgorithm
{
public:
mesh apply_to(mesh& input_mesh);

private:
void label_planar_vertices(mesh& input_mesh);
void label_nonplanar_faces(mesh& input_mesh);
void label_regions(mesh& input_mesh);

std::vector<vertex*> planar_vertices;
std::vector<vertex*> nonplanar_vertices;
std::vector<face*> nonplanar_faces;
};

} // end of namespace "psalm"
Expand Down

0 comments on commit 06325ea

Please sign in to comment.