remove handle_group (header, examples, tests, and demo)

This commit is contained in:
iyaz 2013-08-11 17:29:27 +03:00
parent c235f00659
commit 2c4ece7e57
10 changed files with 140 additions and 325 deletions

View File

@ -257,16 +257,13 @@ void Scene_edit_polyhedron_item::draw_ROI_and_handles() const {
// draw handle related things
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
Deform_mesh::Const_handle_group hgb, hge;
for(boost::tie(hgb, hge) = deform_mesh.handle_groups(); hgb != hge; ++hgb)
for(Handle_group_data_list::const_iterator hgb_data = handle_frame_map.begin(); hgb_data != handle_frame_map.end(); ++hgb_data)
{
// draw axis using manipulated frame assoc with handle_group
const Handle_group_data& hgb_data = get_data(hgb);
if(hgb_data.frame == viewer->manipulatedFrame())
if(hgb_data->frame == viewer->manipulatedFrame())
{
// draw axis
::glPushMatrix();
::glMultMatrixd(hgb_data.frame->matrix());
::glMultMatrixd(hgb_data->frame->matrix());
QGLViewer::drawAxis(length_of_axis);
::glPopMatrix();
// draw bbox
@ -274,20 +271,18 @@ void Scene_edit_polyhedron_item::draw_ROI_and_handles() const {
{
color.set_rgb_color(1.0f, 0, 0);
::glPushMatrix();
::glTranslated(hgb_data.frame->position().x, hgb_data.frame->position().y, hgb_data.frame->position().z);
::glMultMatrixd(hgb_data.frame->orientation().matrix());
::glTranslated(-hgb_data.frame_initial_center.x, -hgb_data.frame_initial_center.y, -hgb_data.frame_initial_center.z);
draw_bbox(hgb_data.bbox);
::glTranslated(hgb_data->frame->position().x, hgb_data->frame->position().y, hgb_data->frame->position().z);
::glMultMatrixd(hgb_data->frame->orientation().matrix());
::glTranslated(-hgb_data->frame_initial_center.x, -hgb_data->frame_initial_center.y, -hgb_data->frame_initial_center.z);
draw_bbox(hgb_data->bbox);
::glPopMatrix();
}
}
// draw handle points
if(hgb == active_group) { color.set_rgb_color(1.0f, 0, 0); }
if(hgb_data == active_group) { color.set_rgb_color(1.0f, 0, 0); }
else { color.set_rgb_color(0, 0, 1.0f); }
Deform_mesh::Handle_const_iterator hb, he;
for(boost::tie(hb, he) = deform_mesh.handles(hgb); hb != he; ++hb)
{
gl_draw_point( (*hb)->point() );
for(std::vector<vertex_descriptor>::const_iterator hb = hgb_data->handle_group.begin(); hb != hgb_data->handle_group.end(); ++hb)
{ gl_draw_point( (*hb)->point() );
}
}

View File

@ -96,7 +96,7 @@ typedef Deform_mesh::Point Point;
class Handle_group_data
{
public:
Deform_mesh::Handle_group handle_group;
std::vector<vertex_descriptor> handle_group;
qglviewer::ManipulatedFrame* frame; // manframe assoc with handle group
qglviewer::Vec frame_initial_center; // initial center of frame
Scene_interface::Bbox bbox; // bbox of handles inside group
@ -106,11 +106,18 @@ private:
Deform_mesh* deform_mesh;
public:
Handle_group_data(Deform_mesh::Handle_group handle_group, Deform_mesh* deform_mesh, qglviewer::ManipulatedFrame* frame = 0)
: handle_group(handle_group), frame(frame), bbox(0,0,0,0,0,0), rot_direction(0.,0.,1.), deform_mesh(deform_mesh)
Handle_group_data(Deform_mesh* deform_mesh, qglviewer::ManipulatedFrame* frame = 0)
: frame(frame), bbox(0,0,0,0,0,0), rot_direction(0.,0.,1.), deform_mesh(deform_mesh)
{ }
void refresh()
{
for(std::vector<vertex_descriptor>::iterator it = handle_group.begin(); it != handle_group.end(); ) {
if(!deform_mesh->is_handle(*it)) {
it = handle_group.erase(it);
}
else { ++it; }
}
reset_initial_positions();
frame_initial_center = calculate_initial_center();
bbox = calculate_initial_bbox();
@ -123,8 +130,7 @@ public:
}
void assign()
{
Deform_mesh::Handle_iterator hb, he;
boost::tie(hb, he) = deform_mesh->handles(handle_group);
std::vector<vertex_descriptor>::iterator hb = handle_group.begin();
for(std::vector<qglviewer::Vec>::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it, ++hb)
{
qglviewer::Vec dif_from_initial_center = (*it) - frame_initial_center;
@ -139,8 +145,8 @@ private:
void reset_initial_positions()
{
initial_positions.clear();
Deform_mesh::Handle_iterator hb, he;
for(boost::tie(hb, he) = deform_mesh->handles(handle_group); hb != he; ++hb)
for(std::vector<vertex_descriptor>::iterator hb = handle_group.begin(); hb != handle_group.end(); ++hb)
{
qglviewer::Vec point((*hb)->point().x(), (*hb)->point().y(), (*hb)->point().z() );
initial_positions.push_back(point);
@ -266,8 +272,8 @@ private:
std::vector<double> normals;
Deform_mesh deform_mesh;
Deform_mesh::Handle_group active_group;
typedef std::list<Handle_group_data> Handle_group_data_list;
Handle_group_data_list::iterator active_group;
Handle_group_data_list handle_frame_map; // keep list of handle_groups with assoc data
double length_of_axis; // for drawing axis at a handle group
@ -289,8 +295,11 @@ public:
return false;
} // no handle group to insert
bool inserted = deform_mesh.insert_handle(active_group, v);
get_data(active_group).refresh();
bool inserted = deform_mesh.insert_handle(v);
if(inserted) {
active_group->handle_group.push_back(v);
active_group->refresh();
}
return inserted;
}
@ -340,15 +349,15 @@ public:
void create_handle_group()
{
active_group = deform_mesh.create_handle_group();
qglviewer::ManipulatedFrame* new_frame = new qglviewer::ManipulatedFrame();
new_frame->setRotationSensitivity(2.0f);
Handle_group_data hgd(active_group, &deform_mesh, new_frame);
Handle_group_data hgd(&deform_mesh, new_frame);
handle_frame_map.push_back(hgd);
hgd.refresh();
active_group = --handle_frame_map.end();
connect(new_frame, SIGNAL(modified()), this, SLOT(deform())); // OK we are deforming via timer,
// but it makes demo more responsive if we also add this signal
emit itemChanged();
@ -366,17 +375,19 @@ public:
// delete group representative
for(Handle_group_data_list::iterator it = handle_frame_map.begin(); it != handle_frame_map.end(); ++it)
{
if(it->handle_group == active_group)
if(it == active_group)
{
delete it->frame;
handle_frame_map.erase(it);
delete it->frame;
for(std::vector<vertex_descriptor>::iterator v_it = it->handle_group.begin(); v_it != it->handle_group.end(); ++v_it) {
deform_mesh.erase_handle(*v_it);
}
handle_frame_map.erase(it);
break;
}
}
deform_mesh.erase_handle(active_group);
// assign another handle_group to active_group
Deform_mesh::Handle_group hgb, hge;
Handle_group_data_list::iterator hgb, hge;
if( is_there_any_handle_group(hgb, hge) )
{
active_group = hgb;
@ -389,7 +400,7 @@ public:
void prev_handle_group()
{
Deform_mesh::Handle_group hgb, hge;
Handle_group_data_list::iterator hgb, hge;
if( !is_there_any_handle_group(hgb, hge) ) {
print_message("There is no handle group to iterate on!");
return;
@ -401,7 +412,7 @@ public:
void next_handle_group()
{
Deform_mesh::Handle_group hgb, hge;
Handle_group_data_list::iterator hgb, hge;
if( !is_there_any_handle_group(hgb, hge) ) {
print_message("There is no handle group to iterate on!");
return;
@ -455,17 +466,12 @@ public:
}
out << std::endl;
// save handles
hc = 0;
Deform_mesh::Const_handle_group hgb, hge;
for(boost::tie(hgb, hge) = deform_mesh.handle_groups(); hgb != hge; ++hgb)
{ ++hc; }
out << hc << std::endl; // handle count
for(boost::tie(hgb, hge) = deform_mesh.handle_groups(); hgb != hge; ++hgb) {
hc = 0;
Deform_mesh::Handle_const_iterator hb, he;
for(boost::tie(hb, he) = deform_mesh.handles(hgb); hb != he; ++hb) { ++hc; }
out << hc << std::endl;
for(boost::tie(hb, he) = deform_mesh.handles(hgb); hb != he; ++hb)
out << handle_frame_map.size() << std::endl; // handle count
for(Handle_group_data_list::const_iterator hgb = handle_frame_map.begin(); hgb != handle_frame_map.end(); ++hgb) {
out << hgb->handle_group.size() << std::endl;
for(std::vector<vertex_descriptor>::const_iterator hb = hgb->handle_group.begin(); hb != hgb->handle_group.end(); ++hb)
{
out << (*hb)->id() << " ";
}
@ -613,28 +619,26 @@ protected:
// std::cout << message.toStdString() << std::endl;
}
bool is_there_any_handle_group(Deform_mesh::Handle_group& hgb, Deform_mesh::Handle_group& hge)
bool is_there_any_handle_group(Handle_group_data_list::iterator& hgb, Handle_group_data_list::iterator& hge)
{
boost::tie(hgb, hge) = deform_mesh.handle_groups();
hgb = handle_frame_map.begin(); hge = handle_frame_map.end();
return hgb != hge;
}
bool is_there_any_handle_group()
{
Deform_mesh::Handle_group hgb, hge;
Handle_group_data_list::iterator hgb, hge;
return is_there_any_handle_group(hgb, hge);
}
bool is_there_any_handle()
{
Deform_mesh::Handle_group hgb, hge;
Handle_group_data_list::iterator hgb, hge;
if(!is_there_any_handle_group(hgb, hge)) { return false; } // there isn't any handle group
for(; hgb != hge; ++hgb) // check inside handle groups
{
Deform_mesh::Handle_iterator hb, he;
boost::tie(hb, he) = deform_mesh.handles(hgb);
if(hb != he) { return true; }
if(!hgb->handle_group.empty()) { return true; }
}
return false;
}
@ -670,24 +674,6 @@ protected:
{ it->refresh(); }
}
Handle_group_data& get_data(Deform_mesh::Handle_group hg)
{
for(Handle_group_data_list::iterator it = handle_frame_map.begin(); it != handle_frame_map.end(); ++it) {
if(it->handle_group == hg) { return *it; }
}
return *handle_frame_map.end(); // crash
// this can't happen since every created handle group is inserted in handle_frame_map
}
Handle_group_data get_data(Deform_mesh::Const_handle_group hg) const
{
for(Handle_group_data_list::const_iterator it = handle_frame_map.begin(); it != handle_frame_map.end(); ++it) {
if(it->handle_group == hg) { return *it; }
}
return *handle_frame_map.end(); // crash
// this can't happen since every created handle group is inserted in handle_frame_map
}
std::map<vertex_descriptor, int> extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k)
{
std::map<vertex_descriptor, int> D;

View File

@ -63,13 +63,11 @@ int main()
deform_mesh.insert_roi(vb, ve); // insert whole mesh as roi
// insert handles
Deform_mesh::Handle_group handles_ref = deform_mesh.create_handle_group();
vertex_descriptor handle_1 = *boost::next(vb, 213);
vertex_descriptor handle_2 = *boost::next(vb, 157);
deform_mesh.insert_handle(handles_ref, handle_1); // insert handles
deform_mesh.insert_handle(handles_ref, handle_2);
deform_mesh.insert_handle(handle_1); // insert handles
deform_mesh.insert_handle(handle_2);
// insertion of roi and handles completed, call preprocess
bool is_matrix_factorization_OK = deform_mesh.preprocess();
@ -102,7 +100,7 @@ int main()
// want to add another handle
//// PREPROCESS SECTION AGAIN////
vertex_descriptor handle_3 = *boost::next(vb, 92);
deform_mesh.insert_handle(handles_ref, handle_3); // now I need to prepocess again
deform_mesh.insert_handle(handle_3); // now I need to prepocess again
if(!deform_mesh.preprocess()){
std::cerr << "Check documentation of preprocess()" << std::endl;

View File

@ -107,14 +107,11 @@ int main()
deform_mesh.insert_roi(vb, ve); // insert whole mesh as roi
// insert handles
Deform_mesh::Handle_group handles_ref = deform_mesh.create_handle_group();
vertex_descriptor handle_1 = *boost::next(vb, 213);
vertex_descriptor handle_2 = *boost::next(vb, 157);
deform_mesh.insert_handle(handles_ref, handle_1); // insert handles
deform_mesh.insert_handle(handles_ref, handle_2);
deform_mesh.insert_handle(handle_1); // insert handles
deform_mesh.insert_handle(handle_2);
// insertion of roi and handles completed, call preprocess
bool is_matrix_factorization_OK = deform_mesh.preprocess();
@ -127,7 +124,7 @@ int main()
// now use assign() to provide constained positions of handles
Deform_mesh::Point constrained_pos_1(-0.35, 0.40, 0.60); // target position of handle_1
deform_mesh.assign(handle_1, constrained_pos_1);
// note that we only assign a constraint for handle_1, other handles will be constained to last assigned positions
// note that we only assign a constraint for handle_1, other handles will be constrained to last assigned positions
// deform the mesh, now positions of vertices of 'mesh' will be changed
deform_mesh.deform();
@ -147,7 +144,7 @@ int main()
// want to add another handle
//// PREPROCESS SECTION AGAIN////
vertex_descriptor handle_3 = *boost::next(vb, 92);
deform_mesh.insert_handle(handles_ref, handle_3); // now I need to prepocess again
deform_mesh.insert_handle(handle_3); // now I need to prepocess again
if(!deform_mesh.preprocess()) {
std::cerr << "Check documentation of preprocess()" << std::endl;

View File

@ -31,27 +31,27 @@ typedef boost::associative_property_map<Internal_edge_map> Edge_index_map;
typedef CGAL::Deform_mesh<Polyhedron, Vertex_index_map, Edge_index_map> Deform_mesh;
// extract vertices which are at most k (inclusive) far from vertex v
std::map<vertex_descriptor, int> extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k)
std::vector<vertex_descriptor> extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k)
{
std::map<vertex_descriptor, int> D;
std::queue<vertex_descriptor> Q;
Q.push(v); D[v] = 0;
std::vector<vertex_descriptor> Q;
Q.push_back(v); D[v] = 0;
std::size_t current_index = 0;
int dist_v;
while( !Q.empty() && (dist_v = D[Q.front()]) < k ) {
v = Q.front();
Q.pop();
while( current_index < Q.size() && (dist_v = D[ Q[current_index] ]) < k ) {
v = Q[current_index++];
out_edge_iterator e, e_end;
for(boost::tie(e, e_end) = boost::out_edges(v, P); e != e_end; e++)
{
vertex_descriptor new_v = boost::target(*e, P);
if(D.insert(std::make_pair(new_v, dist_v + 1)).second) {
Q.push(new_v);
Q.push_back(new_v);
}
}
}
return D;
return Q;
}
int main()
@ -86,35 +86,25 @@ int main()
// insert region of interest
boost::tie(vb,ve) = boost::vertices(mesh);
std::map<vertex_descriptor, int> roi_map = extract_k_ring(mesh, *boost::next(vb, 47), 9);
std::map<vertex_descriptor, int> handles_1_map = extract_k_ring(mesh, *boost::next(vb, 39), 1);
std::map<vertex_descriptor, int> handles_2_map = extract_k_ring(mesh, *boost::next(vb, 97), 1);
std::vector<vertex_descriptor> roi_map = extract_k_ring(mesh, *boost::next(vb, 47), 9);
std::vector<vertex_descriptor> handles_1_map = extract_k_ring(mesh, *boost::next(vb, 39), 1);
std::vector<vertex_descriptor> handles_2_map = extract_k_ring(mesh, *boost::next(vb, 97), 1);
for(std::map<vertex_descriptor, int>::iterator it = roi_map.begin(); it != roi_map.end(); ++it) {
deform_mesh.insert_roi(it->first);
}
Deform_mesh::Handle_group handles_1 = deform_mesh.create_handle_group();
for(std::map<vertex_descriptor, int>::iterator it = handles_1_map.begin(); it != handles_1_map.end(); ++it) {
deform_mesh.insert_handle(handles_1, it->first);
}
Deform_mesh::Handle_group handles_2 = deform_mesh.create_handle_group();
for(std::map<vertex_descriptor, int>::iterator it = handles_2_map.begin(); it != handles_2_map.end(); ++it) {
deform_mesh.insert_handle(handles_2, it->first);
}
deform_mesh.insert_roi(roi_map.begin(), roi_map.end());
deform_mesh.insert_handle(handles_1_map.begin(), handles_1_map.end());
deform_mesh.insert_handle(handles_2_map.begin(), handles_2_map.end());
deform_mesh.preprocess();
//// DEFORM SECTION ////
deform_mesh.translate(handles_1, Eigen::Vector3d(0,0,1));
deform_mesh.translate(handles_1_map.begin(), handles_1_map.end(), Eigen::Vector3d(0,0,1));
// overrides any previous call
Eigen::Quaternion<double> quad(0.92, 0, 0, -0.38);
Eigen::Vector3d vect(0, 0, 0);
deform_mesh.rotate(handles_1, Deform_mesh::Point(0,0,0), quad, vect);
deform_mesh.rotate(handles_2, Deform_mesh::Point(0,0,0), quad, vect);
deform_mesh.rotate(handles_1_map.begin(), handles_1_map.end(), Deform_mesh::Point(0,0,0), quad, vect);
deform_mesh.rotate(handles_2_map.begin(), handles_2_map.end(), Deform_mesh::Point(0,0,0), quad, vect);
deform_mesh.deform();
@ -124,8 +114,8 @@ int main()
// Note that translate and rotate are not cumulative,
// they just use original positions (positions at the time of construction) of the handles while calculating target positions
deform_mesh.translate(handles_1, Eigen::Vector3d(0,0.30,0));
deform_mesh.translate(handles_2, Eigen::Vector3d(0,0.30,0));
deform_mesh.translate(handles_1_map.begin(), handles_1_map.end(), Eigen::Vector3d(0,0.30,0));
deform_mesh.translate(handles_2_map.begin(), handles_2_map.end(), Eigen::Vector3d(0,0.30,0));
deform_mesh.set_iterations(10);
deform_mesh.set_tolerance(0.0);

View File

@ -180,28 +180,10 @@ private:
typedef typename boost::graph_traits<Halfedge_graph>::in_edge_iterator in_edge_iterator;
typedef typename boost::graph_traits<Halfedge_graph>::out_edge_iterator out_edge_iterator;
// Handle container types
typedef std::list<vertex_descriptor> Handle_container;
typedef std::list<Handle_container> Handle_group_container;
typedef typename Closest_rotation_helper::Matrix CR_matrix;
typedef typename Closest_rotation_helper::Vector CR_vector;
public:
/** The type used as the representative of a group of handles*/
typedef typename Handle_group_container::iterator Handle_group;
/** Const version of Handle_group*/
typedef typename Handle_group_container::const_iterator Const_handle_group;
/** Iterator over the groups of handles. The type can be implicitly
converted to Deform_mesh::Handle_group or Deform_mesh::Const_handle_group */
typedef typename Handle_group_container::iterator Handle_group_iterator;
/** Const version of Handle_group_iterator */
typedef typename Handle_group_container::const_iterator Handle_group_const_iterator;
/** Iterator over vertex descriptors in a group of handles. Its value type is `vertex_descriptor` */
typedef typename Handle_container::iterator Handle_iterator;
/** Const version of Handle_iterator*/
typedef typename Handle_container::const_iterator Handle_const_iterator;
/** Iterator over vertex descriptors in the region-of-interest. Its value type is `vertex_descriptor` */
typedef typename std::vector<vertex_descriptor>::iterator Roi_iterator;
@ -236,7 +218,6 @@ private:
bool need_preprocess_region_of_solution; ///< is there any need to compute region of solution
bool last_preprocess_successful; ///< stores the result of last call to preprocess()
Handle_group_container handle_group_list; ///< user specified handles
Weight_calculator weight_calculator;
@ -332,149 +313,53 @@ public:
need_preprocess_both();
// clear vertices
roi.clear();
handle_group_list.clear();
is_roi_map.assign(boost::num_vertices(m_halfedge_graph), false);
is_hdl_map.assign(boost::num_vertices(m_halfedge_graph), false);
}
/**
* Creates a new empty group of handles.
* `insert_handle(Handle_group handle_group, vertex_descriptor vd)` or `insert_handle(Handle_group handle_group, InputIterator begin, InputIterator end)`
* must be used to insert handles in a group.
* After inserting vertices, use `translate()` or `rotate()` for applying a transformation on all the vertices inside a group.
* @return a representative of the group of handles created (it is valid until `erase_handle(Handle_group handle_group)` is called)
*/
Handle_group create_handle_group()
{
// no need to need_preprocess = true;
handle_group_list.push_back(Handle_container());
return --handle_group_list.end();
}
/**
* Inserts a vertex into a group of handles. The vertex is also inserted in the region-of-interest if it is not already in it.
* @param handle_group the group where the vertex is inserted in
* Inserts a vertex into handles. The vertex is also inserted in the region-of-interest if it is not already in it.
* @param vd the vertex to be inserted
* @return `true` if the insertion is successful
*/
bool insert_handle(Handle_group handle_group, vertex_descriptor vd)
bool insert_handle(vertex_descriptor vd)
{
if(is_handle(vd)) { return false; }
need_preprocess_both();
insert_roi(vd); // also insert it as roi
is_hdl_map[id(vd)] = true;
handle_group->push_back(vd);
is_hdl_map[id(vd)] = true;
return true;
}
/**
* Inserts a range of vertices in a group of handles. The vertices are also inserted in the region-of-interest if they are not already in it.
* Inserts a range of vertices into handles. The vertices are also inserted in the region-of-interest if they are not already in it.
* @tparam InputIterator input iterator type with `vertex_descriptor` as value type
* @param handle_group the group where the vertex is inserted in
* @param begin first iterator of the range of vertices
* @param end past-the-end iterator of the range of vertices
*/
template<class InputIterator>
void insert_handle(Handle_group handle_group, InputIterator begin, InputIterator end)
void insert_handle(InputIterator begin, InputIterator end)
{
for( ;begin != end; ++begin)
{
insert_handle(handle_group, *begin);
insert_handle(*begin);
}
}
/**
* Erases a group of handles. Its representative becomes invalid.
* @param handle_group the group to be erased
*/
void erase_handle(Handle_group handle_group)
{
need_preprocess_both();
for(typename Handle_container::iterator it = handle_group->begin(); it != handle_group->end(); ++it)
{
is_hdl_map[id(*it)] = false;
}
handle_group_list.erase(handle_group);
}
/**
* Erases a vertex from a group of handles.
* \note The group of handles is not erased even if it becomes empty.
* @param handle_group the group where the vertex is erased from
* @param vd the vertex to be erased
* @return `true` if the removal is successful
*/
bool erase_handle(Handle_group handle_group, vertex_descriptor vd)
{
if(!is_handle(vd)) { return false; }
typename Handle_container::iterator it = std::find(handle_group->begin(), handle_group->end(), vd);
if(it != handle_group->end())
{
is_hdl_map[id(*it)] = false;
handle_group->erase(it);
need_preprocess_both();
return true;
// Although the handle group might get empty, we do not delete it from handle_group
}
return false; // OK (vd is handle but placed in other handle group than handle_group argument)
}
/**
* Erases a vertex by searching it through all groups of handles.
* \note The group of handles is not erased even if it becomes empty.
* Erases a vertex from handles.
* @param vd the vertex to be erased
* @return `true` if the removal is successful
*/
bool erase_handle(vertex_descriptor vd)
{
if(!is_handle(vd)) { return false; }
for(Handle_group it = handle_group_list.begin(); it != handle_group_list.end(); ++it)
{
if(erase_handle(it, vd)) { return true; }
}
CGAL_assertion(false);// inconsistency between is_handle_map, and handle_group_list
return false;
}
/**
* Provides access to all the groups of handles.
* @return the range of iterators over all groups of handles
*/
std::pair<Handle_group_iterator, Handle_group_iterator> handle_groups()
{
return std::make_pair(handle_group_list.begin(), handle_group_list.end());
}
/**
* Const version
*/
std::pair<Handle_group_const_iterator, Handle_group_const_iterator> handle_groups() const
{
return std::make_pair(handle_group_list.begin(), handle_group_list.end());
}
/**
* Provides access to all the handles inside a group.
* @param handle_group the group containing handles
* @return the range of iterators over all handles inside a group
*
*/
std::pair<Handle_iterator, Handle_iterator> handles(Handle_group handle_group)
{
return std::make_pair(handle_group->begin(), handle_group->end());
}
/**
* Const version
*/
std::pair<Handle_const_iterator, Handle_const_iterator> handles(Const_handle_group handle_group) const
{
return std::make_pair(handle_group->begin(), handle_group->end());
need_preprocess_both();
is_hdl_map[id(vd)] = false;
return true;
}
/**
@ -576,19 +461,21 @@ public:
* \note This transformation is applied on the original positions of the vertices
* (that is positions of vertices at the time of construction or after the last call to `overwrite_original_positions()`).
* \note A call to this function cancels the last call to `rotate()`, `translate()`, or `assign()`.
*
* @tparam InputIterator input iterator type with `vertex_descriptor` as value type
* @tparam Vect is a 3D vector class, `Vect::operator[](int i)` with i=0,1 or 2 returns its coordinates
* @param handle_group the representative of the group of handles to be translated
*
* @param begin first iterator of the range of vertices
* @param end past-the-end iterator of the range of vertices
* @param t translation vector
*/
template<class Vect>
void translate(Const_handle_group handle_group, const Vect& t)
template<class InputIterator, class Vect>
void translate(InputIterator begin, InputIterator end, const Vect& t)
{
region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it.
for(typename Handle_container::const_iterator it = handle_group->begin();
it != handle_group->end(); ++it)
{
std::size_t v_id = ros_id(*it);
for(; begin != end; ++begin) {
std::size_t v_id = ros_id(*begin);
solution[v_id] = add_to_point(original[v_id], t);
}
}
@ -599,22 +486,24 @@ public:
* \note This transformation is applied on the original positions of the vertices
* (that is positions of vertices at the time of construction or after the last call to `overwrite_original_positions()`).
* \note A call to this function cancels the last call to `rotate()`, `translate()`, or `assign()`.
*
* @tparam InputIterator input iterator type with `vertex_descriptor` as value type
* @tparam Quaternion is a quaternion class with `Vect operator*(Quaternion, Vect)` being defined and returns the product of a quaternion with a vector
* @tparam Vect is a 3D vector class, `Vect(double x,double y, double z)` being a constructor available and `Vect::operator[](int i)` with i=0,1 or 2 returns its coordinates
* @param handle_group the representative of the group of handles to be rotated and translated
*
* @param begin first iterator of the range of vertices
* @param end past-the-end iterator of the range of vertices
* @param rotation_center center of rotation
* @param quat rotation holder quaternion
* @param t post translation vector
*/
template <typename Quaternion, typename Vect>
void rotate(Const_handle_group handle_group, const Point& rotation_center, const Quaternion& quat, const Vect& t)
template <typename InputIterator, typename Quaternion, typename Vect>
void rotate(InputIterator begin, InputIterator end, const Point& rotation_center, const Quaternion& quat, const Vect& t)
{
region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it.
for(typename Handle_container::const_iterator it = handle_group->begin();
it != handle_group->end(); ++it)
{
std::size_t v_id = ros_id(*it);
for(; begin != end; ++begin) {
std::size_t v_id = ros_id(*begin);
Vect v = quat * sub_to_vector<Vect>(original[v_id], rotation_center);
const Point& rotated = add_to_point(rotation_center, v);
solution[v_id] = Point(rotated[0] + t[0], rotated[1] + t[1], rotated[2] + t[2]);

View File

@ -23,7 +23,7 @@ typedef CGAL::Deform_mesh<Polyhedron, Vertex_index_map, Edge_index_map, CGAL::SP
const double squared_threshold = 0.001; // alert if average difs between precomputed and deformed mesh models is above threshold
bool compare_mesh(const Polyhedron& mesh_1, const Polyhedron& mesh_2)
void compare_mesh(const Polyhedron& mesh_1, const Polyhedron& mesh_2)
{
Polyhedron::Vertex_const_iterator it_1 = mesh_1.vertices_begin();
Polyhedron::Vertex_const_iterator it_2 = mesh_2.vertices_begin();
@ -36,19 +36,18 @@ bool compare_mesh(const Polyhedron& mesh_1, const Polyhedron& mesh_2)
std::cerr << "Average mesh difference: " << average_mesh_dif << std::endl;
bool close_enough = average_mesh_dif < squared_threshold;
return close_enough;
assert( average_mesh_dif > squared_threshold);
}
// read deformation session saved as a handle differences
template<class DeformMesh>
bool read_handle_difs_and_deform(DeformMesh& deform_mesh, typename DeformMesh::Handle_group& active_handle_group)
template<class DeformMesh, class InputIterator>
void read_handle_difs_and_deform(DeformMesh& deform_mesh, InputIterator begin, InputIterator end)
{
typedef CGAL::Simple_cartesian<double>::Vector_3 Vector;
if(!deform_mesh.preprocess()) {
std::cerr << "Error: preprocess() failed!" << std::endl;
return false;
assert(false);
}
std::ifstream dif_stream("data/cactus_handle_differences.txt");
@ -62,7 +61,7 @@ bool read_handle_difs_and_deform(DeformMesh& deform_mesh, typename DeformMesh::H
for(std::size_t i = 0; i < dif_vector.size(); ++i)
{
timer.start();
deform_mesh.translate(active_handle_group, dif_vector[i]);
deform_mesh.translate(begin, end, dif_vector[i]);
deform_mesh.deform();
timer.stop();
@ -71,10 +70,8 @@ bool read_handle_difs_and_deform(DeformMesh& deform_mesh, typename DeformMesh::H
predeformed_cactus_file << "data/cactus_deformed/cactus_deformed_" << i << ".off";
Polyhedron predeformed_cactus;
if(!read_to_polyhedron(predeformed_cactus_file.str().c_str(), predeformed_cactus))
{ return false; }
if(!compare_mesh(predeformed_cactus, deform_mesh.halfedge_graph()) )
{ return false; }
read_to_polyhedron(predeformed_cactus_file.str().c_str(), predeformed_cactus);
compare_mesh(predeformed_cactus, deform_mesh.halfedge_graph());
// for saving deformation
//std::ofstream(predeformed_cactus_file) << deform_mesh.halfedge_graph();
@ -82,13 +79,12 @@ bool read_handle_difs_and_deform(DeformMesh& deform_mesh, typename DeformMesh::H
}
std::cerr << "Deformation performance (with default number_of_iteration and tolerance) " << std::endl
<< dif_vector.size() << " translation: " << timer.time() << std::endl;
return true;
}
int main()
{
Polyhedron mesh_1;
if(!read_to_polyhedron("data/cactus.off", mesh_1)) { return EXIT_FAILURE; }
read_to_polyhedron("data/cactus.off", mesh_1);
Polyhedron mesh_2 = mesh_1;
init_indices(mesh_1);
@ -97,20 +93,16 @@ int main()
Deform_mesh_arap deform_mesh_arap(mesh_1, Vertex_index_map(), Edge_index_map());
Deform_mesh_spoke deform_mesh_spoke(mesh_2, Vertex_index_map(), Edge_index_map());
// For original arap
boost::optional<Deform_mesh_arap::Handle_group> active_handle_group_1 =
std::vector<Deform_mesh_arap::vertex_descriptor> hg_1 =
read_rois(deform_mesh_arap, "data/cactus_roi.txt", "data/cactus_handle.txt");
if(!active_handle_group_1) { return EXIT_FAILURE; }
bool close_enough = read_handle_difs_and_deform(deform_mesh_arap, *active_handle_group_1);
if(!close_enough) { return EXIT_FAILURE; }
read_handle_difs_and_deform(deform_mesh_arap, hg_1.begin(), hg_1.end());
std::cerr << "ORIGINAL ARAP Success!" << std::endl;
// For spokes rims
boost::optional<Deform_mesh_spoke::Handle_group> active_handle_group_2 =
std::vector<Deform_mesh_arap::vertex_descriptor> hg_2 =
read_rois(deform_mesh_spoke, "data/cactus_roi.txt", "data/cactus_handle.txt");
if(!active_handle_group_2) { return EXIT_FAILURE; }
close_enough = read_handle_difs_and_deform(deform_mesh_spoke, *active_handle_group_2);
if(!close_enough) { return EXIT_FAILURE; }
read_handle_difs_and_deform(deform_mesh_spoke, hg_2.begin(), hg_2.end());
std::cerr << "SPOKES AND RIMS ARAP Success!" << std::endl;
std::cerr << "All done!" << std::endl;
}

View File

@ -32,36 +32,10 @@ typedef CGAL::Deform_mesh<Polyhedron, Vertex_index_map, Edge_index_map,
typedef CGAL::Deform_mesh<Polyhedron, Vertex_index_map, Edge_index_map,
CGAL::SPOKES_AND_RIMS> Deform_mesh_spoke;
template<class DeformMesh>
bool preprocess_and_deform(DeformMesh& deform_mesh, int deformation_iteration)
{
boost::optional<typename DeformMesh::Handle_group> active_handle_group =
read_rois(deform_mesh, "data/cactus_roi.txt", "data/cactus_handle.txt");
if(!active_handle_group) { return false; }
CGAL::Timer timer; timer.start();
if(!deform_mesh.preprocess()) {
std::cerr << "Error: preprocess() failed!" << std::endl;
return false;
}
std::cerr << "Preprocess time: " << timer.time() << std::endl;
timer.reset();
deform_mesh.translate(*active_handle_group, CGAL::Simple_cartesian<double>::Vector_3(-0.55, -0.30, 0.0) );
deform_mesh.deform(deformation_iteration, 0);
timer.stop();
std::cerr << "Deformation time (one handle translated and deform method iterated " <<
deformation_iteration << " times): " << timer.time() << std::endl;
return true;
}
int main()
{
Polyhedron mesh_1;
if(!read_to_polyhedron("data/cactus.off", mesh_1)) { return EXIT_FAILURE; }
read_to_polyhedron("data/cactus.off", mesh_1);
Polyhedron mesh_2 = mesh_1;
init_indices(mesh_1);
@ -74,20 +48,18 @@ int main()
const double x = -0.55; const double y = -0.50; const double z = -0.0;
std::cerr << "ORIGINAL_ARAP performance: " << std::endl;
bool successed = preprocess_and_deform(deform_mesh_arap,
preprocess_and_deform(deform_mesh_arap,
"data/cactus_roi.txt",
"data/cactus_handle.txt",
CGAL::Simple_cartesian<double>::Vector_3(x, y, z),
deformation_iteration);
if(!successed) { return EXIT_FAILURE; }
std::cerr << "SPOKES_AND_RIMS performance: " << std::endl;
successed = preprocess_and_deform(deform_mesh_spoke,
preprocess_and_deform(deform_mesh_spoke,
"data/cactus_roi.txt",
"data/cactus_handle.txt",
CGAL::Simple_cartesian<double>::Vector_3(x, y, z),
deformation_iteration);
if(!successed) { return EXIT_FAILURE; }
std::cerr << "Save deformed models" << std::endl;
std::ofstream("data/cactus_deformed_arap.off") << mesh_1;

View File

@ -27,15 +27,14 @@ public:
};
template<class Polyhedron>
bool read_to_polyhedron(const char* file_name, Polyhedron& mesh)
void read_to_polyhedron(const char* file_name, Polyhedron& mesh)
{
std::ifstream input(file_name);
if ( !input || !(input >> mesh) || mesh.empty() ){
std::cerr << "Error: can not read " << file_name << std::endl;
return false;
assert(false);
}
return true;
}
template<class Polyhedron>
@ -57,7 +56,7 @@ void init_indices(Polyhedron& poly) {
}
template<class DeformMesh>
boost::optional<typename DeformMesh::Handle_group>
std::vector<typename DeformMesh::vertex_descriptor>
read_rois(DeformMesh& deform_mesh,
const std::string& roi_file,
const std::string& handle_file)
@ -66,13 +65,13 @@ read_rois(DeformMesh& deform_mesh,
std::ifstream handle_stream(handle_file);
if(!roi_stream || !handle_stream) {
std::cerr << "Error: can not read roi or handle files" << std::endl;
return boost::optional<typename DeformMesh::Handle_group>();
assert(false);
}
typedef typename boost::graph_traits<typename DeformMesh::Polyhedron>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<typename DeformMesh::Halfedge_graph>::vertex_iterator vertex_iterator;
typedef typename DeformMesh::vertex_descriptor vertex_descriptor;
// put all vertices to a vector
typename DeformMesh::Polyhedron const& polyhedron = deform_mesh.halfedge_graph();
typename DeformMesh::Halfedge_graph const& polyhedron = deform_mesh.halfedge_graph();
std::vector<vertex_descriptor> vertices;
vertices.reserve(boost::num_edges(polyhedron));
@ -84,42 +83,41 @@ read_rois(DeformMesh& deform_mesh,
// put all handles into one handle group
std::size_t id;
typename DeformMesh::Handle_group active_handle_group = deform_mesh.create_handle_group();
std::vector<typename DeformMesh::vertex_descriptor> hg;
while(handle_stream >> id) {
deform_mesh.insert_handle(active_handle_group, vertices[id]);
deform_mesh.insert_handle(vertices[id]);
hg.push_back(vertices[id]);
}
while(roi_stream >> id) {
deform_mesh.insert_roi(vertices[id]);
}
return boost::make_optional(active_handle_group);
return hg;
}
template<class DeformMesh>
bool preprocess_and_deform(DeformMesh& deform_mesh,
void preprocess_and_deform(DeformMesh& deform_mesh,
const std::string& roi_file,
const std::string& handle_file,
CGAL::Simple_cartesian<double>::Vector_3 translate,
int deformation_iteration)
{
boost::optional<typename DeformMesh::Handle_group> active_handle_group =
std::vector<typename DeformMesh::vertex_descriptor> hg =
read_rois(deform_mesh, roi_file, handle_file);
if(!active_handle_group) { return false; }
CGAL::Timer timer; timer.start();
if(!deform_mesh.preprocess()) {
std::cerr << "Error: preprocess() failed!" << std::endl;
return false;
assert(false);
}
std::cerr << "Preprocess time: " << timer.time() << std::endl;
timer.reset();
deform_mesh.translate(*active_handle_group, translate);
deform_mesh.translate(hg.begin(), hg.end(), translate);
deform_mesh.deform(deformation_iteration, 0);
std::cerr << "Deformation time (one handle translated and deform method iterated " <<
deformation_iteration << " times): " << timer.time() << std::endl;
return true;
}

View File

@ -25,7 +25,7 @@ typedef CGAL::Deform_mesh<Polyhedron, Vertex_index_map, Edge_index_map, CGAL::SP
int main()
{
Polyhedron mesh_1;
if(!read_to_polyhedron("data/square.off", mesh_1)) { return EXIT_FAILURE; }
read_to_polyhedron("data/square.off", mesh_1);
Polyhedron mesh_2 = mesh_1;
init_indices(mesh_1);
@ -38,20 +38,18 @@ int main()
const double x = -0.45; const double y = -0.65; const double z = -0.0;
std::cerr << "ORIGINAL_ARAP performance: " << std::endl;
bool successed = preprocess_and_deform(deform_mesh_arap,
preprocess_and_deform(deform_mesh_arap,
"data/Symmetry_test_roi.txt",
"data/Symmetry_test_handle.txt",
CGAL::Simple_cartesian<double>::Vector_3(x, y, z),
deformation_iteration);
if(!successed) { return EXIT_FAILURE; }
std::cerr << "SPOKES_AND_RIMS performance: " << std::endl;
successed = preprocess_and_deform(deform_mesh_spoke,
preprocess_and_deform(deform_mesh_spoke,
"data/Symmetry_test_roi.txt",
"data/Symmetry_test_handle.txt",
CGAL::Simple_cartesian<double>::Vector_3(x, y, z),
deformation_iteration);
if(!successed) { return EXIT_FAILURE; }
std::cerr << "Save deformed models" << std::endl;
std::ofstream("data/Symmetry_test_deformed_arap.off") << mesh_1;