diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp index afd012bf387..b2fdb76beb6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp @@ -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::const_iterator hb = hgb_data->handle_group.begin(); hb != hgb_data->handle_group.end(); ++hb) + { gl_draw_point( (*hb)->point() ); } } diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index b6e1ef34a82..3586d32e350 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -96,7 +96,7 @@ typedef Deform_mesh::Point Point; class Handle_group_data { public: - Deform_mesh::Handle_group handle_group; + std::vector 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::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::iterator hb = handle_group.begin(); for(std::vector::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::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 normals; Deform_mesh deform_mesh; - Deform_mesh::Handle_group active_group; typedef std::list 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::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::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 extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k) { std::map D; diff --git a/Surface_modeling/examples/Surface_modeling/all_roi_assign_example.cpp b/Surface_modeling/examples/Surface_modeling/all_roi_assign_example.cpp index f0b7a1f30a4..86de5484458 100644 --- a/Surface_modeling/examples/Surface_modeling/all_roi_assign_example.cpp +++ b/Surface_modeling/examples/Surface_modeling/all_roi_assign_example.cpp @@ -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; diff --git a/Surface_modeling/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp b/Surface_modeling/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp index 1ea6b256627..7046de1ba3b 100644 --- a/Surface_modeling/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp +++ b/Surface_modeling/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp @@ -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; diff --git a/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp b/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp index 59ac65378a0..727b6f48aa8 100644 --- a/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp +++ b/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp @@ -31,27 +31,27 @@ typedef boost::associative_property_map Edge_index_map; typedef CGAL::Deform_mesh Deform_mesh; // extract vertices which are at most k (inclusive) far from vertex v -std::map extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k) +std::vector extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k) { std::map D; - std::queue Q; - Q.push(v); D[v] = 0; + std::vector 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 roi_map = extract_k_ring(mesh, *boost::next(vb, 47), 9); - std::map handles_1_map = extract_k_ring(mesh, *boost::next(vb, 39), 1); - std::map handles_2_map = extract_k_ring(mesh, *boost::next(vb, 97), 1); + std::vector roi_map = extract_k_ring(mesh, *boost::next(vb, 47), 9); + std::vector handles_1_map = extract_k_ring(mesh, *boost::next(vb, 39), 1); + std::vector handles_2_map = extract_k_ring(mesh, *boost::next(vb, 97), 1); - for(std::map::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::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::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 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); diff --git a/Surface_modeling/include/CGAL/Deform_mesh.h b/Surface_modeling/include/CGAL/Deform_mesh.h index b95a4a3b8bc..028e6298184 100644 --- a/Surface_modeling/include/CGAL/Deform_mesh.h +++ b/Surface_modeling/include/CGAL/Deform_mesh.h @@ -180,28 +180,10 @@ private: typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - // Handle container types - typedef std::list Handle_container; - typedef std::list 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::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 - 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_groups() - { - return std::make_pair(handle_group_list.begin(), handle_group_list.end()); - } - - /** - * Const version - */ - std::pair 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 handles(Handle_group handle_group) - { - return std::make_pair(handle_group->begin(), handle_group->end()); - } - - /** - * Const version - */ - std::pair 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 - void translate(Const_handle_group handle_group, const Vect& t) + template + 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 - void rotate(Const_handle_group handle_group, const Point& rotation_center, const Quaternion& quat, const Vect& t) + template + 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(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]); diff --git a/Surface_modeling/test/Surface_modeling/Cactus_deformation_session.cpp b/Surface_modeling/test/Surface_modeling/Cactus_deformation_session.cpp index 8c54c2ad674..a91f1b8cc2c 100644 --- a/Surface_modeling/test/Surface_modeling/Cactus_deformation_session.cpp +++ b/Surface_modeling/test/Surface_modeling/Cactus_deformation_session.cpp @@ -23,7 +23,7 @@ typedef CGAL::Deform_mesh squared_threshold); } // read deformation session saved as a handle differences -template -bool read_handle_difs_and_deform(DeformMesh& deform_mesh, typename DeformMesh::Handle_group& active_handle_group) +template +void read_handle_difs_and_deform(DeformMesh& deform_mesh, InputIterator begin, InputIterator end) { typedef CGAL::Simple_cartesian::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 active_handle_group_1 = + std::vector 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 active_handle_group_2 = + std::vector 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; } diff --git a/Surface_modeling/test/Surface_modeling/Cactus_performance_test.cpp b/Surface_modeling/test/Surface_modeling/Cactus_performance_test.cpp index ac275e1a3be..c0a29002ab4 100644 --- a/Surface_modeling/test/Surface_modeling/Cactus_performance_test.cpp +++ b/Surface_modeling/test/Surface_modeling/Cactus_performance_test.cpp @@ -32,36 +32,10 @@ typedef CGAL::Deform_mesh Deform_mesh_spoke; - -template -bool preprocess_and_deform(DeformMesh& deform_mesh, int deformation_iteration) -{ - boost::optional 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::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::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::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; diff --git a/Surface_modeling/test/Surface_modeling/Surface_modeling_test_commons.h b/Surface_modeling/test/Surface_modeling/Surface_modeling_test_commons.h index 0a601752873..91d44274654 100644 --- a/Surface_modeling/test/Surface_modeling/Surface_modeling_test_commons.h +++ b/Surface_modeling/test/Surface_modeling/Surface_modeling_test_commons.h @@ -27,15 +27,14 @@ public: }; template -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 @@ -57,7 +56,7 @@ void init_indices(Polyhedron& poly) { } template -boost::optional +std::vector 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(); + assert(false); } - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::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 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 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 -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::Vector_3 translate, int deformation_iteration) { - boost::optional active_handle_group = + std::vector 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; } diff --git a/Surface_modeling/test/Surface_modeling/Symmetry_test.cpp b/Surface_modeling/test/Surface_modeling/Symmetry_test.cpp index 62d52a84fff..d8336a3cce9 100644 --- a/Surface_modeling/test/Surface_modeling/Symmetry_test.cpp +++ b/Surface_modeling/test/Surface_modeling/Symmetry_test.cpp @@ -25,7 +25,7 @@ typedef CGAL::Deform_mesh::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::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;