diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 876cacc160d..61df7bdab00 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -234,7 +234,7 @@ Scene_polygon_soup_item::compile_shaders(void) "void main(void) \n" "{ \n" - " fColors = vec3(0,0,0); \n//color[0], color[1], color[2]); \n" + " fColors = vec3(color); \n" " gl_Position = mvp_matrix * positions_lines; \n" "} \n" }; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 8a104dd5966..2abbcd975d0 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -1,2 +1,459 @@ #include "Scene_polyhedron_selection_item.h" #include "Scene_polyhedron_selection_item.moc" +struct light_info +{ + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; + GLfloat spec_power; + +}; + +void Scene_polyhedron_selection_item::initialize_buffers() +{ + glBindVertexArray(vao[0]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_facets.size())*sizeof(float), + positions_facets.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(0, //number of the buffer + 3, //number of floats to be taken + GL_FLOAT, // type of data + GL_FALSE, //not normalized + 0, //compact data (not in a struct) + NULL //no offset (seperated in several buffers) + ); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + glBufferData(GL_ARRAY_BUFFER, + (normals.size())*sizeof(float), + normals.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(1, //number of the buffer + 3, //number of floats to be taken + GL_FLOAT, // type of data + GL_FALSE, //not normalized + 0, //compact data (not in a struct) + NULL //no offset (seperated in several buffers) + ); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); + glBufferData(GL_ARRAY_BUFFER, + (positions_lines.size())*sizeof(float), + positions_lines.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(2, //number of the buffer + 3, //number of floats to be taken + GL_FLOAT, // type of data + GL_FALSE, //not normalized + 0, //compact data (not in a struct) + NULL //no offset (seperated in several buffers) + ); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glBufferData(GL_ARRAY_BUFFER, + (positions_points.size())*sizeof(float), + positions_points.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(3, //number of the buffer + 3, //number of floats to be taken + GL_FLOAT, // type of data + GL_FALSE, //not normalized + 0, //compact data (not in a struct) + NULL //no offset (seperated in several buffers) + ); + glEnableVertexAttribArray(3); + + glBindVertexArray(0); + +} +void Scene_polyhedron_selection_item::compile_shaders() +{ + //The facets + //fill the vertex shader + static const GLchar* vertex_shader_source_facets[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec3 positions; \n" + "layout (location = 1) in vec3 vNormals; \n" + "uniform mat4 mvp_matrix; \n" + "uniform mat4 mv_matrix; \n" + + "uniform int is_two_side; \n" + "uniform vec3 light_pos; \n" + "uniform vec3 light_diff; \n" + "uniform vec3 light_spec; \n" + "uniform vec3 light_amb; \n" + "float spec_power = 128.0; \n" + "vec4 positions_facets = vec4(positions, 1.0); \n" + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + "vec4 P = mv_matrix * positions_facets; \n" + "vec3 N = mat3(mv_matrix)* vNormals; \n" + "vec3 L = light_pos - P.xyz; \n" + "vec3 V = -P.xyz; \n" + + "N = normalize(N); \n" + "L = normalize(L); \n" + "V = normalize(V); \n" + + "vec3 R = reflect(-L, N); \n" + " vec3 diffuse; \n" + "if(is_two_side == 1) \n" + " diffuse = abs(dot(N,L)) * light_diff; \n" + "else \n" + " diffuse = max(dot(N,L), 0.0) * light_diff; \n" + "vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" + + "fColors = light_amb + diffuse + specular ; \n" + "gl_Position = mvp_matrix * positions_facets; \n" + "} \n" + }; + + //fill the fragment shader + static const GLchar* fragment_shader_source[]= + { + "#version 300 es \n" + " \n" + "in highp vec3 fColors; \n" + + "out highp vec3 color; \n" + " \n" + "void main(void) \n" + "{ \n" + " color = fColors; \n" + "} \n" + }; + + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source_facets, NULL); + glCompileShader(vertex_shader); + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); + glCompileShader(fragment_shader); + + GLuint program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + glDeleteShader(vertex_shader); + rendering_program_facets = program; + + //The lines + //fill the vertex shader + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 2) in vec3 positions; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform vec3 color; \n" + "out highp vec3 fColors; \n" + "vec4 positions_lines = vec4(positions, 1.0); \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color; \n" + " gl_Position = mvp_matrix * positions_lines; \n" + "} \n" + }; + + + + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source_lines, NULL); + glCompileShader(vertex_shader); + glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); + glCompileShader(fragment_shader); + + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + glDeleteShader(vertex_shader); + rendering_program_lines = program; + + //The points + //fill the vertex shader + static const GLchar* vertex_shader_source_points[] = + { + "#version 300 es \n" + " \n" + "layout (location = 3) in vec3 positions; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform vec3 color; \n" + "out highp vec3 fColors; \n" + "vec4 positions_points = vec4(positions, 1.0); \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color; \n" + " gl_Position = mvp_matrix * positions_points; \n" + "} \n" + }; + + + + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source_points, NULL); + glCompileShader(vertex_shader); + glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); + glCompileShader(fragment_shader); + + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + glDeleteShader(vertex_shader); + rendering_program_points = program; + + + glDeleteShader(fragment_shader); + +} +void Scene_polyhedron_selection_item::uniform_attrib(Viewer_interface* viewer, int mode) const +{ + GLfloat colors[3]; + light_info light; + GLint is_both_sides = 0; + GLfloat mvp_mat[16]; + GLfloat mv_mat[16]; + + //fills the MVP and MV matrices. + + GLdouble d_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mat); + //Convert the GLdoubles matrices in GLfloats + for (int i=0; i<16; ++i) + mvp_mat[i] = GLfloat(d_mat[i]); + + viewer->camera()->getModelViewMatrix(d_mat); + for (int i=0; i<16; ++i) + mv_mat[i] = GLfloat(d_mat[i]); + + + glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); + + //fills the arraw of colors with the current color + colors[0] = facet_color.redF(); + colors[1] = facet_color.greenF(); + colors[2] = facet_color.blueF(); + //Gets lighting info : + + //position + glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); + + //ambient + glGetLightfv(GL_LIGHT0, GL_AMBIENT, light.ambient); + light.ambient[0]*=colors[0]; + light.ambient[1]*=colors[1]; + light.ambient[2]*=colors[2]; + + //specular + glGetLightfv(GL_LIGHT0, GL_SPECULAR, light.specular); + + //diffuse + glGetLightfv(GL_LIGHT0, GL_DIFFUSE, light.diffuse); + + light.diffuse[0]*=colors[0]; + light.diffuse[1]*=colors[1]; + light.diffuse[2]*=colors[2]; + + //For the Flat mode + if(mode ==0) + { + glUseProgram(rendering_program_facets); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[1], 1, GL_FALSE, mv_mat); + glUniform3fv(location[2], 1, light.position); + glUniform3fv(location[3], 1, light.diffuse); + glUniform3fv(location[4], 1, light.specular); + glUniform3fv(location[5], 1, light.ambient); + glUniform1i(location[6], is_both_sides); + + + } + //For the Wire mode + else if(mode ==1) + { + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[7], 1, GL_FALSE, mvp_mat); + colors[0] = edge_color.redF(); + colors[1] = edge_color.greenF(); + colors[2] = edge_color.blueF(); + glUniform3fv(location[8],1,colors); + } + //For the points mode + else if(mode ==2) + { + glUseProgram(rendering_program_points); + glUniformMatrix4fv(location[9], 1, GL_FALSE, mvp_mat); + colors[0] = vertex_color.redF(); + colors[1] = vertex_color.greenF(); + colors[2] = vertex_color.blueF(); + glUniform3fv(location[10],1,colors); + } +} +void Scene_polyhedron_selection_item::compute_elements() +{ + positions_facets.clear(); + positions_lines.clear(); + positions_points.clear(); + normals.clear(); + //The facets + { + + + for(Selection_set_facet::iterator + it = selected_facets.begin(), + end = selected_facets.end(); + it != end; ++it) + { + const Kernel::Vector_3 n = + compute_facet_normal(**it); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + + Polyhedron::Halfedge_around_facet_circulator + he = (*it)->facet_begin(), + cend = he; + + CGAL_For_all(he,cend) + { + const Kernel::Point_3& p = he->vertex()->point(); + positions_facets.push_back(p.x()); + positions_facets.push_back(p.y()); + positions_facets.push_back(p.z()); + } + } + } + + //The Lines + { + + for(Selection_set_edge::iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) { + const Kernel::Point_3& a = (it->halfedge())->vertex()->point(); + const Kernel::Point_3& b = (it->halfedge())->opposite()->vertex()->point(); + positions_lines.push_back(a.x()); + positions_lines.push_back(a.y()); + positions_lines.push_back(a.z()); + + positions_lines.push_back(b.x()); + positions_lines.push_back(b.y()); + positions_lines.push_back(b.z()); + } + + } + + //The points + { + for(Selection_set_vertex::iterator + it = selected_vertices.begin(), + end = selected_vertices.end(); + it != end; ++it) + { + const Kernel::Point_3& p = (*it)->point(); + positions_points.push_back(p.x()); + positions_points.push_back(p.y()); + positions_points.push_back(p.z()); + } + } + + location[0] = glGetUniformLocation(rendering_program_facets, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_facets, "mv_matrix"); + location[2] = glGetUniformLocation(rendering_program_facets, "light_pos"); + location[3] = glGetUniformLocation(rendering_program_facets, "light_diff"); + location[4] = glGetUniformLocation(rendering_program_facets, "light_spec"); + location[5] = glGetUniformLocation(rendering_program_facets, "light_amb"); + location[6] = glGetUniformLocation(rendering_program_facets, "is_two_side"); + + location[7] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[8] = glGetUniformLocation(rendering_program_lines, "color"); + + location[9] = glGetUniformLocation(rendering_program_points, "mvp_matrix"); + location[10] = glGetUniformLocation(rendering_program_points, "color"); +} + +void Scene_polyhedron_selection_item::draw(Viewer_interface* viewer) const +{ + draw(); + + draw_points(viewer); + GLfloat offset_factor; + GLfloat offset_units; + glGetFloatv( GL_POLYGON_OFFSET_FACTOR, &offset_factor); + glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); + glPolygonOffset(-1.f, 1.f); + glBindVertexArray(vao[0]); + uniform_attrib(viewer,0); + glUseProgram(rendering_program_facets); + glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/3); + glUseProgram(0); + glBindVertexArray(0); + glPolygonOffset(offset_factor, offset_units); + draw_edges(viewer); + + +} + +void Scene_polyhedron_selection_item::draw_edges(Viewer_interface* viewer) const +{ + + glLineWidth(3.f); + glBindVertexArray(vao[0]); + uniform_attrib(viewer,1); + glUseProgram(rendering_program_lines); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); + glLineWidth(1.f); +} + +void Scene_polyhedron_selection_item::draw_points(Viewer_interface* viewer) const +{ + std::cout<<"draw_points"< struct Selection_traits { - typedef typename SelectionItem::Selection_set_vertex Container; - typedef boost::graph_traits::vertex_iterator Iterator; - Selection_traits(SelectionItem* item) : item(item) { } + typedef typename SelectionItem::Selection_set_vertex Container; + typedef boost::graph_traits::vertex_iterator Iterator; + Selection_traits(SelectionItem* item) : item(item) { } - Container& container() { return item->selected_vertices; } - Iterator iterator_begin() { return vertices(*item->polyhedron()).first; } - Iterator iterator_end() { return vertices(*item->polyhedron()).second; } - std::size_t size() { return item->polyhedron()->size_of_vertices(); } - void update_indices() { item->polyhedron_item()->update_vertex_indices(); } - std::size_t id(typename SelectionItem::Vertex_handle vh) {return vh->id();} + Container& container() { return item->selected_vertices; } + Iterator iterator_begin() { return vertices(*item->polyhedron()).first; } + Iterator iterator_end() { return vertices(*item->polyhedron()).second; } + std::size_t size() { return item->polyhedron()->size_of_vertices(); } + void update_indices() { item->polyhedron_item()->update_vertex_indices(); } + std::size_t id(typename SelectionItem::Vertex_handle vh) {return vh->id();} - template - static - OutputIterator - erode_selection( - const VertexRange& selection, - HalfedgeGraph& graph, - unsigned int k, - IsVertexSelectedPMap is_selected, - OutputIterator out) - { - return erode_vertex_selection(selection, graph, k, is_selected, out); - } - template - static - OutputIterator - dilate_selection( - const VertexRange& selection, - HalfedgeGraph& graph, - unsigned int k, - IsVertexSelectedPMap is_selected, - OutputIterator out) - { - return dilate_vertex_selection(selection, graph, k, is_selected, out); - } + template + static + OutputIterator + erode_selection( + const VertexRange& selection, + HalfedgeGraph& graph, + unsigned int k, + IsVertexSelectedPMap is_selected, + OutputIterator out) + { + return erode_vertex_selection(selection, graph, k, is_selected, out); + } + template + static + OutputIterator + dilate_selection( + const VertexRange& selection, + HalfedgeGraph& graph, + unsigned int k, + IsVertexSelectedPMap is_selected, + OutputIterator out) + { + return dilate_vertex_selection(selection, graph, k, is_selected, out); + } - SelectionItem* item; + SelectionItem* item; }; template struct Selection_traits { - typedef typename SelectionItem::Selection_set_facet Container; - typedef boost::graph_traits::face_iterator Iterator; - Selection_traits(SelectionItem* item) : item(item) { } + typedef typename SelectionItem::Selection_set_facet Container; + typedef boost::graph_traits::face_iterator Iterator; + Selection_traits(SelectionItem* item) : item(item) { } - Container& container() { return item->selected_facets; } - Iterator iterator_begin() { return faces(*item->polyhedron()).first; } - Iterator iterator_end() { return faces(*item->polyhedron()).second; } - std::size_t size() { return item->polyhedron()->size_of_facets(); } - void update_indices() { item->polyhedron_item()->update_facet_indices(); } - std::size_t id(typename SelectionItem::Facet_handle fh) {return fh->id();} + Container& container() { return item->selected_facets; } + Iterator iterator_begin() { return faces(*item->polyhedron()).first; } + Iterator iterator_end() { return faces(*item->polyhedron()).second; } + std::size_t size() { return item->polyhedron()->size_of_facets(); } + void update_indices() { item->polyhedron_item()->update_facet_indices(); } + std::size_t id(typename SelectionItem::Facet_handle fh) {return fh->id();} - template - static - OutputIterator - erode_selection( - const FaceRange& selection, - HalfedgeGraph& graph, - unsigned int k, - IsFaceSelectedPMap is_selected, - OutputIterator out) - { - return erode_face_selection(selection, graph, k, is_selected, out); - } - template - static - OutputIterator - dilate_selection( - const FaceRange& selection, - HalfedgeGraph& graph, - unsigned int k, - IsFaceSelectedPMap is_selected, - OutputIterator out) - { - return dilate_face_selection(selection, graph, k, is_selected, out); - } + template + static + OutputIterator + erode_selection( + const FaceRange& selection, + HalfedgeGraph& graph, + unsigned int k, + IsFaceSelectedPMap is_selected, + OutputIterator out) + { + return erode_face_selection(selection, graph, k, is_selected, out); + } + template + static + OutputIterator + dilate_selection( + const FaceRange& selection, + HalfedgeGraph& graph, + unsigned int k, + IsFaceSelectedPMap is_selected, + OutputIterator out) + { + return dilate_face_selection(selection, graph, k, is_selected, out); + } - SelectionItem* item; + SelectionItem* item; }; template struct Selection_traits { - typedef typename SelectionItem::Selection_set_edge Container; - typedef boost::graph_traits::edge_iterator Iterator; - Selection_traits(SelectionItem* item) : item(item) { } + typedef typename SelectionItem::Selection_set_edge Container; + typedef boost::graph_traits::edge_iterator Iterator; + Selection_traits(SelectionItem* item) : item(item) { } - Container& container() { return item->selected_edges; } - Iterator iterator_begin() { return edges(*item->polyhedron()).first; } - Iterator iterator_end() { return edges(*item->polyhedron()).second; } - std::size_t size() { return item->polyhedron()->size_of_halfedges()/2; } - void update_indices() { item->polyhedron_item()->update_halfedge_indices(); } - std::size_t id(boost::graph_traits::edge_descriptor ed) {return ed.halfedge()->id()/2;} + Container& container() { return item->selected_edges; } + Iterator iterator_begin() { return edges(*item->polyhedron()).first; } + Iterator iterator_end() { return edges(*item->polyhedron()).second; } + std::size_t size() { return item->polyhedron()->size_of_halfedges()/2; } + void update_indices() { item->polyhedron_item()->update_halfedge_indices(); } + std::size_t id(boost::graph_traits::edge_descriptor ed) {return ed.halfedge()->id()/2;} - template - static - OutputIterator - erode_selection( - const EdgeRange& selection, - HalfedgeGraph& graph, - unsigned int k, - IsEdgeSelectedPMap is_selected, - OutputIterator out) - { - return erode_edge_selection(selection, graph, k, is_selected, out); - } - template - static - OutputIterator - dilate_selection( - const EdgeRange& selection, - HalfedgeGraph& graph, - unsigned int k, - IsEdgeSelectedPMap is_selected, - OutputIterator out) - { - return dilate_edge_selection(selection, graph, k, is_selected, out); - } + template + static + OutputIterator + erode_selection( + const EdgeRange& selection, + HalfedgeGraph& graph, + unsigned int k, + IsEdgeSelectedPMap is_selected, + OutputIterator out) + { + return erode_edge_selection(selection, graph, k, is_selected, out); + } + template + static + OutputIterator + dilate_selection( + const EdgeRange& selection, + HalfedgeGraph& graph, + unsigned int k, + IsEdgeSelectedPMap is_selected, + OutputIterator out) + { + return dilate_edge_selection(selection, graph, k, is_selected, out); + } - SelectionItem* item; + SelectionItem* item; }; ////////////////////////////////////////////////////////////////////////// class SCENE_POLYHEDRON_SELECTION_ITEM_EXPORT Scene_polyhedron_selection_item - : public Scene_polyhedron_item_decorator + : public Scene_polyhedron_item_decorator { - Q_OBJECT + Q_OBJECT -friend class Polyhedron_demo_selection_plugin; + friend class Polyhedron_demo_selection_plugin; public: - typedef Polyhedron::Vertex_handle Vertex_handle; - typedef Polyhedron::Facet_handle Facet_handle; - typedef boost::graph_traits::edge_descriptor edge_descriptor; - typedef Polyhedron::Vertex_iterator Vertex_iterator; - typedef Polyhedron::Facet_iterator Facet_iterator; - typedef Scene_polyhedron_item_k_ring_selection::Active_handle Active_handle; - // To be used inside loader - Scene_polyhedron_selection_item() - : Scene_polyhedron_item_decorator(NULL, false) - { } + typedef Polyhedron::Vertex_handle Vertex_handle; + typedef Polyhedron::Facet_handle Facet_handle; + typedef boost::graph_traits::edge_descriptor edge_descriptor; + typedef Polyhedron::Vertex_iterator Vertex_iterator; + typedef Polyhedron::Facet_iterator Facet_iterator; + typedef Scene_polyhedron_item_k_ring_selection::Active_handle Active_handle; + // To be used inside loader + Scene_polyhedron_selection_item() + : Scene_polyhedron_item_decorator(NULL, false) + { } - Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw) - : Scene_polyhedron_item_decorator(NULL, false) - { init(poly_item, mw); } + Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw) + : Scene_polyhedron_item_decorator(NULL, false) + { init(poly_item, mw); + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(4, buffer); + compile_shaders(); + changed(); + } + + ~Scene_polyhedron_selection_item() + { + glDeleteBuffers(4, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_facets); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_points); + } protected: - void init(Scene_polyhedron_item* poly_item, QMainWindow* mw) - { - this->poly_item = poly_item; - connect(poly_item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed())); - connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, - SLOT(selected(const std::set&))); - connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, - SLOT(selected(const std::set&))); - connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, - SLOT(selected(const std::set&))); + void init(Scene_polyhedron_item* poly_item, QMainWindow* mw) + { + this->poly_item = poly_item; + connect(poly_item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed())); + connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, + SLOT(selected(const std::set&))); + connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, + SLOT(selected(const std::set&))); + connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, + SLOT(selected(const std::set&))); - k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1); + k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - viewer->installEventFilter(this); - mw->installEventFilter(this); + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->installEventFilter(this); + mw->installEventFilter(this); - facet_color = QColor(87,87,87); - edge_color = QColor(173,35,35); - vertex_color = QColor(255,205,243); - } + facet_color = QColor(87,87,87); + edge_color = QColor(173,35,35); + vertex_color = QColor(255,205,243); + } - Active_handle::Type get_active_handle_type() - { return k_ring_selector.active_handle_type; } - void set_active_handle_type(Active_handle::Type aht) - { k_ring_selector.active_handle_type = aht; } + Active_handle::Type get_active_handle_type() + { return k_ring_selector.active_handle_type; } + void set_active_handle_type(Active_handle::Type aht) + { k_ring_selector.active_handle_type = aht; } - int get_k_ring() { return k_ring_selector.k_ring; } - void set_k_ring(int k) { k_ring_selector.k_ring = k; } + int get_k_ring() { return k_ring_selector.k_ring; } + void set_k_ring(int k) { k_ring_selector.k_ring = k; } + + bool get_is_insert() { return is_insert; } + void set_is_insert(bool i) { is_insert = i; } - bool get_is_insert() { return is_insert; } - void set_is_insert(bool i) { is_insert = i; } - public: - typedef boost::unordered_set Selection_set_vertex; - typedef boost::unordered_set Selection_set_facet; - typedef boost::unordered_set Selection_set_edge; + typedef boost::unordered_set Selection_set_vertex; + typedef boost::unordered_set Selection_set_facet; + typedef boost::unordered_set Selection_set_edge; -// drawing - void draw() const { - draw_selected_vertices(); - draw_selected_facets(); - draw_selected_edges(); - } - void draw_edges() const { } + // drawing + void draw() const { + draw_selected_vertices(); + draw_selected_facets(); + draw_selected_edges(); + } + virtual void draw(Viewer_interface*) const; + virtual void draw_edges() const { } + virtual void draw_edges(Viewer_interface*) const; + virtual void draw_points(Viewer_interface*) const; + void draw_selected_vertices() const { + GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); + glDisable(GL_LIGHTING); - void draw_selected_vertices() const { - GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); - glDisable(GL_LIGHTING); - - CGAL::GL::Point_size point_size; point_size.set_point_size(5); - CGALglcolor(vertex_color); + CGAL::GL::Point_size point_size; point_size.set_point_size(5); + CGALglcolor(vertex_color); - ::glBegin(GL_POINTS); - for(Selection_set_vertex::iterator - it = selected_vertices.begin(), - end = selected_vertices.end(); - it != end; ++it) + ::glBegin(GL_POINTS); + for(Selection_set_vertex::iterator + it = selected_vertices.begin(), + end = selected_vertices.end(); + it != end; ++it) + { + const Kernel::Point_3& p = (*it)->point(); + ::glVertex3d(p.x(), p.y(), p.z()); + } + ::glEnd(); + + if(enable_back_lighting) { glEnable(GL_LIGHTING); } + } + void draw_selected_facets() const { + CGALglcolor(facet_color); + + GLfloat offset_factor; + GLfloat offset_units; + ::glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &offset_factor); + ::glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); + + ::glPolygonOffset(-1.f, 1.f); + ::glBegin(GL_TRIANGLES); + for(Selection_set_facet::iterator + it = selected_facets.begin(), + end = selected_facets.end(); + it != end; ++it) + { + const Kernel::Vector_3 n = + compute_facet_normal(**it); + ::glNormal3d(n.x(),n.y(),n.z()); + + Polyhedron::Halfedge_around_facet_circulator + he = (*it)->facet_begin(), + cend = he; + + CGAL_For_all(he,cend) + { + const Kernel::Point_3& p = he->vertex()->point(); + ::glVertex3d(p.x(),p.y(),p.z()); + } + } + ::glEnd(); + ::glPolygonOffset(offset_factor, offset_units); + } + void draw_selected_edges() const { + GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); + glDisable(GL_LIGHTING); + + CGALglcolor(edge_color); + ::glLineWidth(3.f); + ::glBegin(GL_LINES); + for(Selection_set_edge::iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) { + const Kernel::Point_3& a = (it->halfedge())->vertex()->point(); + const Kernel::Point_3& b = (it->halfedge())->opposite()->vertex()->point(); + ::glVertex3d(a.x(),a.y(),a.z()); + ::glVertex3d(b.x(),b.y(),b.z()); + } + ::glEnd(); + + if(enable_back_lighting) { glEnable(GL_LIGHTING); } + } + + bool supportsRenderingMode(RenderingMode m) const { return (m==Flat); } + + bool isEmpty() const { + return selected_vertices.empty() && selected_edges.empty() && selected_facets.empty(); + } + Bbox bbox() const { - const Kernel::Point_3& p = (*it)->point(); - ::glVertex3d(p.x(), p.y(), p.z()); + // Workaround a bug in g++-4.8.3: + // http://stackoverflow.com/a/21755207/1728537 + // Using boost::make_optional to copy-initialize 'item_bbox' hides the + // warning about '*item_bbox' not being initialized. + // -- Laurent Rineau, 2014/10/30 + boost::optional item_bbox + = boost::make_optional(false, CGAL::Bbox_3()); + + for(Selection_set_vertex::const_iterator v_it = selected_vertices.begin(); + v_it != selected_vertices.end(); ++v_it) { + + if(item_bbox) { *item_bbox = *item_bbox + (*v_it)->point().bbox(); } + else { item_bbox = (*v_it)->point().bbox(); } + } + + for(Selection_set_edge::const_iterator e_it = selected_edges.begin(); + e_it != selected_edges.end(); ++e_it) { + CGAL::Bbox_3 e_bbox = e_it->halfedge()->vertex()->point().bbox(); + e_bbox = e_bbox + e_it->halfedge()->opposite()->vertex()->point().bbox(); + if(item_bbox) { *item_bbox = *item_bbox + e_bbox; } + else { item_bbox = e_bbox; } + } + + for(Selection_set_facet::const_iterator f_it = selected_facets.begin(); + f_it != selected_facets.end(); ++f_it) { + + Polyhedron::Halfedge_around_facet_circulator he = (*f_it)->facet_begin(), cend = he; + CGAL_For_all(he,cend) { + if(item_bbox) { *item_bbox = *item_bbox + he->vertex()->point().bbox(); } + else { item_bbox = he->vertex()->point().bbox(); } + } + } + + if(!item_bbox) { return Bbox(); } + return Bbox(item_bbox->xmin(),item_bbox->ymin(),item_bbox->zmin(), + item_bbox->xmax(),item_bbox->ymax(),item_bbox->zmax()); } - ::glEnd(); - if(enable_back_lighting) { glEnable(GL_LIGHTING); } - } - void draw_selected_facets() const { - CGALglcolor(facet_color); + bool save(const std::string& file_name) const { + // update id fields before using + if(selected_vertices.size() > 0) { poly_item->update_vertex_indices(); } + if(selected_facets.size() > 0) { poly_item->update_facet_indices(); } + if(selected_edges.size() > 0) { poly_item->update_halfedge_indices(); } - GLfloat offset_factor; - GLfloat offset_units; - ::glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &offset_factor); - ::glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); + std::ofstream out(file_name.c_str()); + if(!out) { return false; } - ::glPolygonOffset(-1.f, 1.f); - ::glBegin(GL_TRIANGLES); - for(Selection_set_facet::iterator - it = selected_facets.begin(), - end = selected_facets.end(); - it != end; ++it) + for(Selection_set_vertex::const_iterator it = selected_vertices.begin(); it != selected_vertices.end(); ++it) + { out << (*it)->id() << " "; } + out << std::endl; + + for(Selection_set_facet::const_iterator it = selected_facets.begin(); it != selected_facets.end(); ++it) + { out << (*it)->id() << " "; } + out << std::endl; + + for(Selection_set_edge::const_iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) + { out << it->id() << " "; } + out << std::endl; + return true; + } + bool load(const std::string& file_name) { + file_name_holder = file_name; + return true; + } + // this function is called by selection_plugin, since at the time of the call of load(...) + // we do not have access to selected polyhedron item + bool actual_load(Scene_polyhedron_item* poly_item, QMainWindow* mw) { - const Kernel::Vector_3 n = - compute_facet_normal(**it); - ::glNormal3d(n.x(),n.y(),n.z()); + init(poly_item, mw); - Polyhedron::Halfedge_around_facet_circulator - he = (*it)->facet_begin(), - cend = he; + std::vector all_vertices; + all_vertices.reserve(polyhedron()->size_of_vertices()); + Polyhedron::Vertex_iterator vb(polyhedron()->vertices_begin()), ve(polyhedron()->vertices_end()); + for(;vb != ve; ++vb) { all_vertices.push_back(vb); } - CGAL_For_all(he,cend) - { - const Kernel::Point_3& p = he->vertex()->point(); - ::glVertex3d(p.x(),p.y(),p.z()); - } - } - ::glEnd(); - ::glPolygonOffset(offset_factor, offset_units); - } - void draw_selected_edges() const { - GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); - glDisable(GL_LIGHTING); + std::vector all_facets; + all_facets.reserve(polyhedron()->size_of_facets()); + Polyhedron::Facet_iterator fb(polyhedron()->facets_begin()), fe(polyhedron()->facets_end()); + for(;fb != fe; ++fb) { all_facets.push_back(fb); } - CGALglcolor(edge_color); - ::glLineWidth(3.f); - ::glBegin(GL_LINES); - for(Selection_set_edge::iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) { - const Kernel::Point_3& a = (it->halfedge())->vertex()->point(); - const Kernel::Point_3& b = (it->halfedge())->opposite()->vertex()->point(); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - } - ::glEnd(); + std::vector all_edges(edges(*polyhedron()).first, edges(*polyhedron()).second); - if(enable_back_lighting) { glEnable(GL_LIGHTING); } - } + std::ifstream in(file_name_holder.c_str()); + if(!in) { return false; } - bool supportsRenderingMode(RenderingMode m) const { return (m==Flat); } + std::string line; + std::size_t id; - bool isEmpty() const { - return selected_vertices.empty() && selected_edges.empty() && selected_facets.empty(); - } - Bbox bbox() const - { - // Workaround a bug in g++-4.8.3: - // http://stackoverflow.com/a/21755207/1728537 - // Using boost::make_optional to copy-initialize 'item_bbox' hides the - // warning about '*item_bbox' not being initialized. - // -- Laurent Rineau, 2014/10/30 - boost::optional item_bbox - = boost::make_optional(false, CGAL::Bbox_3()); + if(!std::getline(in, line)) { return true; } + std::istringstream vertex_line(line); + while(vertex_line >> id) { + if(id >= all_vertices.size()) { return false; } + selected_vertices.insert(all_vertices[id]); + } - for(Selection_set_vertex::const_iterator v_it = selected_vertices.begin(); - v_it != selected_vertices.end(); ++v_it) { + if(!std::getline(in, line)) { return true; } + std::istringstream facet_line(line); + while(facet_line >> id) { + if(id >= all_facets.size()) { return false; } + selected_facets.insert(all_facets[id]); + } - if(item_bbox) { *item_bbox = *item_bbox + (*v_it)->point().bbox(); } - else { item_bbox = (*v_it)->point().bbox(); } + if(!std::getline(in, line)) { return true; } + std::istringstream edge_line(line); + while(edge_line >> id) { + if(id >= all_edges.size()) { return false; } + selected_edges.insert(all_edges[id]); + } + return true; } - for(Selection_set_edge::const_iterator e_it = selected_edges.begin(); - e_it != selected_edges.end(); ++e_it) { - CGAL::Bbox_3 e_bbox = e_it->halfedge()->vertex()->point().bbox(); - e_bbox = e_bbox + e_it->halfedge()->opposite()->vertex()->point().bbox(); - if(item_bbox) { *item_bbox = *item_bbox + e_bbox; } - else { item_bbox = e_bbox; } + // select all of `active_handle_type`(vertex, facet or edge) + void select_all() { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + select_all(); break; + case Active_handle::FACET: + select_all(); break; + case Active_handle::EDGE: + selected_edges.insert(edges(*polyhedron()).first, edges(*polyhedron()).second); + } + } + // select all of vertex, facet or edge (use Vertex_handle, Facet_handle, edge_descriptor as template argument) + template + void select_all() { + typedef Selection_traits Tr; + Tr tr(this); + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + tr.container().insert(*it); + } + emit itemChanged(); } - for(Selection_set_facet::const_iterator f_it = selected_facets.begin(); - f_it != selected_facets.end(); ++f_it) { + // clear all of `active_handle_type`(vertex, facet or edge) + void clear() { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + clear(); break; + case Active_handle::FACET: + clear(); break; + case Active_handle::EDGE: + clear(); break; + } + } + // select all of vertex, facet or edge (use Vertex_handle, Facet_handle, edge_descriptor as template argument) + template + void clear() { - Polyhedron::Halfedge_around_facet_circulator he = (*f_it)->facet_begin(), cend = he; - CGAL_For_all(he,cend) { - if(item_bbox) { *item_bbox = *item_bbox + he->vertex()->point().bbox(); } - else { item_bbox = he->vertex()->point().bbox(); } + Selection_traits tr(this); + tr.container().clear(); + emit itemChanged(); + } + + boost::optional get_minimum_isolated_component() { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + return get_minimum_isolated_component(); + case Active_handle::FACET: + return get_minimum_isolated_component(); + default: + return get_minimum_isolated_component(); + } + } + template // use Vertex_handle, Facet_handle, edge_descriptor + boost::optional get_minimum_isolated_component() { + Selection_traits tr(this); + tr.update_indices(); + Travel_isolated_components::Minimum_visitor visitor; + Travel_isolated_components().travel + (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); + return visitor.minimum; + } + + boost::optional select_isolated_components(std::size_t threshold) { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + return select_isolated_components(threshold); + case Active_handle::FACET: + return select_isolated_components(threshold); + default: + return select_isolated_components(threshold); + } + } + template // use Vertex_handle, Facet_handle, edge_descriptor + boost::optional select_isolated_components(std::size_t threshold) { + typedef Selection_traits Tr; + Tr tr(this); + tr.update_indices(); + typedef std::insert_iterator Output_iterator; + Output_iterator out(tr.container(), tr.container().begin()); + + Travel_isolated_components::Selection_visitor visitor(threshold , out); + Travel_isolated_components().travel + (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); + + if(visitor.any_inserted) { emit itemChanged(); } + return visitor.minimum_visitor.minimum; + } + + void dilate_or_erode(int steps) { + if (steps>0) + { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + dilate_selection(steps); + break; + case Active_handle::FACET: + dilate_selection(steps); + break; + default: + dilate_selection(steps); + } + } + else + { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + erode_selection(-steps); + break; + case Active_handle::FACET: + erode_selection(-steps); + break; + default: + erode_selection(-steps); + } } } - if(!item_bbox) { return Bbox(); } - return Bbox(item_bbox->xmin(),item_bbox->ymin(),item_bbox->zmin(), - item_bbox->xmax(),item_bbox->ymax(),item_bbox->zmax()); - } + template + struct Is_selected_property_map{ + std::vector& is_selected; + Is_selected_property_map(std::vector& is_selected) + : is_selected( is_selected) {} - bool save(const std::string& file_name) const { - // update id fields before using - if(selected_vertices.size() > 0) { poly_item->update_vertex_indices(); } - if(selected_facets.size() > 0) { poly_item->update_facet_indices(); } - if(selected_edges.size() > 0) { poly_item->update_halfedge_indices(); } + template + std::size_t id(H h){ return h->id(); } + std::size_t id(edge_descriptor ed) { return ed.halfedge()->id()/2; } - std::ofstream out(file_name.c_str()); - if(!out) { return false; } - - for(Selection_set_vertex::const_iterator it = selected_vertices.begin(); it != selected_vertices.end(); ++it) - { out << (*it)->id() << " "; } - out << std::endl; - - for(Selection_set_facet::const_iterator it = selected_facets.begin(); it != selected_facets.end(); ++it) - { out << (*it)->id() << " "; } - out << std::endl; - - for(Selection_set_edge::const_iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) - { out << it->id() << " "; } - out << std::endl; - return true; - } - bool load(const std::string& file_name) { - file_name_holder = file_name; - return true; - } - // this function is called by selection_plugin, since at the time of the call of load(...) - // we do not have access to selected polyhedron item - bool actual_load(Scene_polyhedron_item* poly_item, QMainWindow* mw) - { - init(poly_item, mw); - - std::vector all_vertices; - all_vertices.reserve(polyhedron()->size_of_vertices()); - Polyhedron::Vertex_iterator vb(polyhedron()->vertices_begin()), ve(polyhedron()->vertices_end()); - for(;vb != ve; ++vb) { all_vertices.push_back(vb); } - - std::vector all_facets; - all_facets.reserve(polyhedron()->size_of_facets()); - Polyhedron::Facet_iterator fb(polyhedron()->facets_begin()), fe(polyhedron()->facets_end()); - for(;fb != fe; ++fb) { all_facets.push_back(fb); } - - std::vector all_edges(edges(*polyhedron()).first, edges(*polyhedron()).second); - - std::ifstream in(file_name_holder.c_str()); - if(!in) { return false; } - - std::string line; - std::size_t id; - - if(!std::getline(in, line)) { return true; } - std::istringstream vertex_line(line); - while(vertex_line >> id) { - if(id >= all_vertices.size()) { return false; } - selected_vertices.insert(all_vertices[id]); - } - - if(!std::getline(in, line)) { return true; } - std::istringstream facet_line(line); - while(facet_line >> id) { - if(id >= all_facets.size()) { return false; } - selected_facets.insert(all_facets[id]); - } - - if(!std::getline(in, line)) { return true; } - std::istringstream edge_line(line); - while(edge_line >> id) { - if(id >= all_edges.size()) { return false; } - selected_edges.insert(all_edges[id]); - } - return true; - } - - // select all of `active_handle_type`(vertex, facet or edge) - void select_all() { - switch(get_active_handle_type()) { - case Active_handle::VERTEX: - select_all(); break; - case Active_handle::FACET: - select_all(); break; - case Active_handle::EDGE: - selected_edges.insert(edges(*polyhedron()).first, edges(*polyhedron()).second); - } - } - // select all of vertex, facet or edge (use Vertex_handle, Facet_handle, edge_descriptor as template argument) - template - void select_all() { - typedef Selection_traits Tr; - Tr tr(this); - for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { - tr.container().insert(*it); - } - emit itemChanged(); - } - - // clear all of `active_handle_type`(vertex, facet or edge) - void clear() { - switch(get_active_handle_type()) { - case Active_handle::VERTEX: - clear(); break; - case Active_handle::FACET: - clear(); break; - case Active_handle::EDGE: - clear(); break; - } - } - // select all of vertex, facet or edge (use Vertex_handle, Facet_handle, edge_descriptor as template argument) - template - void clear() { - - Selection_traits tr(this); - tr.container().clear(); - emit itemChanged(); - } - - boost::optional get_minimum_isolated_component() { - switch(get_active_handle_type()) { - case Active_handle::VERTEX: - return get_minimum_isolated_component(); - case Active_handle::FACET: - return get_minimum_isolated_component(); - default: - return get_minimum_isolated_component(); - } - } - template // use Vertex_handle, Facet_handle, edge_descriptor - boost::optional get_minimum_isolated_component() { - Selection_traits tr(this); - tr.update_indices(); - Travel_isolated_components::Minimum_visitor visitor; - Travel_isolated_components().travel - (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); - return visitor.minimum; - } - - boost::optional select_isolated_components(std::size_t threshold) { - switch(get_active_handle_type()) { - case Active_handle::VERTEX: - return select_isolated_components(threshold); - case Active_handle::FACET: - return select_isolated_components(threshold); - default: - return select_isolated_components(threshold); - } - } - template // use Vertex_handle, Facet_handle, edge_descriptor - boost::optional select_isolated_components(std::size_t threshold) { - typedef Selection_traits Tr; - Tr tr(this); - tr.update_indices(); - typedef std::insert_iterator Output_iterator; - Output_iterator out(tr.container(), tr.container().begin()); - - Travel_isolated_components::Selection_visitor visitor(threshold , out); - Travel_isolated_components().travel - (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); - - if(visitor.any_inserted) { emit itemChanged(); } - return visitor.minimum_visitor.minimum; - } - - void dilate_or_erode(int steps) { - if (steps>0) - { - switch(get_active_handle_type()) { - case Active_handle::VERTEX: - dilate_selection(steps); - break; - case Active_handle::FACET: - dilate_selection(steps); - break; - default: - dilate_selection(steps); - } - } - else - { - switch(get_active_handle_type()) { - case Active_handle::VERTEX: - erode_selection(-steps); - break; - case Active_handle::FACET: - erode_selection(-steps); - break; - default: - erode_selection(-steps); - } - } - } - - template - struct Is_selected_property_map{ - std::vector& is_selected; - Is_selected_property_map(std::vector& is_selected) - : is_selected( is_selected) {} - - template - std::size_t id(H h){ return h->id(); } - std::size_t id(edge_descriptor ed) { return ed.halfedge()->id()/2; } - - friend bool get(Is_selected_property_map map, Handle h) - { - return map.is_selected[map.id(h)]; - } - - friend void put(Is_selected_property_map map, Handle h, bool b) - { - map.is_selected[map.id(h)]=b; - } - }; - - template - void dilate_selection(unsigned int steps) { - - typedef Selection_traits Tr; - Tr tr(this); - - tr.update_indices(); - std::vector mark(tr.size(),false); - - BOOST_FOREACH(Handle h,tr.container()) - mark[tr.id(h)]=true; - - Tr::dilate_selection( - tr.container(), - *this->poly_item->polyhedron(), - steps, - Is_selected_property_map(mark), - CGAL::Emptyset_iterator() - ); - - bool any_change = false; - for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { - if(mark[tr.id(*it)]) { - any_change |= tr.container().insert(*it).second; - } - } - if(any_change) { emit itemChanged(); } - } - - template - void erode_selection(unsigned int steps) { - - typedef Selection_traits Tr; - Tr tr(this); - - tr.update_indices(); - std::vector mark(tr.size(),false); - - BOOST_FOREACH(Handle h,tr.container()) - mark[tr.id(h)]=true; - - Tr::erode_selection( - tr.container(), - *this->poly_item->polyhedron(), - steps, - Is_selected_property_map(mark), - CGAL::Emptyset_iterator() - ); - - bool any_change = false; - for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { - if(!mark[tr.id(*it)]) { - any_change |= (tr.container().erase(*it)!=0); - } - } - if(any_change) { emit itemChanged(); } - } - - void erase_selected_facets() { - if(selected_facets.empty()) {return;} - // no-longer-valid vertices and edges will be handled when item_about_to_be_changed() - - // erase facets from poly - for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { - polyhedron()->erase_facet((*fb)->halfedge()); - } - selected_facets.clear(); - changed_with_poly_item(); - } - - bool export_selected_facets_as_polyhedron(Polyhedron* out) { - // Note: might be a more performance wise solution - // assign sequential id to vertices neighbor to selected facets - for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { - Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); - do { - hb->vertex()->id() = 0; - } while(++hb != hend); - } - // construct point vector - std::vector points; - points.reserve(selected_facets.size()); - std::size_t counter = 1; - for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { - Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); - do { - if(hb->vertex()->id() == 0) { - hb->vertex()->id() = counter++; - points.push_back(hb->vertex()->point()); + friend bool get(Is_selected_property_map map, Handle h) + { + return map.is_selected[map.id(h)]; } - } while(++hb != hend); - } - // construct polygon vector - std::vector > polygons(selected_facets.size()); - counter = 0; - for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb, ++counter) { - Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); - do { - polygons[counter].push_back(hb->vertex()->id() -1); - } while(++hb != hend); - } - CGAL::polygon_soup_to_polyhedron_3(*out, points, polygons); - return out->size_of_vertices() > 0; - } - void changed_with_poly_item() { - // no need to update indices - poly_item->changed(); - emit itemChanged(); - } + friend void put(Is_selected_property_map map, Handle h, bool b) + { + map.is_selected[map.id(h)]=b; + } + }; + + template + void dilate_selection(unsigned int steps) { + + typedef Selection_traits Tr; + Tr tr(this); + + tr.update_indices(); + std::vector mark(tr.size(),false); + + BOOST_FOREACH(Handle h,tr.container()) + mark[tr.id(h)]=true; + + Tr::dilate_selection( + tr.container(), + *this->poly_item->polyhedron(), + steps, + Is_selected_property_map(mark), + CGAL::Emptyset_iterator() + ); + + bool any_change = false; + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + if(mark[tr.id(*it)]) { + any_change |= tr.container().insert(*it).second; + } + } + if(any_change) { emit itemChanged(); } + } + + template + void erode_selection(unsigned int steps) { + + typedef Selection_traits Tr; + Tr tr(this); + + tr.update_indices(); + std::vector mark(tr.size(),false); + + BOOST_FOREACH(Handle h,tr.container()) + mark[tr.id(h)]=true; + + Tr::erode_selection( + tr.container(), + *this->poly_item->polyhedron(), + steps, + Is_selected_property_map(mark), + CGAL::Emptyset_iterator() + ); + + bool any_change = false; + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + if(!mark[tr.id(*it)]) { + any_change |= (tr.container().erase(*it)!=0); + } + } + if(any_change) { emit itemChanged(); } + } + + void erase_selected_facets() { + if(selected_facets.empty()) {return;} + // no-longer-valid vertices and edges will be handled when item_about_to_be_changed() + + // erase facets from poly + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { + polyhedron()->erase_facet((*fb)->halfedge()); + } + selected_facets.clear(); + changed_with_poly_item(); + } + + bool export_selected_facets_as_polyhedron(Polyhedron* out) { + // Note: might be a more performance wise solution + // assign sequential id to vertices neighbor to selected facets + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { + Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); + do { + hb->vertex()->id() = 0; + } while(++hb != hend); + } + // construct point vector + std::vector points; + points.reserve(selected_facets.size()); + std::size_t counter = 1; + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { + Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); + do { + if(hb->vertex()->id() == 0) { + hb->vertex()->id() = counter++; + points.push_back(hb->vertex()->point()); + } + } while(++hb != hend); + } + // construct polygon vector + std::vector > polygons(selected_facets.size()); + counter = 0; + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb, ++counter) { + Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); + do { + polygons[counter].push_back(hb->vertex()->id() -1); + } while(++hb != hend); + } + CGAL::polygon_soup_to_polyhedron_3(*out, points, polygons); + return out->size_of_vertices() > 0; + } + + void changed_with_poly_item() { + // no need to update indices + poly_item->changed(); + emit itemChanged(); + } public slots: - void changed() { - // do not use decorator function, which calls changed on poly_item which cause deletion of AABB - } - // slots are called by signals of polyhedron_k_ring_selector - void selected(const std::set& m) - { has_been_selected(m); } - void selected(const std::set& m) - { has_been_selected(m); } - void selected(const std::set& m) - { has_been_selected(m); } - void poly_item_changed() { - remove_erased_handles(); - remove_erased_handles(); - remove_erased_handles(); - } + void changed() { + // do not use decorator function, which calls changed on poly_item which cause deletion of AABB + // poly_item->changed(); + compute_elements(); + initialize_buffers(); + } + // slots are called by signals of polyhedron_k_ring_selector + void selected(const std::set& m) + { has_been_selected(m); } + void selected(const std::set& m) + { has_been_selected(m); } + void selected(const std::set& m) + { has_been_selected(m); } + void poly_item_changed() { + remove_erased_handles(); + remove_erased_handles(); + remove_erased_handles(); + } protected: - bool eventFilter(QObject* /*target*/, QEvent * gen_event) - { - if(!visible() || !k_ring_selector.state.shift_pressing) { return false; } - if(gen_event->type() == QEvent::Wheel) + bool eventFilter(QObject* /*target*/, QEvent * gen_event) { - QWheelEvent *event = static_cast(gen_event); - int steps = event->delta() / 120; - dilate_or_erode(steps); - return true; + if(!visible() || !k_ring_selector.state.shift_pressing) { return false; } + if(gen_event->type() == QEvent::Wheel) + { + QWheelEvent *event = static_cast(gen_event); + int steps = event->delta() / 120; + dilate_or_erode(steps); + return true; + } + return false; } - return false; - } - template - void remove_erased_handles() { - typedef Selection_traits Tr; - Tr tr(this); - if(tr.container().empty()) { return;} + template + void remove_erased_handles() { + typedef Selection_traits Tr; + Tr tr(this); + if(tr.container().empty()) { return;} - std::vector exists; - for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { - if(tr.container().count(*it)) { - exists.push_back(*it); - } + std::vector exists; + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + if(tr.container().count(*it)) { + exists.push_back(*it); + } + } + tr.container().clear(); + for(typename std::vector::iterator it = exists.begin(); it != exists.end(); ++it) { + tr.container().insert(*it); + } } - tr.container().clear(); - for(typename std::vector::iterator it = exists.begin(); it != exists.end(); ++it) { - tr.container().insert(*it); - } - } - template - void has_been_selected(const std::set& selection) - { - if(!visible()) { return; } - Selection_traits tr(this); + template + void has_been_selected(const std::set& selection) + { + if(!visible()) { return; } + Selection_traits tr(this); - bool any_change = false; - if(is_insert) { - BOOST_FOREACH(HandleType h, selection) - any_change |= tr.container().insert(h).second; + bool any_change = false; + if(is_insert) { + BOOST_FOREACH(HandleType h, selection) + any_change |= tr.container().insert(h).second; + } + else{ + BOOST_FOREACH(HandleType h, selection) + any_change |= (tr.container().erase(h)!=0); + } + if(any_change) { emit itemChanged(); } } - else{ - BOOST_FOREACH(HandleType h, selection) - any_change |= (tr.container().erase(h)!=0); - } - if(any_change) { emit itemChanged(); } - } -// members - std::string file_name_holder; - Scene_polyhedron_item_k_ring_selection k_ring_selector; - // action state - bool is_insert; + // members + std::string file_name_holder; + Scene_polyhedron_item_k_ring_selection k_ring_selector; + // action state + bool is_insert; public: -// selection - Selection_set_vertex selected_vertices; - Selection_set_facet selected_facets; - Selection_set_edge selected_edges; // stores one halfedge for each pair (halfedge with minimum address) -// - QColor vertex_color, facet_color, edge_color; + // selection + Selection_set_vertex selected_vertices; + Selection_set_facet selected_facets; + Selection_set_edge selected_edges; // stores one halfedge for each pair (halfedge with minimum address) + // + QColor vertex_color, facet_color, edge_color; + +private: + + std::vector positions_facets; + std::vector normals; + std::vector positions_lines; + std::vector positions_points; + + + + GLint location[11]; + GLuint vao[1]; + GLuint buffer[4]; + GLuint rendering_program_facets; + GLuint rendering_program_lines; + GLuint rendering_program_points; + + void initialize_buffers(); + void compile_shaders(); + void uniform_attrib(Viewer_interface*, int) const; + void compute_elements(); + }; #endif diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp index 62138582d87..daac51c911c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp @@ -46,6 +46,7 @@ void Scene_polyhedron_transform_item::initialize_buffers() NULL //no offset (seperated in several buffers) ); glEnableVertexAttribArray(0); + glBindVertexArray(0); } void Scene_polyhedron_transform_item::compile_shaders() {