sharp feature detection

This commit is contained in:
Yin Xu 2011-08-03 14:22:06 +00:00
parent f849dc2b41
commit 9966c8ae66
5 changed files with 93 additions and 38 deletions

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>260</width>
<width>280</width>
<height>223</height>
</rect>
</property>
@ -110,6 +110,13 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="sharpFeatureCb">
<property name="text">
<string>Sharp feature</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -194,6 +194,7 @@ convert_to_edit_polyhedron(Item_id i,
edit_poly->setHandlesRegionSize(deform_mesh_widget.handlesRegionSize->value());
edit_poly->setInterestRegionSize(deform_mesh_widget.interestRegionSize->value());
edit_poly->setGeodesicCircle(deform_mesh_widget.geodesicCircleCb->isChecked());
edit_poly->setSharpFeature(deform_mesh_widget.sharpFeatureCb->isChecked());
edit_poly->setUsageScenario(deform_mesh_widget.usageScenarioCb->currentIndex());
edit_poly->setSelectedHandlesMoved(false);
edit_poly->setSelectedVertexChanged(false);
@ -207,6 +208,8 @@ convert_to_edit_polyhedron(Item_id i,
edit_poly, SLOT(setInterestRegionSize(int)));
connect(deform_mesh_widget.geodesicCircleCb, SIGNAL(clicked(bool)),
edit_poly, SLOT(setGeodesicCircle(bool)));
connect(deform_mesh_widget.sharpFeatureCb, SIGNAL(clicked(bool)),
edit_poly, SLOT(setSharpFeature(bool)));
connect(deform_mesh_widget.usageScenarioCb, SIGNAL(currentIndexChanged(int)),
edit_poly, SLOT(setUsageScenario(int)));
scene->replaceItem(i, edit_poly);

View File

@ -28,7 +28,7 @@ typedef Polyhedron_vertex_deformation_index_map<Polyhedron> Vertex_index_map;
typedef Polyhedron_edge_deformation_length_map<Polyhedron> Edge_length_map;
typedef boost::iterator_property_map<std::vector<double>::iterator, Vertex_index_map> Dist_pmap;
#define PI 3.14159265359
struct Scene_edit_polyhedron_item_priv {
@ -36,6 +36,7 @@ struct Scene_edit_polyhedron_item_priv {
int handlesRegionSize;
int interestRegionSize;
bool geodesicCircle;
bool sharpFeature;
int usageScenario;
bool selected_vertex_changed;
bool selected_handles_moved;
@ -53,7 +54,7 @@ struct Scene_edit_polyhedron_item_priv {
Edge_length_map* edge_length_map;
std::vector<double> geodesic_distance;
Dist_pmap* dist_pmap;
std::vector<double> dihedral_angle_variance;
std::vector<bool> is_sharp_vertices;
}; // end struct Scene_edit_polyhedron_item_priv
Scene_edit_polyhedron_item::Scene_edit_polyhedron_item(Scene_polyhedron_item* poly_item)
@ -83,7 +84,7 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item(Scene_polyhedron_item* po
}
d->geodesic_distance.resize(boost::num_vertices(*poly_item->polyhedron()), 0);
d->dist_pmap = new Dist_pmap(d->geodesic_distance.begin(), *d->vertex_index_map);
compute_dihedral_angle_variance();
find_sharp_vertices_1();
}
Scene_edit_polyhedron_item::~Scene_edit_polyhedron_item()
@ -276,6 +277,14 @@ Scene_edit_polyhedron_item::setGeodesicCircle(bool status) {
}
}
void
Scene_edit_polyhedron_item::setSharpFeature(bool status) {
d->sharpFeature = status;
if(d->selected_vertex != Vertex_handle()) {
vertex_has_been_selected(&*d->selected_vertex);
}
}
void
Scene_edit_polyhedron_item::setUsageScenario(int i) {
d->usageScenario = i;
@ -348,10 +357,11 @@ double Scene_edit_polyhedron_item::dihedral_angle(edge_descriptor e)
}
void
Scene_edit_polyhedron_item::compute_dihedral_angle_variance()
Scene_edit_polyhedron_item::find_sharp_vertices()
{
Polyhedron* poly = d->poly_item->polyhedron();
d->dihedral_angle_variance.clear();
d->is_sharp_vertices.clear();
d->is_sharp_vertices.resize(poly->size_of_vertices(), false);
std::vector<double> dihedral_angles;
vertex_iterator vb, ve;
for ( boost::tie(vb,ve) = boost::vertices(*poly); vb != ve; vb++ )
@ -376,7 +386,35 @@ Scene_edit_polyhedron_item::compute_dihedral_angle_variance()
{
var += (dihedral_angles[i] - ave_angle)*(dihedral_angles[i] - ave_angle)/dihedral_angles.size();
}
d->dihedral_angle_variance.push_back(var);
if (var > 0.2)
{
d->is_sharp_vertices[ boost::get(*d->vertex_index_map, *vb) ] = true ;
}
}
}
void
Scene_edit_polyhedron_item::find_sharp_vertices_1()
{
Polyhedron* poly = d->poly_item->polyhedron();
d->is_sharp_vertices.clear();
d->is_sharp_vertices.resize(poly->size_of_vertices(), false);
vertex_iterator vb, ve;
for ( boost::tie(vb,ve) = boost::vertices(*poly); vb != ve; vb++ )
{
// compute dihedral angles
in_edge_iterator eb, ee;
for ( boost::tie(eb,ee) = boost::in_edges(*vb, *poly); eb != ee; eb++ )
{
double angle = dihedral_angle(*eb);
if (angle < PI*3.0/4.0)
{
d->is_sharp_vertices[ boost::get(*d->vertex_index_map, *vb) ] = true;
break;
}
}
}
}
@ -475,8 +513,7 @@ Selected_vertices extend_circle(Selected_vertices selected_vertices, double radi
// extend vertices until reaching the sharp edges
Selected_vertices extend_sharp_edge(Selected_vertices selected_vertices, double tolerance,
std::vector<double> dihedral_angle_variance, Vertex_index_map vertex_index_map)
Selected_vertices extend_sharp_edge(Selected_vertices selected_vertices, std::vector<bool> is_sharp_vertices, Vertex_index_map vertex_index_map)
{
std::vector<Vertex_handle> selected_vertices_vector;
selected_vertices_vector.insert(selected_vertices_vector.begin(), selected_vertices.begin(), selected_vertices.end());
@ -496,7 +533,7 @@ Selected_vertices extend_sharp_edge(Selected_vertices selected_vertices, double
do {
const Vertex_handle other_v = he_it->opposite()->vertex();
int idx = boost::get(vertex_index_map, other_v);
if( dihedral_angle_variance[idx] <= tolerance )
if( !is_sharp_vertices[idx] )
{
std::vector<Vertex_handle>::iterator it = std::find(selected_vertices_vector.begin(), selected_vertices_vector.end(), other_v);
if (it == selected_vertices_vector.end())
@ -541,35 +578,41 @@ void Scene_edit_polyhedron_item::vertex_has_been_selected(void* void_ptr) {
distance_map (*d->dist_pmap));
}
if (d->selected_handles_moved) // re-compute variance of dihedral angles for each vertex
{
compute_dihedral_angle_variance();
}
// set new handles and ROI regions
Selected_vertices new_handles;
new_handles.insert(vh);
new_handles = extend_k_ring(new_handles, d->handlesRegionSize);
Selected_vertices new_roi = new_handles;
new_roi = extend_k_ring( new_roi, d->interestRegionSize - d->handlesRegionSize );
if (d->geodesicCircle)
Selected_vertices new_roi;
if (d->sharpFeature)
{
double radius = 0;
BOOST_FOREACH(Vertex_handle v, new_handles)
{
double dist = boost::get(*d->dist_pmap, v);
if ( dist> radius ) radius = dist;
}
new_handles = extend_circle(new_handles, radius, *d->dist_pmap);
radius = 0;
BOOST_FOREACH(Vertex_handle v, new_roi)
{
double dist = boost::get(*d->dist_pmap, v);
if ( dist> radius ) radius = dist;
}
new_roi = extend_circle(new_roi, radius, *d->dist_pmap);
new_roi.insert(vh);
new_roi = extend_sharp_edge(new_roi, d->is_sharp_vertices, *d->vertex_index_map);
}
else
{
new_roi = new_handles;
new_roi = extend_k_ring( new_roi, d->interestRegionSize - d->handlesRegionSize );
if (d->geodesicCircle)
{
double radius = 0;
BOOST_FOREACH(Vertex_handle v, new_handles)
{
double dist = boost::get(*d->dist_pmap, v);
if ( dist> radius ) radius = dist;
}
new_handles = extend_circle(new_handles, radius, *d->dist_pmap);
radius = 0;
BOOST_FOREACH(Vertex_handle v, new_roi)
{
double dist = boost::get(*d->dist_pmap, v);
if ( dist> radius ) radius = dist;
}
new_roi = extend_circle(new_roi, radius, *d->dist_pmap);
}
}
// multiple handles scenario
if (d->usageScenario == 1)
{
if (d->selected_vertex != vh) // selected_vertex changed
@ -671,7 +714,7 @@ void Scene_edit_polyhedron_item::vertex_has_been_selected_2(void* void_ptr) {
}
if (d->selected_handles_moved) // re-compute variance of dihedral angles for each vertex
{
compute_dihedral_angle_variance();
find_sharp_vertices_1();
}
if (d->selected_vertex_changed || d->selected_handles_moved) // selected_vertex is changed or moved
{

View File

@ -82,7 +82,8 @@ public:
void setSelectedHandlesMoved(bool status);
void setSelectedVector(Kernel::Vector_3 translation_last);
double dihedral_angle(edge_descriptor e);
void compute_dihedral_angle_variance();
void find_sharp_vertices();
void find_sharp_vertices_1();
/// @deprecated
QList<Polyhedron::Vertex_handle> selected_vertices()
@ -110,6 +111,7 @@ public slots:
void setHandlesRegionSize(int i);
void setInterestRegionSize(int i);
void setGeodesicCircle(bool status);
void setSharpFeature(bool status);
void setUsageScenario(int i);
void vertex_has_been_selected(void* vertex_handle);
void vertex_has_been_selected_2(void* vertex_handle);

View File

@ -834,14 +834,14 @@ public:
double energy_last;
// iterations
CGAL_TRACE_STREAM << "iteration started...\n";
optimal_rotations_polar();
optimal_rotations_svd();
for ( int ite = 0; ite < iterations; ite ++)
{
update_solution();
optimal_rotations_polar();
optimal_rotations_svd();
energy_last = energy_this;
energy_this = energy();
//CGAL_TRACE_STREAM << ite << " iterations: energy = " << energy_this << "\n";
CGAL_TRACE_STREAM << ite << " iterations: energy = " << energy_this << "\n";
if ( abs((energy_last-energy_this)/energy_this) < tolerance )
{
break;