From 4a48cfb524e174fa11d5ec77cfee8835dfb8d14b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 9 Mar 2015 16:13:38 +0100 Subject: [PATCH] Update of polyline_item. Polylines now use shaders, and spheres are made without gluSphere. The displayList has been replaced bay an Instanced drawing of the shperes with the function DrawArraysInstanced. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 1 + .../demo/Polyhedron/Scene_polyhedron_item.cpp | 10 +- .../demo/Polyhedron/Scene_polyhedron_item.h | 2 +- .../demo/Polyhedron/Scene_polylines_item.cpp | 1451 +++++++++++++---- .../demo/Polyhedron/Scene_polylines_item.h | 144 +- 5 files changed, 1205 insertions(+), 403 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 99e8233d021..086c5106b15 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -889,3 +889,4 @@ Scene_polygon_soup_item::new_triangle(const std::size_t i, // Local Variables: // c-basic-offset: 4 // End: + diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 663ddc295db..7349d340206 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -780,13 +780,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) positions_lines.push_back(b.z()); positions_lines.push_back(1.0); - /* color_lines.push_back(1.0); - color_lines.push_back(0.0); - color_lines.push_back(0.0); - color_lines.push_back(1.0); - color_lines.push_back(0.0); - color_lines.push_back(0.0);*/ } @@ -1124,7 +1118,7 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { glBindVertexArray(vao[0]); // tells the GPU to use the program just created - // glUseProgram(rendering_program_facets); + glUseProgram(rendering_program_facets); uniform_attrib(viewer,0); //draw the polygons // the third argument is the number of vec4 that will be entered @@ -1162,7 +1156,7 @@ Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { uniform_attrib(viewer,1); //draw the points - glDrawArrays(GL_POINTS, 0, positions_facets.size()); + glDrawArrays(GL_POINTS, 0, positions_facets.size()/4); // Clean-up glBindVertexArray(0); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 5ff631c6c2a..33f6f6e903d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -117,7 +117,7 @@ private: GLint location[9]; GLuint vao[1]; - GLuint buffer[6]; + GLuint buffer[5]; void initialize_buffers(); void compile_shaders(void); void compute_normals_and_vertices(void); diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index c7df02791ad..b1b7fa97ecb 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -7,149 +7,906 @@ #include #include - namespace { - void CGALglcolor(QColor c, int dv = 0) - { +void CGALglcolor(QColor c, int dv = 0) +{ if ( 0 != dv ) { -// workaround for Qt-4.2. + // workaround for Qt-4.2. #if QT_VERSION < 0x040300 # define darker dark #endif - c = c.darker(dv); + c = c.darker(dv); #undef darker } ::glColor4d(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); - } +} +} +struct light_info +{ + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; +}; +typedef Scene_polylines_item::K K; +typedef K::Point_3 Point_3; + +void Scene_polylines_item::create_Sphere(double R) +{ + + float T, P; + int rings(18), sectors(36); + float x[4],y[4],z[4]; + + + //Top of the sphere + for(int t=0; t<360; t+=sectors) + { + + positions_spheres.push_back(0); + positions_spheres.push_back(0); + positions_spheres.push_back(R); + positions_spheres.push_back(1.0); + + + normals_spheres.push_back(0); + normals_spheres.push_back(0); + normals_spheres.push_back(1); + + + + P = rings*M_PI/180.0; + T = t*M_PI/180.0; + x[1] = sin(P) * cos(T) ; + y[1] = sin(P) * sin(T) ; + z[1] = cos(P); + positions_spheres.push_back(R * x[1]); + positions_spheres.push_back(R * y[1]); + positions_spheres.push_back(R * z[1]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[1]); + normals_spheres.push_back(y[1]); + normals_spheres.push_back(z[1]); + + // + P = rings*M_PI/180.0; + T = (t+sectors)*M_PI/180.0; + x[2] = sin(P) * cos(T) ; + y[2] = sin(P) * sin(T) ; + z[2] = cos(P); + positions_spheres.push_back(R * x[2]); + positions_spheres.push_back(R * y[2]); + positions_spheres.push_back(R * z[2]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[2]); + normals_spheres.push_back(y[2]); + normals_spheres.push_back(z[2]); + + } + + //Body of the sphere + for (int p=rings; p<180-rings; p+=rings) + for(int t=0; t<360; t+=sectors) + { + P = p*M_PI/180.0; + T = t*M_PI/180.0; + x[0] = sin(P) * cos(T) ; + y[0] = sin(P) * sin(T) ; + z[0] = cos(P); + + positions_spheres.push_back(R * x[0]); + positions_spheres.push_back(R * y[0]); + positions_spheres.push_back(R * z[0]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[0]); + normals_spheres.push_back(y[0]); + normals_spheres.push_back(z[0]); + + + P = (p+rings)*M_PI/180.0; + T = t*M_PI/180.0; + x[1] = sin(P) * cos(T) ; + y[1] = sin(P) * sin(T) ; + z[1] = cos(P); + positions_spheres.push_back(R * x[1]); + positions_spheres.push_back(R * y[1]); + positions_spheres.push_back(R * z[1]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[1]); + normals_spheres.push_back(y[1]); + normals_spheres.push_back(z[1]); + + + P = p*M_PI/180.0; + T = (t+sectors)*M_PI/180.0; + x[2] = sin(P) * cos(T) ; + y[2] = sin(P) * sin(T) ; + z[2] = cos(P); + positions_spheres.push_back(R * x[2]); + positions_spheres.push_back(R * y[2]); + positions_spheres.push_back(R * z[2]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[2]); + normals_spheres.push_back(y[2]); + normals_spheres.push_back(z[2]); + + P = (p+rings)*M_PI/180.0; + T = (t+sectors)*M_PI/180.0; + x[3] = sin(P) * cos(T) ; + y[3] = sin(P) * sin(T) ; + z[3] = cos(P); + positions_spheres.push_back(R * x[3]); + positions_spheres.push_back(R * y[3]); + positions_spheres.push_back(R * z[3]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[3]); + normals_spheres.push_back(y[3]); + normals_spheres.push_back(z[3]); + + + + positions_spheres.push_back(R * x[1]); + positions_spheres.push_back(R * y[1]); + positions_spheres.push_back(R * z[1]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[1]); + normals_spheres.push_back(y[1]); + normals_spheres.push_back(z[1]); + + positions_spheres.push_back(R * x[2]); + positions_spheres.push_back(R * y[2]); + positions_spheres.push_back(R * z[2]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[2]); + normals_spheres.push_back(y[2]); + normals_spheres.push_back(z[2]); + + } + //Bottom of the sphere + for(int t=0; t<360; t+=sectors) + { + + + positions_spheres.push_back(0); + positions_spheres.push_back(0); + positions_spheres.push_back(-R); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(0); + normals_spheres.push_back(0); + normals_spheres.push_back(-1); + + + P = (180-rings)*M_PI/180.0; + T = t*M_PI/180.0; + x[1] = sin(P) * cos(T) ; + y[1] = sin(P) * sin(T) ; + z[1] = cos(P); + positions_spheres.push_back(R * x[1]); + positions_spheres.push_back(R * y[1]); + positions_spheres.push_back(R * z[1]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[1]); + normals_spheres.push_back(y[1]); + normals_spheres.push_back(z[1]); + + + P = (180-rings)*M_PI/180.0; + T = (t+sectors)*M_PI/180.0; + x[2] = sin(P) * cos(T) ; + y[2] = sin(P) * sin(T) ; + z[2] = cos(P); + positions_spheres.push_back(R * x[2]); + positions_spheres.push_back(R * y[2]); + positions_spheres.push_back(R * z[2]); + positions_spheres.push_back(1.0); + + normals_spheres.push_back(x[2]); + normals_spheres.push_back(y[2]); + normals_spheres.push_back(z[2]); + + } } class Scene_polylines_item_private { public: - typedef Scene_polylines_item::K K; - typedef K::Point_3 Point_3; + typedef Scene_polylines_item::K K; + typedef K::Point_3 Point_3; - Scene_polylines_item_private() : - draw_extremities(false), - spheres_drawn_radius(0), - sphere_display_list(0), - quadric(0) - {} + Scene_polylines_item_private() : + draw_extremities(false), + spheres_drawn_radius(0), + sphere_display_list(0), + quadric(0) + {} - ~Scene_polylines_item_private() - { - if(quadric != 0) - gluDeleteQuadric(quadric); - if(sphere_display_list != 0) - glDeleteLists(sphere_display_list, 1); - } + ~Scene_polylines_item_private() + { + if(quadric != 0) + gluDeleteQuadric(quadric); + if(sphere_display_list != 0) + glDeleteLists(sphere_display_list, 1); + } - void draw_sphere(const K::Point_3&, double) const; - void draw_spheres(const Scene_polylines_item*) const; + void draw_sphere(const K::Point_3&, double) const; + void draw_spheres(const Scene_polylines_item*) const; - bool draw_extremities; - double spheres_drawn_radius; + bool draw_extremities; + double spheres_drawn_radius; private: - mutable GLuint sphere_display_list; - mutable GLUquadric* quadric; + mutable GLuint sphere_display_list; + mutable GLUquadric* quadric; }; -Scene_polylines_item::Scene_polylines_item() - : d(new Scene_polylines_item_private()) +void +Scene_polylines_item::initialize_buffers() { + glBindVertexArray(vao[0]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_lines.size())*sizeof(float), + positions_lines.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(0, //number of the buffer + 4, //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, + (positions_spheres.size())*sizeof(float), + positions_spheres.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(1, //number of the buffer + 4, //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, + (normals_spheres.size())*sizeof(float), + normals_spheres.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(2); + + + + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glBufferData(GL_ARRAY_BUFFER, + (color_spheres.size())*sizeof(float), + color_spheres.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glBufferData(GL_ARRAY_BUFFER, + (positions_center.size())*sizeof(float), + positions_center.data(), GL_STATIC_DRAW); + glVertexAttribPointer(4, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(4); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[5]); + glBufferData(GL_ARRAY_BUFFER, + (positions_wire_spheres.size())*sizeof(float), + positions_wire_spheres.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(5, //number of the buffer + 4, //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(5); + + glVertexAttribDivisor(3, 1); + glVertexAttribDivisor(4, 1); + // Clean-up + glBindVertexArray(0); + + +} + +void +Scene_polylines_item::compile_shaders() +{ + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 1) in vec4 positions_spheres; \n" + "layout (location = 2) in vec3 vNormals; \n" + "layout (location = 3) in vec3 color_spheres; \n" + "layout (location = 4) in vec3 center; \n" + " \n" + "uniform mat4 mvp_matrix; \n" + "uniform mat4 mv_matrix; \n" + " \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" + " \n" + "out highp vec3 fColors; \n" + " \n" + " \n" + "void main(void) \n" + "{ \n" + " vec4 P = mv_matrix * positions_spheres; \n" + " vec3 N = mat3(mv_matrix)* vNormals; \n" + " vec3 L = light_pos - P.xyz; \n" + " vec3 V = -P.xyz; \n" + " \n" + " N = normalize(N); \n" + " L = normalize(L); \n" + " V = normalize(V); \n" + " \n" + " vec3 R = reflect(-L, N); \n" + " vec3 diffuse; \n" + " if(is_two_side == 1) \n" + " diffuse = abs(dot(N,L)) * light_diff * color_spheres; \n" + " else \n" + " diffuse = max(dot(N,L), 0.0) * light_diff * color_spheres; \n" + " vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" + " \n" + " fColors = light_amb*color_spheres + diffuse + specular ; \n" + " gl_Position = mvp_matrix * vec4(positions_spheres.x + center.x, positions_spheres.y + center.y, positions_spheres.z + center.z, 1.0) ; \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" + }; + + //creates and compiles the vertex shader + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); + glCompileShader(vertex_shader); + + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); + glCompileShader(fragment_shader); + + //creates the program, attaches and links the shaders + GLuint program= glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + //Delete the shaders which are now in the memory + glDeleteShader(vertex_shader); + + rendering_program_spheres = program; + + //For the edges + //fill the vertex shader + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec4 positions_lines; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform vec3 color_lines; \n" + + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color_lines; \n" + " gl_Position = mvp_matrix * positions_lines; \n" + "} \n" + }; + + //creates and compiles the vertex shader + 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); + + //creates the program, attaches and links the shaders + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + //Delete the shaders which are now in the memory + glDeleteShader(vertex_shader); + rendering_program_lines = program; + //For the edges + //fill the vertex shader + static const GLchar* vertex_shader_source_wire_sphere[] = + { + "#version 300 es \n" + " \n" + "layout (location = 5) in vec4 positions_WireSpheres; \n" + "layout (location = 3) in vec3 color_spheres; \n" + "layout (location = 4) in vec3 center; \n" + " \n" + "uniform mat4 mvp_matrix; \n" + " \n" + " \n" + "out highp vec3 fColors; \n" + " \n" + " \n" + "void main(void) \n" + "{ \n" + " fColors = color_spheres; \n" + " gl_Position = mvp_matrix * vec4(positions_WireSpheres.x + center.x, positions_WireSpheres.y + center.y, positions_WireSpheres.z + center.z, 1.0) ; \n" + "} \n" + }; + + //creates and compiles the vertex shader + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source_wire_sphere, NULL); + glCompileShader(vertex_shader); + + glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); + glCompileShader(fragment_shader); + + //creates the program, attaches and links the shaders + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + //Delete the shaders which are now in the memory + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + rendering_program_WireSpheres = program; + +} + + +void Scene_polylines_item::uniform_attrib(Viewer_interface* viewer, int mode) const +{ + 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 matrix 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]); + + if(mode ==0) + { + glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); + + //fills the arraw of colors with the current color + + + //Gets lighting info : + + //position + glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); + + //ambient + glGetLightfv(GL_LIGHT0, GL_AMBIENT, light.ambient); + + + //specular + glGetLightfv(GL_LIGHT0, GL_SPECULAR, light.specular); + + //diffuse + glGetLightfv(GL_LIGHT0, GL_DIFFUSE, light.diffuse); + + + glUseProgram(rendering_program_spheres); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[1], 1, GL_FALSE, mv_mat); + //Set the light infos + 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); + } + else if(mode ==1) + { + //Lines + GLfloat colors[3]; + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[7], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[8], 1, colors); + + glUseProgram(rendering_program_WireSpheres); + glUniformMatrix4fv(location[9], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[10], 1, colors); + } +} + +void +Scene_polylines_item::compute_elements() +{ + positions_spheres.clear(); + positions_wire_spheres.clear(); + positions_lines.clear(); + color_spheres.clear(); + normals_spheres.clear(); + positions_center.clear(); + nbSpheres = 0; + + for(std::list >::const_iterator it = polylines.begin(); + it != polylines.end(); + ++it){ + if(it->empty()) continue; + for(size_t i = 0, end = it->size()-1; + i < end; ++i) + { + const Point_3& a = (*it)[i]; + const Point_3& b = (*it)[i+1]; + positions_lines.push_back(a.x()); + positions_lines.push_back(a.y()); + positions_lines.push_back(a.z()); + positions_lines.push_back(1.0); + + positions_lines.push_back(b.x()); + positions_lines.push_back(b.y()); + positions_lines.push_back(b.z()); + positions_lines.push_back(1.0); + + } + + } + if(d->draw_extremities) + { + + // FIRST, count the number of incident cycles and polylines + // for all extremities. + typedef std::map Point_to_int_map; + typedef Point_to_int_map::iterator iterator; + Point_to_int_map corner_polyline_nb; + + { // scope to fill corner_polyline_nb' + Point_to_int_map corner_cycles_nb; + + for(std::list >::const_iterator + it = this->polylines.begin(), + end = this->polylines.end(); + it != end; ++it) + { + const K::Point_3& a = *it->begin(); + const K::Point_3& b = *it->rbegin(); + if(a == b) { + if ( it->size()>1 ) + ++corner_cycles_nb[a]; + else + ++corner_polyline_nb[a]; + } + else { + ++corner_polyline_nb[a]; + ++corner_polyline_nb[b]; + } + } + // THEN, ignore points that are incident to one cycle only. + for(iterator + c_it = corner_cycles_nb.begin(), + end = corner_cycles_nb.end(); + c_it != end; ++c_it) + { + const Point_3& a = c_it->first; + + iterator p_it = corner_polyline_nb.find(a); + + // If the point 'a'=c_it->first has only incident cycles... + if(p_it == corner_polyline_nb.end()) { + // ...then count it as a corner only if it has two incident cycles + // or more. + if(c_it->second > 1) { + corner_polyline_nb[a] = c_it->second; + } + } else { + // else add the number of cycles. + p_it->second += c_it->second; + } + } + } + // At this point, 'corner_polyline_nb' gives the multiplicity of all + // corners. + for(iterator + p_it = corner_polyline_nb.begin(), + end = corner_polyline_nb.end(); + p_it != end; ++p_it) + { + nbSpheres++; + const K::Point_3& centre = p_it->first; + positions_center.push_back(centre.x()); + positions_center.push_back(centre.y()); + positions_center.push_back(centre.z()); + + float colors[3]; + switch(p_it->second) { + case 1: + colors[0] = 0.0; // black + colors[1] = 0.0; + colors[2] = 0.0; + break; + case 2: + colors[0] = 0.0; // green + colors[1] = 0.8; + colors[2] = 0.0; + break; + case 3: + colors[0] = 0.0; // blue + colors[1] = 0.0; + colors[2] = 0.8; + break; + case 4: + colors[0] = 0.8; //red + colors[1] = 0.0; + colors[2] = 0.0; + break; + default: + colors[0] = 0.8; //fuschia + colors[1] = 0.0; + colors[2] = 0.8; + } + + color_spheres.push_back(colors[0]); + color_spheres.push_back(colors[1]); + color_spheres.push_back(colors[2]); + } + create_Sphere(d->spheres_drawn_radius); + + //Convert the ttriangle coordinates to lines coordinates for the + //Wiremode in the spheres + for(int i=0; i< positions_spheres.size(); i+=12) + { + //AB + for(int j=i; j boxes; - for(std::list >::const_iterator it = polylines.begin(); - it != polylines.end(); - ++it){ - if(it->begin() != it->end()) { - Iso_cuboid_3 cub = CGAL::bounding_box(it->begin(), it->end()); - boxes.push_back((cub.min)()); - boxes.push_back((cub.max)()); + if(isEmpty()) + return Bbox(); + std::list boxes; + for(std::list >::const_iterator it = polylines.begin(); + it != polylines.end(); + ++it){ + if(it->begin() != it->end()) { + Iso_cuboid_3 cub = CGAL::bounding_box(it->begin(), it->end()); + boxes.push_back((cub.min)()); + boxes.push_back((cub.max)()); + } } - } - Iso_cuboid_3 bbox = - boxes.begin() != boxes.end() ? - CGAL::bounding_box(boxes.begin(), boxes.end()) : - Iso_cuboid_3(); + Iso_cuboid_3 bbox = + boxes.begin() != boxes.end() ? + CGAL::bounding_box(boxes.begin(), boxes.end()) : + Iso_cuboid_3(); - return Bbox(bbox.xmin(), - bbox.ymin(), - bbox.zmin(), - bbox.xmax(), - bbox.ymax(), - bbox.zmax()); + return Bbox(bbox.xmin(), + bbox.ymin(), + bbox.zmin(), + bbox.xmax(), + bbox.ymax(), + bbox.zmax()); } Scene_polylines_item* Scene_polylines_item::clone() const { - Scene_polylines_item* item = new Scene_polylines_item; - item->polylines = polylines; - QVariant metadata_variant = property("polylines metadata"); - if(metadata_variant.type() == QVariant::StringList) - { - item->setProperty("polylines metadata", metadata_variant); - } - return item; + Scene_polylines_item* item = new Scene_polylines_item; + item->polylines = polylines; + QVariant metadata_variant = property("polylines metadata"); + if(metadata_variant.type() == QVariant::StringList) + { + item->setProperty("polylines metadata", metadata_variant); + } + return item; } QString Scene_polylines_item::toolTip() const { - QString s = - tr("

%1 (mode: %2, color: %3)
" - "Polylines

" - "

Number of polylines: %4

") - .arg(this->name()) - .arg(this->renderingModeName()) - .arg(this->color().name()) - .arg(polylines.size()); - if(d->draw_extremities) { - s += tr("

Legende of endpoints colors:

    " - "
  • black: one incident polyline
  • " - "
  • green: two incident polylines
  • " - "
  • blue: three incident polylines
  • " - "
  • red: four incident polylines
  • " - "
  • fuchsia: five or more incident polylines
  • " - "

"); - } - return s; + QString s = + tr("

%1 (mode: %2, color: %3)
" + "Polylines

" + "

Number of polylines: %4

") + .arg(this->name()) + .arg(this->renderingModeName()) + .arg(this->color().name()) + .arg(polylines.size()); + if(d->draw_extremities) { + s += tr("

Legende of endpoints colors:

    " + "
  • black: one incident polyline
  • " + "
  • green: two incident polylines
  • " + "
  • blue: three incident polylines
  • " + "
  • red: four incident polylines
  • " + "
  • fuchsia: five or more incident polylines
  • " + "

"); + } + return s; } bool Scene_polylines_item::supportsRenderingMode(RenderingMode m) const { - return (m == Wireframe || + return (m == Wireframe || m == FlatPlusEdges || m == Points); } // Shaded OpenGL drawing: only draw spheres void -Scene_polylines_item::draw() const { - if(d->draw_extremities) - d->draw_spheres(this); +Scene_polylines_item::draw(Viewer_interface* viewer) const { + + if(d->draw_extremities) + { + glBindVertexArray(vao[0]); + + // tells the GPU to use the program just created + glUseProgram(rendering_program_spheres); + uniform_attrib(viewer,0); + //draw the polygons + // the third argument is the number of vec4 that will be entered + glDrawArraysInstanced(GL_TRIANGLES, 0, positions_spheres.size()/4, nbSpheres); + glUseProgram(0); + glBindVertexArray(0); + } } // Wireframe OpenGL drawing void -Scene_polylines_item::draw_edges() const { - CGALglcolor(this->color()); - ::glBegin(GL_LINES); +Scene_polylines_item::draw_edges(Viewer_interface* viewer) const { + + glBindVertexArray(vao[0]); + + uniform_attrib(viewer,1); + // tells the GPU to use the program just created + glUseProgram(rendering_program_lines); + + //draw the edges + glDrawArrays(GL_LINES, 0, positions_lines.size()/4); + + if(d->draw_extremities) + { + + // tells the GPU to use the program just created + uniform_attrib(viewer,0); + glUseProgram(rendering_program_WireSpheres); + //draw the polygons + + // the third argument is the number of vec4 that will be entered + glDrawArraysInstanced(GL_LINES, 0, positions_wire_spheres.size()/4, nbSpheres); + } + // Clean-up + glUseProgram(0); + glBindVertexArray(0); + /* + CGALglcolor(this->color()); + ::glBegin(GL_LINES); for(std::list >::const_iterator it = polylines.begin(); it != polylines.end(); ++it){ @@ -166,310 +923,330 @@ Scene_polylines_item::draw_edges() const { ::glEnd(); if(d->draw_extremities) { - d->draw_spheres(this); - } + d->draw_spheres(this); + }*/ } void -Scene_polylines_item::draw_points() const { - ::glBegin(GL_POINTS); - // draw all points but endpoints - for(std::list >::const_iterator it = polylines.begin(); - it != polylines.end(); - ++it) - { - if(it->empty()) continue; - for(size_t i = 1, end = it->size()-1; - i < end; ++i) +Scene_polylines_item::draw_points(Viewer_interface* viewer) const { + /* ::glBegin(GL_POINTS); + // draw all points but endpoints + for(std::list >::const_iterator it = polylines.begin(); + it != polylines.end(); + ++it) { - const Point_3& a = (*it)[i]; - ::glVertex3d(a.x(), a.y(), a.z()); + if(it->empty()) continue; + for(size_t i = 1, end = it->size()-1; + i < end; ++i) + { + const Point_3& a = (*it)[i]; + ::glVertex3d(a.x(), a.y(), a.z()); + } } - } - ::glEnd(); + ::glEnd(); - ::glColor3d(1., 0., 0.); //red - // draw endpoints - ::glBegin(GL_POINTS); - for(std::list >::const_iterator it = polylines.begin(); - it != polylines.end(); - ++it){ - if(it->empty()) continue; - const Point_3& a = (*it)[0]; - const Point_3& b = (*it)[it->size()-1]; - ::glVertex3d(a.x(), a.y(), a.z()); - ::glVertex3d(b.x(), b.y(), b.z()); - } - ::glEnd(); + ::glColor3d(1., 0., 0.); //red + // draw endpoints + ::glBegin(GL_POINTS); + for(std::list >::const_iterator it = polylines.begin(); + it != polylines.end(); + ++it){ + if(it->empty()) continue; + const Point_3& a = (*it)[0]; + const Point_3& b = (*it)[it->size()-1]; + ::glVertex3d(a.x(), a.y(), a.z()); + ::glVertex3d(b.x(), b.y(), b.z()); + } + ::glEnd();*/ + glBindVertexArray(vao[0]); + + // tells the GPU to use the program just created + //glUseProgram(rendering_program_lines); + + uniform_attrib(viewer,1); + + //draw the points + glDrawArrays(GL_POINTS, 0, positions_lines.size()/4); + + // Clean-up + glBindVertexArray(0); } void Scene_polylines_item_private:: draw_spheres(const Scene_polylines_item* item) const { - // FIRST, count the number of incident cycles and polylines - // for all extremities. - typedef std::map Point_to_int_map; - typedef Point_to_int_map::iterator iterator; - Point_to_int_map corner_polyline_nb; + // FIRST, count the number of incident cycles and polylines + // for all extremities. + typedef std::map Point_to_int_map; + typedef Point_to_int_map::iterator iterator; + Point_to_int_map corner_polyline_nb; - { // scope to fill corner_polyline_nb' - Point_to_int_map corner_cycles_nb; + { // scope to fill corner_polyline_nb' + Point_to_int_map corner_cycles_nb; - for(std::list >::const_iterator - it = item->polylines.begin(), - end = item->polylines.end(); - it != end; ++it) - { - const K::Point_3& a = *it->begin(); - const K::Point_3& b = *it->rbegin(); - if(a == b) { - if ( it->size()>1 ) - ++corner_cycles_nb[a]; - else - ++corner_polyline_nb[a]; - } - else { - ++corner_polyline_nb[a]; - ++corner_polyline_nb[b]; - } - } - // THEN, ignore points that are incident to one cycle only. - for(iterator - c_it = corner_cycles_nb.begin(), - end = corner_cycles_nb.end(); - c_it != end; ++c_it) - { - const Point_3& a = c_it->first; - - iterator p_it = corner_polyline_nb.find(a); - - // If the point 'a'=c_it->first has only incident cycles... - if(p_it == corner_polyline_nb.end()) { - // ...then count it as a corner only if it has two incident cycles - // or more. - if(c_it->second > 1) { - corner_polyline_nb[a] = c_it->second; + for(std::list >::const_iterator + it = item->polylines.begin(), + end = item->polylines.end(); + it != end; ++it) + { + const K::Point_3& a = *it->begin(); + const K::Point_3& b = *it->rbegin(); + if(a == b) { + if ( it->size()>1 ) + ++corner_cycles_nb[a]; + else + ++corner_polyline_nb[a]; + } + else { + ++corner_polyline_nb[a]; + ++corner_polyline_nb[b]; + } + } + // THEN, ignore points that are incident to one cycle only. + for(iterator + c_it = corner_cycles_nb.begin(), + end = corner_cycles_nb.end(); + c_it != end; ++c_it) + { + const Point_3& a = c_it->first; + + iterator p_it = corner_polyline_nb.find(a); + + // If the point 'a'=c_it->first has only incident cycles... + if(p_it == corner_polyline_nb.end()) { + // ...then count it as a corner only if it has two incident cycles + // or more. + if(c_it->second > 1) { + corner_polyline_nb[a] = c_it->second; + } + } else { + // else add the number of cycles. + p_it->second += c_it->second; + } } - } else { - // else add the number of cycles. - p_it->second += c_it->second; - } } - } - // At this point, 'corner_polyline_nb' gives the multiplicity of all - // corners. - for(iterator + // At this point, 'corner_polyline_nb' gives the multiplicity of all + // corners. + for(iterator p_it = corner_polyline_nb.begin(), end = corner_polyline_nb.end(); - p_it != end; ++p_it) - { - switch(p_it->second) { - case 1: - ::glColor3d(0.0, 0.0, 0.0); // black - break; - case 2: - ::glColor3d(0.0, 0.8, 0.0); // green - break; - case 3: - ::glColor3d(0.0, 0.0, 0.8); // blue - break; - case 4: - ::glColor3d(0.8, 0.0, 0.0); //red - break; - default: - ::glColor3d(0.8, 0.0, 0.8); //fuschia + p_it != end; ++p_it) + { + switch(p_it->second) { + case 1: + ::glColor3d(0.0, 0.0, 0.0); // black + break; + case 2: + ::glColor3d(0.0, 0.8, 0.0); // green + break; + case 3: + ::glColor3d(0.0, 0.0, 0.8); // blue + break; + case 4: + ::glColor3d(0.8, 0.0, 0.0); //red + break; + default: + ::glColor3d(0.8, 0.0, 0.8); //fuschia + } + this->draw_sphere(p_it->first, this->spheres_drawn_radius); } - this->draw_sphere(p_it->first, this->spheres_drawn_radius); - } } void Scene_polylines_item_private::draw_sphere(const K::Point_3& p, - double r) const + double r) const { - if(sphere_display_list == 0) { - sphere_display_list = glGenLists(1); - if(sphere_display_list == 0) - std::cerr << "ERROR: Cannot create display list!\n"; - if(quadric == 0) - quadric = gluNewQuadric(); - if(quadric == 0) - std::cerr << "ERROR: Cannot create GLU quadric!\n"; - glNewList(sphere_display_list, GL_COMPILE); - gluSphere(quadric, 1., 10, 10); - glEndList(); - if(glGetError() != GL_NO_ERROR) - std::cerr << gluErrorString(glGetError()); - } - glPushMatrix(); - glTranslated(CGAL::to_double(p.x()), - CGAL::to_double(p.y()), - CGAL::to_double(p.z())); + if(sphere_display_list == 0) { + sphere_display_list = glGenLists(1); + if(sphere_display_list == 0) + std::cerr << "ERROR: Cannot create display list!\n"; + if(quadric == 0) + quadric = gluNewQuadric(); + if(quadric == 0) + std::cerr << "ERROR: Cannot create GLU quadric!\n"; + glNewList(sphere_display_list, GL_COMPILE); + gluSphere(quadric, 1., 10, 10); + glEndList(); + if(glGetError() != GL_NO_ERROR) + std::cerr << gluErrorString(glGetError()); + } + glPushMatrix(); + glTranslated(CGAL::to_double(p.x()), + CGAL::to_double(p.y()), + CGAL::to_double(p.z())); - glScaled(r, r, r); - glCallList(sphere_display_list); - glPopMatrix(); + glScaled(r, r, r); + glCallList(sphere_display_list); + glPopMatrix(); } QMenu* Scene_polylines_item::contextMenu() { - const char* prop_name = "Menu modified by Scene_polylines_item."; + const char* prop_name = "Menu modified by Scene_polylines_item."; - QMenu* menu = Scene_item::contextMenu(); + QMenu* menu = Scene_item::contextMenu(); - // Use dynamic properties: - // http://doc.trolltech.com/lastest/qobject.html#property - bool menuChanged = menu->property(prop_name).toBool(); + // Use dynamic properties: + // http://doc.trolltech.com/lastest/qobject.html#property + bool menuChanged = menu->property(prop_name).toBool(); + + if(!menuChanged) { + menu->addSeparator(); + // TODO: add actions to display corners + QAction* action = menu->addAction(tr("Display corners with radius...")); + connect(action, SIGNAL(triggered()), + this, SLOT(change_corner_radii())); + + QAction* actionSmoothPolylines = + menu->addAction(tr("Smooth polylines")); + actionSmoothPolylines->setObjectName("actionSmoothPolylines"); + connect(actionSmoothPolylines, SIGNAL(triggered()),this, SLOT(smooth())); + menu->setProperty(prop_name, true); + } + return menu; +} + +void Scene_polylines_item::changed() +{ + compute_elements(); + initialize_buffers(); - if(!menuChanged) { - menu->addSeparator(); - // TODO: add actions to display corners - QAction* action = menu->addAction(tr("Display corners with radius...")); - connect(action, SIGNAL(triggered()), - this, SLOT(change_corner_radii())); - QAction* actionSmoothPolylines = - menu->addAction(tr("Smooth polylines")); - actionSmoothPolylines->setObjectName("actionSmoothPolylines"); - connect(actionSmoothPolylines, SIGNAL(triggered()),this, SLOT(smooth())); - menu->setProperty(prop_name, true); - } - return menu; } void Scene_polylines_item::change_corner_radii() { - bool ok = true; - double proposed_radius = d->spheres_drawn_radius; - if(proposed_radius == 0) { - Scene_interface::Bbox b = bbox(); - proposed_radius = (std::max)(b.xmax - b.xmin, - proposed_radius); - proposed_radius = (std::max)(b.ymax - b.ymin, - proposed_radius); - proposed_radius = (std::max)(b.zmax - b.zmin, - proposed_radius); - proposed_radius /= 100; - } - double r = QInputDialog::getDouble(NULL, - tr("Display corners with new radius..."), - tr("Radius:"), - proposed_radius, // value - 0., // min - 2147483647., // max - 10, // decimals - &ok); - if(ok) { - change_corner_radii(r); - } + bool ok = true; + double proposed_radius = d->spheres_drawn_radius; + if(proposed_radius == 0) { + Scene_interface::Bbox b = bbox(); + proposed_radius = (std::max)(b.xmax - b.xmin, + proposed_radius); + proposed_radius = (std::max)(b.ymax - b.ymin, + proposed_radius); + proposed_radius = (std::max)(b.zmax - b.zmin, + proposed_radius); + proposed_radius /= 100; + } + double r = QInputDialog::getDouble(NULL, + tr("Display corners with new radius..."), + tr("Radius:"), + proposed_radius, // value + 0., // min + 2147483647., // max + 10, // decimals + &ok); + if(ok) { + change_corner_radii(r); + } } void Scene_polylines_item::change_corner_radii(double r) { - if(r >= 0) { - d->spheres_drawn_radius = r; - d->draw_extremities = (r > 0); - this->changed(); - emit itemChanged(); - } + if(r >= 0) { + d->spheres_drawn_radius = r; + d->draw_extremities = (r > 0); + this->changed(); + emit itemChanged(); + } } void Scene_polylines_item::split_at_sharp_angles() { - typedef Polylines_container Bare_polyline_container; - typedef Polyline Bare_polyline; - Polylines_container& bare_polylines = polylines; + typedef Polylines_container Bare_polyline_container; + typedef Polyline Bare_polyline; + Polylines_container& bare_polylines = polylines; - int counter = 0; - for(Bare_polyline_container::iterator + int counter = 0; + for(Bare_polyline_container::iterator bare_polyline_it = bare_polylines.begin(); - bare_polyline_it != bare_polylines.end(); // the end changes - // during the loop - ++counter /* bare_polyline_it is incremented in the loop */) - { - Bare_polyline_container::iterator current_polyline_it = - bare_polyline_it; - Bare_polyline& bare_polyline = *bare_polyline_it; - Bare_polyline::iterator it = boost::next(bare_polyline.begin()); - - if(boost::next(bare_polyline.begin()) == bare_polyline.end()) + bare_polyline_it != bare_polylines.end(); // the end changes + // during the loop + ++counter /* bare_polyline_it is incremented in the loop */) { - std::cerr << "WARNING: Isolated point in polylines\n"; - bare_polyline_it = bare_polylines.erase(bare_polyline_it); - continue; - } - else - ++bare_polyline_it; - if(it != bare_polyline.end()) { - for(; it != boost::prior(bare_polyline.end()); ++it) { - const Point_3 pv = *it; - const Point_3 pa = *boost::prior(it); - const Point_3 pb = *boost::next(it); - const K::Vector_3 av = pv - pa; - const K::Vector_3 bv = pv - pb; - const K::FT sc_prod = av * bv; - if( sc_prod >= 0 || - (sc_prod < 0 && - CGAL::square(sc_prod) < (av * av) * (bv * bv) / 4 ) ) + Bare_polyline_container::iterator current_polyline_it = + bare_polyline_it; + Bare_polyline& bare_polyline = *bare_polyline_it; + Bare_polyline::iterator it = boost::next(bare_polyline.begin()); + + if(boost::next(bare_polyline.begin()) == bare_polyline.end()) { -#ifdef PROTECTION_DEBUG - std::cerr << "Split polyline (small angle) " - << std::acos(sqrt(CGAL::square(sc_prod) / - ((av*av) * (bv*bv)))) * 180 /CGAL_PI - << " degres\n"; -#endif - Bare_polyline new_polyline; - std::copy(it, bare_polyline.end(), - std::back_inserter(new_polyline)); - - if(*bare_polyline.begin() == *bare_polyline.rbegin()) { - // if the polyline is a cycle, test if its beginning is a sharp - // angle... - const Point_3 pv = *bare_polyline.begin(); - const Point_3 pa = *boost::prior(boost::prior(bare_polyline.end())); - const Point_3 pb = *boost::next(bare_polyline.begin()); - const K::Vector_3 av = pv - pa; - const K::Vector_3 bv = pv - pb; - const K::FT sc_prod = av * bv; - if( sc_prod >= 0 || - (sc_prod < 0 && - CGAL::square(sc_prod) < (av * av) * (bv * bv) / 4 ) ) - { - // if its beginning is a sharp angle, then split - bare_polyline.erase(boost::next(it), bare_polyline.end()); - } - else { - // ...if not, modifies its beginning - std::copy(boost::next(bare_polyline.begin()), - boost::next(it), - std::back_inserter(new_polyline)); - bare_polylines.erase(current_polyline_it); - } - } - else { - bare_polyline.erase(boost::next(it), bare_polyline.end()); - } - bare_polylines.push_back(new_polyline); - break; + std::cerr << "WARNING: Isolated point in polylines\n"; + bare_polyline_it = bare_polylines.erase(bare_polyline_it); + continue; + } + else + ++bare_polyline_it; + if(it != bare_polyline.end()) { + for(; it != boost::prior(bare_polyline.end()); ++it) { + const Point_3 pv = *it; + const Point_3 pa = *boost::prior(it); + const Point_3 pb = *boost::next(it); + const K::Vector_3 av = pv - pa; + const K::Vector_3 bv = pv - pb; + const K::FT sc_prod = av * bv; + if( sc_prod >= 0 || + (sc_prod < 0 && + CGAL::square(sc_prod) < (av * av) * (bv * bv) / 4 ) ) + { +#ifdef PROTECTION_DEBUG + std::cerr << "Split polyline (small angle) " + << std::acos(sqrt(CGAL::square(sc_prod) / + ((av*av) * (bv*bv)))) * 180 /CGAL_PI + << " degres\n"; +#endif + Bare_polyline new_polyline; + std::copy(it, bare_polyline.end(), + std::back_inserter(new_polyline)); + + if(*bare_polyline.begin() == *bare_polyline.rbegin()) { + // if the polyline is a cycle, test if its beginning is a sharp + // angle... + const Point_3 pv = *bare_polyline.begin(); + const Point_3 pa = *boost::prior(boost::prior(bare_polyline.end())); + const Point_3 pb = *boost::next(bare_polyline.begin()); + const K::Vector_3 av = pv - pa; + const K::Vector_3 bv = pv - pb; + const K::FT sc_prod = av * bv; + if( sc_prod >= 0 || + (sc_prod < 0 && + CGAL::square(sc_prod) < (av * av) * (bv * bv) / 4 ) ) + { + // if its beginning is a sharp angle, then split + bare_polyline.erase(boost::next(it), bare_polyline.end()); + } + else { + // ...if not, modifies its beginning + std::copy(boost::next(bare_polyline.begin()), + boost::next(it), + std::back_inserter(new_polyline)); + bare_polylines.erase(current_polyline_it); + } + } + else { + bare_polyline.erase(boost::next(it), bare_polyline.end()); + } + bare_polylines.push_back(new_polyline); + break; + } + } } - } } - } - emit itemChanged(); + emit itemChanged(); } void Scene_polylines_item::merge(Scene_polylines_item* other_item) { - if(other_item == 0) return; - std::copy(other_item->polylines.begin(), - other_item->polylines.end(), - std::back_inserter(polylines)); - QVariant other_metadata_variant = other_item->property("polylines metadata"); - if(other_metadata_variant.type() == QVariant::StringList) - { - QStringList metadata = property("polylines metadata").toStringList(); - metadata.append(other_metadata_variant.toStringList()); - setProperty("polylines metadata", metadata); - } - changed(); + if(other_item == 0) return; + std::copy(other_item->polylines.begin(), + other_item->polylines.end(), + std::back_inserter(polylines)); + QVariant other_metadata_variant = other_item->property("polylines metadata"); + if(other_metadata_variant.type() == QVariant::StringList) + { + QStringList metadata = property("polylines metadata").toStringList(); + metadata.append(other_metadata_variant.toStringList()); + setProperty("polylines metadata", metadata); + } + changed(); } #include "Scene_polylines_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h index a7ad624c002..2674877f2ee 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h @@ -1,8 +1,8 @@ #ifndef SCENE_POLYLINES_ITEM_H #define SCENE_POLYLINES_ITEM_H - +#include #include "Scene_polylines_item_config.h" - +#include "Viewer_interface.h" #include #include "Scene_item.h" @@ -16,77 +16,107 @@ class Scene_polylines_item_private; class SCENE_POLYLINES_ITEM_EXPORT Scene_polylines_item : public Scene_item { - Q_OBJECT + Q_OBJECT public: - typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef K::Point_3 Point_3; - typedef std::vector Polyline; - typedef std::list Polylines_container; + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + typedef K::Point_3 Point_3; + typedef std::vector Polyline; + typedef std::list Polylines_container; - typedef K::Iso_cuboid_3 Iso_cuboid_3; + typedef K::Iso_cuboid_3 Iso_cuboid_3; - Scene_polylines_item(); - virtual ~Scene_polylines_item(); + Scene_polylines_item(); + virtual ~Scene_polylines_item(); - bool isFinite() const { return true; } - bool isEmpty() const; - Bbox bbox() const; + bool isFinite() const { return true; } + bool isEmpty() const; + Bbox bbox() const; - Scene_polylines_item* clone() const; + Scene_polylines_item* clone() const; - QString toolTip() const; + QString toolTip() const; - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const; + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const; - QMenu* contextMenu(); - - // Flat/Gouraud OpenGL drawing - void draw() const; + QMenu* contextMenu(); - // Wireframe OpenGL drawing - void draw_edges() const; + // Flat/Gouraud OpenGL drawing + void draw() const {} + void draw(Viewer_interface*) const; - void draw_points() const; - - void smooth(std::vector& polyline){ - bool is_closed = polyline.front()==polyline.back(); - typedef K::Vector_3 Vector_3; - - std::size_t start = is_closed ? 0:1; - std::size_t end = polyline.size()-1; - - Vector_3 prev = (is_closed ? polyline[end-1] : polyline[0]) - CGAL::ORIGIN; - - for (std::size_t i=start; i!=end; ++i) - { - Vector_3 curr = polyline[i] - CGAL::ORIGIN; - Vector_3 next = polyline[i+1] - CGAL::ORIGIN; - - polyline[i] = CGAL::ORIGIN+(prev+2*curr+next)/4; - prev=curr; + // Wireframe OpenGL drawing + void draw_edges() const{} + void draw_edges(Viewer_interface*) const; + + void draw_points() const{} + void draw_points(Viewer_interface*) const; + + + void smooth(std::vector& polyline){ + bool is_closed = polyline.front()==polyline.back(); + typedef K::Vector_3 Vector_3; + + std::size_t start = is_closed ? 0:1; + std::size_t end = polyline.size()-1; + + Vector_3 prev = (is_closed ? polyline[end-1] : polyline[0]) - CGAL::ORIGIN; + + for (std::size_t i=start; i!=end; ++i) + { + Vector_3 curr = polyline[i] - CGAL::ORIGIN; + Vector_3 next = polyline[i+1] - CGAL::ORIGIN; + + polyline[i] = CGAL::ORIGIN+(prev+2*curr+next)/4; + prev=curr; + } + + if (is_closed) polyline[end]=polyline[0]; } - - if (is_closed) polyline[end]=polyline[0]; - } - + public slots: - void change_corner_radii(double); - void change_corner_radii(); - void split_at_sharp_angles(); + virtual void changed(); + void change_corner_radii(double); + void change_corner_radii(); + void split_at_sharp_angles(); - void merge(Scene_polylines_item*); + void merge(Scene_polylines_item*); - void smooth(){ - for (Polylines_container::iterator pit=polylines.begin(),pit_end=polylines.end();pit!=pit_end;++pit) - smooth(*pit); - emit itemChanged(); - } + void smooth(){ + for (Polylines_container::iterator pit=polylines.begin(),pit_end=polylines.end();pit!=pit_end;++pit) + smooth(*pit); + emit itemChanged(); + } public: - Polylines_container polylines; + Polylines_container polylines; + + // http://en.wikipedia.org/wiki/D-pointer + Scene_polylines_item_private* d; +private: + std::vector positions_lines; + std::vector positions_spheres; + std::vector positions_wire_spheres; + std::vector positions_center; + std::vector normals_spheres; + std::vector color_spheres; + + + + GLint location[11]; + GLuint vao[1]; + GLuint buffer[6]; + GLuint rendering_program_spheres; + GLuint rendering_program_lines; + GLuint rendering_program_WireSpheres; + GLuint nbSpheres; + typedef std::map Point_to_int_map; + typedef Point_to_int_map::iterator iterator; + void create_Sphere(double); + void initialize_buffers(); + void compile_shaders(); + void uniform_attrib(Viewer_interface*, int) const; + void compute_elements(); - // http://en.wikipedia.org/wiki/D-pointer - Scene_polylines_item_private* d; }; // end class Scene_polylines_item