From 9966c8ae669a2a04475af43e2057072dc4eb6c7e Mon Sep 17 00:00:00 2001 From: Yin Xu Date: Wed, 3 Aug 2011 14:22:06 +0000 Subject: [PATCH] sharp feature detection --- Polyhedron/demo/Polyhedron/Deform_mesh.ui | 9 +- ...Polyhedron_demo_edit_polyhedron_plugin.cpp | 3 + .../Polyhedron/Scene_edit_polyhedron_item.cpp | 109 ++++++++++++------ .../Polyhedron/Scene_edit_polyhedron_item.h | 4 +- .../include/CGAL/Deform_mesh_BGL.h | 6 +- 5 files changed, 93 insertions(+), 38 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Deform_mesh.ui b/Polyhedron/demo/Polyhedron/Deform_mesh.ui index b8b2b901948..317179e9300 100644 --- a/Polyhedron/demo/Polyhedron/Deform_mesh.ui +++ b/Polyhedron/demo/Polyhedron/Deform_mesh.ui @@ -6,7 +6,7 @@ 0 0 - 260 + 280 223 @@ -110,6 +110,13 @@ + + + + Sharp feature + + + diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp index 056aca24aeb..4c09f2461e8 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp @@ -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); diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp index f329a679148..4e9f5a68811 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp @@ -28,7 +28,7 @@ typedef Polyhedron_vertex_deformation_index_map Vertex_index_map; typedef Polyhedron_edge_deformation_length_map Edge_length_map; typedef boost::iterator_property_map::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 geodesic_distance; Dist_pmap* dist_pmap; - std::vector dihedral_angle_variance; + std::vector 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 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 dihedral_angle_variance, Vertex_index_map vertex_index_map) +Selected_vertices extend_sharp_edge(Selected_vertices selected_vertices, std::vector is_sharp_vertices, Vertex_index_map vertex_index_map) { std::vector 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::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 { diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index 8bb983df795..6d5ba0f114e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -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 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); diff --git a/Surface_modeling/include/CGAL/Deform_mesh_BGL.h b/Surface_modeling/include/CGAL/Deform_mesh_BGL.h index be09bfe2928..02bf9a11be4 100644 --- a/Surface_modeling/include/CGAL/Deform_mesh_BGL.h +++ b/Surface_modeling/include/CGAL/Deform_mesh_BGL.h @@ -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;