From 2a8c38111311cca78bc25cbf5db907322da89f9f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Feb 2015 14:28:09 +0100 Subject: [PATCH 01/62] first commit, update of the OpenGL code for Scene_polygon_soup_item --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 2 +- Polyhedron/demo/Polyhedron/Scene_item.h | 4 +- .../Polyhedron/Scene_polygon_soup_item.cpp | 745 +++++++++++++----- .../demo/Polyhedron/Scene_polygon_soup_item.h | 10 +- 4 files changed, 550 insertions(+), 211 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 87007ae046e..12b5edd5033 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -213,7 +213,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) add_item(scene_implicit_function_item Scene_implicit_function_item.cpp Scene_implicit_function_item.moc Color_ramp.cpp) add_item(scene_polygon_soup_item Scene_polygon_soup_item.cpp Scene_polygon_soup_item.moc) - target_link_libraries(scene_polygon_soup_item scene_polyhedron_item) + target_link_libraries(scene_polygon_soup_item scene_polyhedron_item ${GLEW_LIBRARIES}) add_item(scene_nef_polyhedron_item Scene_nef_polyhedron_item.cpp Scene_nef_polyhedron_item.moc Scene_nef_rendering.cpp) target_link_libraries(scene_nef_polyhedron_item scene_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 94b636acee2..183b6d07717 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -43,10 +43,10 @@ public: virtual bool supportsRenderingMode(RenderingMode m) const = 0; // Flat/Gouraud OpenGL drawing virtual void draw() const = 0; - virtual void draw(Viewer_interface*) const { draw(); } + virtual void draw(Viewer_interface*) const { draw(); } // Wireframe OpenGL drawing virtual void draw_edges() const { draw(); } - virtual void draw_edges(Viewer_interface*) const { draw_edges(); } + virtual void draw_edges(Viewer_interface* viewer) const { draw(viewer); } // Points OpenGL drawing virtual void draw_points() const { draw(); } virtual void draw_points(Viewer_interface*) const { draw_points(); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 7ff448012c6..dcdaa41ebd3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -1,3 +1,5 @@ +#include + #include "Scene_polygon_soup_item.h" #include "Scene_polyhedron_item.h" #include @@ -13,90 +15,263 @@ #include #include -#include +#include #include #include #include + + +std::vector positions_poly(0); +std::vector positions_lines(0); +std::vector positions_points(0); +std::vector colors(0); +std::vector normals(0); +GLuint rendering_program; +GLuint vertex_array_object; +int isInit = 0; +GLint location; +GLfloat *mvp_mat; + +GLuint vertex_shader; +GLuint fragment_shader; +GLuint program; +GLuint vao; +GLuint buffer[3]; + +GLuint compile_shaders(void) +{ + + + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(3, buffer); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + + glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.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); + + + + //Bind the second and initialize it + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + glBufferData(GL_ARRAY_BUFFER, (colors.size())*sizeof(colors.data()), colors.data(), GL_STATIC_DRAW); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(1); + + //Bind the second and initialize it + glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); + glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(2); + + + + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec4 positions_poly; \n" + "layout (location = 1) in vec3 vColors; \n" + "uniform mat4 mvp_matrix; \n" + "out highp vec3 fColors; \n" + " \n" + "void main(void) \n" + "{ \n" + "gl_Position = mvp_matrix * positions_poly; \n" + "fColors = vColors; \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" //polygons de couleur rouge + "} \n" + }; + + //creates and compiles the vertex shader + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); + glCompileShader(vertex_shader); + + GLint result; + glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); + if(result == GL_TRUE){ + std::cout<<"Vertex compilation OK"<clear(); - } + void write_header( std::ostream&, + std::size_t /* vertices */, + std::size_t /* halfedges */, + std::size_t /* facets */, + bool /* normals */ = false ) { + soup->clear(); + } - void write_footer() { - } + void write_footer() { + } - void write_vertex( const double& x, const double& y, const double& z) { - soup->points.push_back(Point_3(x, y, z)); - } + void write_vertex( const double& x, const double& y, const double& z) { + soup->points.push_back(Point_3(x, y, z)); + } - void write_normal( const double& /* x */, const double& /* y */, const double& /* z */) { - } + void write_normal( const double& /* x */, const double& /* y */, const double& /* z */) { + } - void write_facet_header() { - } + void write_facet_header() { + } - void write_facet_begin( std::size_t no) { - polygon.clear(); - polygon.reserve(no); - } - void write_facet_vertex_index( std::size_t index) { - polygon.push_back(index); - } - void write_facet_end() { - soup->polygons.push_back(polygon); - polygon.clear(); - } + void write_facet_begin( std::size_t no) { + polygon.clear(); + polygon.reserve(no); + } + void write_facet_vertex_index( std::size_t index) { + polygon.push_back(index); + } + void write_facet_end() { + soup->polygons.push_back(polygon); + polygon.clear(); + } }; // end struct Polyhedron_to_soup_writer + Scene_polygon_soup_item::Scene_polygon_soup_item() - : Scene_item_with_display_list(), - soup(0), - oriented(false) + : Scene_item(), + soup(0), + oriented(false) { + glewInit(); + mvp_mat = new GLfloat[16]; } Scene_polygon_soup_item::~Scene_polygon_soup_item() { - delete soup; + glDeleteVertexArrays(1, &vertex_array_object); + glDeleteProgram(rendering_program); + glDeleteVertexArrays(1, &vertex_array_object); + + delete soup; } -Scene_polygon_soup_item* +Scene_polygon_soup_item* Scene_polygon_soup_item::clone() const { - Scene_polygon_soup_item* new_soup = new Scene_polygon_soup_item(); - new_soup->soup = soup->clone(); - new_soup->oriented = oriented; - return new_soup; + Scene_polygon_soup_item* new_soup = new Scene_polygon_soup_item(); + new_soup->soup = soup->clone(); + new_soup->oriented = oriented; + return new_soup; } + bool Scene_polygon_soup_item::load(std::istream& in) { - if (!soup) soup=new Polygon_soup(); - else soup->clear(); - return CGAL::read_OFF(in, soup->points, soup->polygons); + if (!soup) soup=new Polygon_soup(); + else soup->clear(); + return CGAL::read_OFF(in, soup->points, soup->polygons); } void Scene_polygon_soup_item::init_polygon_soup(std::size_t nb_pts, std::size_t nb_polygons){ - if(!soup) - soup = new Polygon_soup; + if(!soup) + soup = new Polygon_soup; soup->clear(); - soup->points.reserve(nb_pts); - soup->polygons.reserve(nb_polygons); - oriented = false; + soup->points.reserve(nb_pts); + soup->polygons.reserve(nb_polygons); + oriented = false; } void Scene_polygon_soup_item::finalize_polygon_soup(){ soup->fill_edges(); } @@ -105,223 +280,385 @@ void Scene_polygon_soup_item::finalize_polygon_soup(){ soup->fill_edges(); } #include void Scene_polygon_soup_item::load(Scene_polyhedron_item* poly_item) { - if(!poly_item) return; - if(!poly_item->polyhedron()) return; + if(!poly_item) return; + if(!poly_item->polyhedron()) return; - if(!soup) - soup = new Polygon_soup; + if(!soup) + soup = new Polygon_soup; - Polyhedron_to_polygon_soup_writer writer(soup); - CGAL::generic_print_polyhedron(std::cerr, - *poly_item->polyhedron(), - writer); - emit changed(); + Polyhedron_to_polygon_soup_writer writer(soup); + CGAL::generic_print_polyhedron(std::cerr, + *poly_item->polyhedron(), + writer); + emit changed(); } void Scene_polygon_soup_item::setDisplayNonManifoldEdges(const bool b) { - soup->display_non_manifold_edges = b; - changed(); + + soup->display_non_manifold_edges = b; + changed(); } bool Scene_polygon_soup_item::displayNonManifoldEdges() const { - return soup->display_non_manifold_edges; + + return soup->display_non_manifold_edges; } void Scene_polygon_soup_item::shuffle_orientations() { - for(Polygon_soup::size_type i = 0, end = soup->polygons.size(); - i < end; ++i) - { - if(std::rand() % 2 == 0) soup->inverse_orientation(i); - } - soup->fill_edges(); - changed(); + for(Polygon_soup::size_type i = 0, end = soup->polygons.size(); + i < end; ++i) + { + if(std::rand() % 2 == 0) soup->inverse_orientation(i); + } + soup->fill_edges(); + changed(); } void Scene_polygon_soup_item::inside_out() { - for(Polygon_soup::size_type i = 0, end = soup->polygons.size(); - i < end; ++i) - { - soup->inverse_orientation(i); - } - soup->fill_edges(); - changed(); + for(Polygon_soup::size_type i = 0, end = soup->polygons.size(); + i < end; ++i) + { + soup->inverse_orientation(i); + } + soup->fill_edges(); + changed(); } -bool +bool Scene_polygon_soup_item::orient() { - if(isEmpty() || oriented) - return true; // nothing to do - oriented=true; - return CGAL::orient_polygon_soup(soup->points, soup->polygons); + + if(isEmpty() || this->oriented) + return true; // nothing to do + + oriented = CGAL::orient_polygon_soup(soup->points, soup->polygons); + return oriented; } -bool +bool Scene_polygon_soup_item::save(std::ostream& out) const { - typedef Polygon_soup::size_type size_type; - CGAL::File_writer_OFF writer; - writer.write_header(out, - soup->points.size(), - 0, - soup->polygons.size()); - for(size_type i = 0, end = soup->points.size(); - i < end; ++i) - { - const Point_3& p = soup->points[i]; - writer.write_vertex( p.x(), p.y(), p.z() ); - } - writer.write_facet_header(); - for(size_type i = 0, end = soup->polygons.size(); - i < end; ++i) - { - const Polygon_soup::Polygon_3& polygon = soup->polygons[i]; - const size_type size = polygon.size(); - writer.write_facet_begin(size); - for(size_type j = 0; j < size; ++j) { - writer.write_facet_vertex_index(polygon[j]); - } - writer.write_facet_end(); - } - writer.write_footer(); - return (bool) out; + typedef Polygon_soup::size_type size_type; + CGAL::File_writer_OFF writer; + writer.write_header(out, + soup->points.size(), + 0, + soup->polygons.size()); + for(size_type i = 0, end = soup->points.size(); + i < end; ++i) + { + const Point_3& p = soup->points[i]; + writer.write_vertex( p.x(), p.y(), p.z() ); + } + writer.write_facet_header(); + for(size_type i = 0, end = soup->polygons.size(); + i < end; ++i) + { + const Polygon_soup::Polygon_3& polygon = soup->polygons[i]; + const size_type size = polygon.size(); + writer.write_facet_begin(size); + for(size_type j = 0; j < size; ++j) { + writer.write_facet_vertex_index(polygon[j]); + } + writer.write_facet_end(); + } + writer.write_footer(); + + return (bool) out; } -bool +bool Scene_polygon_soup_item::exportAsPolyhedron(Polyhedron* out_polyhedron) { - orient(); - CGAL::polygon_soup_to_polyhedron_3(*out_polyhedron, soup->points, soup->polygons); + orient(); + CGAL::polygon_soup_to_polyhedron_3(*out_polyhedron, soup->points, soup->polygons); - if(out_polyhedron->size_of_vertices() > 0) { - // Also check whether the consistent orientation is fine - if(!CGAL::is_oriented(*out_polyhedron)) { - out_polyhedron->inside_out(); + if(out_polyhedron->size_of_vertices() > 0) { + // Also check whether the consistent orientation is fine + if(!CGAL::is_oriented(*out_polyhedron)) { + out_polyhedron->inside_out(); + } + return true; } - return true; - } - return false; + return false; } - -QString +QString Scene_polygon_soup_item::toolTip() const { - if(!soup) - return QString(); - return QObject::tr("

%1 (mode: %5, color: %6)
" - "Polygons soup

" - "

Number of vertices: %2
" - "Number of polygons: %3

") - .arg(this->name()) - .arg(soup->points.size()) - .arg(soup->polygons.size()) - .arg(this->renderingModeName()) - .arg(this->color().name()); + if(!soup) + return QString(); + + return QObject::tr("

%1 (mode: %5, color: %6)
" + "Polygons soup

" + "

Number of vertices: %2
" + "Number of polygons: %3

") + .arg(this->name()) + .arg(soup->points.size()) + .arg(soup->polygons.size()) + .arg(this->renderingModeName()) + .arg(this->color().name()); } void -Scene_polygon_soup_item::direct_draw() const { - typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; - typedef Polygon_soup::Polygons::size_type size_type; - for(Polygons_iterator it = soup->polygons.begin(); - it != soup->polygons.end(); ++it) - { - const Point_3& pa = soup->points[it->at(0)]; - const Point_3& pb = soup->points[it->at(1)]; - const Point_3& pc = soup->points[it->at(2)]; - - Kernel::Vector_3 n = CGAL::cross_product(pb-pa, pc -pa); - n = n / std::sqrt(n * n); - - ::glBegin(GL_POLYGON); - ::glNormal3d(n.x(),n.y(),n.z()); - - for(size_type i = 0; i < it->size(); ++i) { - const Point_3& p = soup->points[it->at(i)]; - ::glVertex3d(p.x(),p.y(),p.z()); - } - ::glEnd(); - } - if(soup->display_non_manifold_edges) { - double current_color[4]; - GLboolean lightning; - ::glGetDoublev(GL_CURRENT_COLOR, current_color); - ::glColor3d(1., 0., 0.); // red - ::glGetBooleanv(GL_LIGHTING, &lightning); - ::glDisable(GL_LIGHTING); - - BOOST_FOREACH(const Polygon_soup::Edge& edge, - soup->non_manifold_edges) +Scene_polygon_soup_item::draw() const { + std::cout<<"Erreur de Draw"<points[edge[0]]; - const Point_3& b = soup->points[edge[1]]; - ::glBegin(GL_LINES); - ::glVertex3d(a.x(), a.y(), a.z()); - ::glVertex3d(b.x(), b.y(), b.z()); - ::glEnd(); + for(Polygons_iterator it = soup->polygons.begin(); + it != soup->polygons.end(); ++it) + { + + const Point_3& pa = soup->points[it->at(0)]; + const Point_3& pb = soup->points[it->at(1)]; + const Point_3& pc = soup->points[it->at(2)]; + + Kernel::Vector_3 n = CGAL::cross_product(pb-pa, pc -pa); + n = n / std::sqrt(n * n); + // ::glBegin(GL_POLYGON); + //::glNormal3d(n.x(),n.y(),n.z()); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + colors.push_back(this->color().redF()); + colors.push_back(this->color().greenF()); + colors.push_back(this->color().blueF()); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + colors.push_back(this->color().redF()); + colors.push_back(this->color().greenF()); + colors.push_back(this->color().blueF()); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + colors.push_back(this->color().redF()); + colors.push_back(this->color().greenF()); + colors.push_back(this->color().blueF()); + + for(size_type i = 0; i < it->size(); ++i) + { + const Point_3& p = soup->points[it->at(i)]; + + positions_poly.push_back(p.x()); + positions_poly.push_back(p.y()); + positions_poly.push_back(p.z()); + positions_poly.push_back(1.0); + + + } + + } + + if(soup->display_non_manifold_edges) { + double current_color[4]; + GLboolean lightning; + ::glGetDoublev(GL_CURRENT_COLOR, current_color); + //::glColor3d(1., 0., 0.); // red + ::glGetBooleanv(GL_LIGHTING, &lightning); + ::glDisable(GL_LIGHTING); + + BOOST_FOREACH(const Polygon_soup::Edge& edge, + soup->non_manifold_edges) + { + const Point_3& a = soup->points[edge[0]]; + const Point_3& b = soup->points[edge[1]]; + + // ::glBegin(GL_LINES); + // ::glVertex3d(a.x(), a.y(), a.z()); + // ::glVertex3d(b.x(), b.y(), b.z()); + // ::glEnd(); + positions_lines.push_back(a.x()); + positions_lines.push_back(a.y()); + positions_lines.push_back(a.y()); + + positions_lines.push_back(b.x()); + positions_lines.push_back(b.y()); + positions_lines.push_back(b.y()); + + } + if(lightning) glEnable(GL_LIGHTING); + // ::glColor4dv(current_color); + } + } - if(lightning) glEnable(GL_LIGHTING); - ::glColor4dv(current_color); - } + render(); +} + +void +Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { + + typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; + typedef Polygon_soup::Polygons::size_type size_type; + + //Remplit la matrice MVP + GLdouble plouf[16]; + viewer->camera()->getModelViewProjectionMatrix(plouf); + + for (int i=0; i<16; ++i) + mvp_mat[i] = GLfloat(plouf[i]); + + + if(isInit!=1) + { + for(Polygons_iterator it = soup->polygons.begin(); + it != soup->polygons.end(); ++it) + { + + const Point_3& pa = soup->points[it->at(0)]; + const Point_3& pb = soup->points[it->at(1)]; + const Point_3& pc = soup->points[it->at(2)]; + + Kernel::Vector_3 n = CGAL::cross_product(pb-pa, pc -pa); + n = n / std::sqrt(n * n); + // ::glBegin(GL_POLYGON); + //::glNormal3d(n.x(),n.y(),n.z()); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + colors.push_back(this->color().redF()); + colors.push_back(this->color().greenF()); + colors.push_back(this->color().blueF()); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + colors.push_back(this->color().redF()); + colors.push_back(this->color().greenF()); + colors.push_back(this->color().blueF()); + + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + + colors.push_back(this->color().redF()); + colors.push_back(this->color().greenF()); + colors.push_back(this->color().blueF()); + + for(size_type i = 0; i < it->size(); ++i) + { + const Point_3& p = soup->points[it->at(i)]; + + positions_poly.push_back(p.x()); + positions_poly.push_back(p.y()); + positions_poly.push_back(p.z()); + positions_poly.push_back(1.0); + + + } + + } + + if(soup->display_non_manifold_edges) { + double current_color[4]; + GLboolean lightning; + ::glGetDoublev(GL_CURRENT_COLOR, current_color); + //::glColor3d(1., 0., 0.); // red + ::glGetBooleanv(GL_LIGHTING, &lightning); + ::glDisable(GL_LIGHTING); + + BOOST_FOREACH(const Polygon_soup::Edge& edge, + soup->non_manifold_edges) + { + const Point_3& a = soup->points[edge[0]]; + const Point_3& b = soup->points[edge[1]]; + + // ::glBegin(GL_LINES); + // ::glVertex3d(a.x(), a.y(), a.z()); + // ::glVertex3d(b.x(), b.y(), b.z()); + // ::glEnd(); + positions_lines.push_back(a.x()); + positions_lines.push_back(a.y()); + positions_lines.push_back(a.y()); + + positions_lines.push_back(b.x()); + positions_lines.push_back(b.y()); + positions_lines.push_back(b.y()); + + } + if(lightning) glEnable(GL_LIGHTING); + // ::glColor4dv(current_color); + } + } + + render(); } void Scene_polygon_soup_item::draw_points() const { - if(soup == 0) return; - ::glBegin(GL_POINTS); - for(Polygon_soup::Points::const_iterator pit = soup->points.begin(), + + + if(soup == 0) return; + //::glBegin(GL_POINTS); + for(Polygon_soup::Points::const_iterator pit = soup->points.begin(), end = soup->points.end(); - pit != end; ++pit) - { - ::glVertex3d(pit->x(), pit->y(), pit->z()); - } - ::glEnd(); + pit != end; ++pit) + { + // ::glVertex3d(pit->x(), pit->y(), pit->z()); + positions_points.push_back(pit->x()); + positions_points.push_back(pit->y()); + positions_points.push_back(pit->y()); + + } + //::glEnd(); } bool Scene_polygon_soup_item::isEmpty() const { - return (soup == 0 || soup->points.empty()); + + return (soup == 0 || soup->points.empty()); } Scene_polygon_soup_item::Bbox Scene_polygon_soup_item::bbox() const { - const Point_3& p = *(soup->points.begin()); - CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); - for(Polygon_soup::Points::const_iterator it = soup->points.begin(); - it != soup->points.end(); - ++it) { - bbox = bbox + it->bbox(); - } - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + + const Point_3& p = *(soup->points.begin()); + CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); + for(Polygon_soup::Points::const_iterator it = soup->points.begin(); + it != soup->points.end(); + ++it) { + bbox = bbox + it->bbox(); + } + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); } -void +void Scene_polygon_soup_item::new_vertex(const double& x, - const double& y, - const double& z) + const double& y, + const double& z) { - soup->points.push_back(Point_3(x, y, z)); + + soup->points.push_back(Point_3(x, y, z)); } - -void + +void Scene_polygon_soup_item::new_triangle(const std::size_t i, - const std::size_t j, - const std::size_t k) + const std::size_t j, + const std::size_t k) { - Polygon_soup::Polygon_3 new_polygon(3); - new_polygon[0] = i; - new_polygon[1] = j; - new_polygon[2] = k; - soup->polygons.push_back(new_polygon); + + Polygon_soup::Polygon_3 new_polygon(3); + new_polygon[0] = i; + new_polygon[1] = j; + new_polygon[2] = k; + soup->polygons.push_back(new_polygon); } - + #include "Scene_polygon_soup_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index f426b544b9a..ad955db8270 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -1,8 +1,9 @@ #ifndef SCENE_POLYGON_SOUP_ITEM_H #define SCENE_POLYGON_SOUP_ITEM_H - +#include #include "Scene_polygon_soup_item_config.h" -#include "Scene_item_with_display_list.h" +#include "Scene_item.h" +#include "Viewer.h" #include "Polyhedron_type.h" #include @@ -93,7 +94,7 @@ struct Polygon_soup class Scene_polyhedron_item; class SCENE_POLYGON_SOUP_ITEM_EXPORT Scene_polygon_soup_item - : public Scene_item_with_display_list + : public Scene_item { typedef Kernel::Point_3 Point_3; @@ -136,7 +137,8 @@ public: // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! // OpenGL drawing in a display list - void direct_draw() const; + void draw() const; + void draw(Viewer_interface*) const; void draw_points() const; bool isFinite() const { return true; } From b9206adc1e7bc1d54874a8d7a47db1b65911aea2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Feb 2015 15:44:51 +0100 Subject: [PATCH 02/62] fix click bugs and wireframe problems An intempestive call to glClearBufferfv cleared the screen at each call to draw. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index dcdaa41ebd3..4e7265424df 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -109,37 +109,37 @@ GLuint compile_shaders(void) }; //creates and compiles the vertex shader - vertex_shader = glCreateShader(GL_VERTEX_SHADER); + vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader); GLint result; glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); if(result == GL_TRUE){ - std::cout<<"Vertex compilation OK"<camera()->getModelViewProjectionMatrix(plouf); - + GLdouble d_mvp_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mvp_mat); + viewer->camera()->getModelViewMatrix(mv_mat); + //Convert the GLdoubles matrix in GLfloats for (int i=0; i<16; ++i) - mvp_mat[i] = GLfloat(plouf[i]); + mvp_mat[i] = GLfloat(d_mvp_mat[i]); + if(isInit!=1) From 7edebec70e3d5a2edb019f6fb67f74e19a048c04 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Feb 2015 13:02:27 +0100 Subject: [PATCH 04/62] Light update I now set the light properties in the Scene class constructor and pass them to the shader in the polygon_soup render function --- Polyhedron/demo/Polyhedron/Scene.cpp | 15 ++++ .../Polyhedron/Scene_polygon_soup_item.cpp | 76 +++++++++++-------- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 1a68ee6efb9..b0b803caf63 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -212,6 +212,21 @@ void Scene::initializeGL() { #ifdef CGAL_GLEW_ENABLED ms_splatting->init(); + + //Setting the light options + + // Create light components + GLfloat ambientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; + GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + GLfloat position[] = { 3.0f, 2.0f, 1.0f, 1.0f }; + + // Assign created components to GL_LIGHT0 + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); + glLightfv(GL_LIGHT0, GL_POSITION, position); + #endif } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index af8967208cd..c251ca76d2c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -32,7 +32,7 @@ std::vector normals(0); GLuint rendering_program; GLuint vertex_array_object; int isInit = 0; -GLint location[2]; +GLint location[6]; GLfloat *mvp_mat; GLfloat *mv_mat; @@ -46,26 +46,17 @@ GLuint buffer[3]; struct light_info { //position - GLfloat pos_x; - GLfloat pos_y; - GLfloat pos_z; - GLfloat alpha; + GLfloat position[4]; //ambient - GLfloat amb_x; - GLfloat amb_y; - GLfloat amb_z; - GLfloat amb_alpha; + GLfloat ambient[4]; + //diffuse - GLfloat diff_x; - GLfloat diff_y; - GLfloat diff_z; - GLfloat diff_alpha; + GLfloat diffuse[4]; + //specular - GLfloat spec_x; - GLfloat spec_y; - GLfloat spec_z; - GLfloat spec_alpha; + GLfloat specular[4]; + GLfloat spec_power; }; light_info light; @@ -119,11 +110,11 @@ GLuint compile_shaders(void) "uniform mat4 mv_matrix; \n" - " vec3 light_pos = vec3(0.0,0.0,1.0); \n" - " vec3 light_diff = vColors; \n" - " vec3 light_spec = vec3(0.2,0.2,0.2); \n" - " vec3 light_amb = vec3(0.1,0.1,0.1); \n" - " float spec_power = 0.128; \n" + " uniform vec3 light_pos; \n" + " uniform vec3 light_diff; \n" + " uniform vec3 light_spec; \n" + " uniform vec3 light_amb; \n" + " float spec_power = 0.0; \n" "out highp vec3 fColors; \n" "out highp vec3 fNormals; \n" @@ -238,14 +229,26 @@ void render() // tells the GPU to use the program just created glUseProgram(rendering_program); - //Allocates a uniform location for the MVP matrix + //Allocates a uniform location for the MVP and MV matrices location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); - //Set the ModelViewProjection matrix + //Allocates a uniform location for the light values + location[2] = glGetUniformLocation(rendering_program, "light_pos"); + location[3] = glGetUniformLocation(rendering_program, "light_diff"); + location[4] = glGetUniformLocation(rendering_program, "light_spec"); + location[5] = glGetUniformLocation(rendering_program, "light_amb"); + + //Set the ModelViewProjection and ModelView matrices 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); + isInit = 1; //draw the polygons // the third argument is the number of vec4 that will be entered @@ -305,12 +308,25 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() glewInit(); mvp_mat = new GLfloat[16]; mv_mat = new GLfloat[16]; - //gets the lighting info - GLfloat result[4]; - glGetLightfv(GL_LIGHT0, GL_POSITION, result); - light.pos_x=result[0];light.pos_y=result[1];light.pos_z=result[2];light.alpha=result[3]; - glGetLightfv(GL_LIGHT0, GL_AMBIENT, result); - light.amb_x=result[0];light.amb_y=result[1];light.amb_z=result[2];light.amb_alpha=result[3]; + + + //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); + + std::cout<<"position : "< Date: Thu, 19 Feb 2015 15:09:40 +0100 Subject: [PATCH 05/62] draw_edges fix For now the function draw_edges is the same than draw() but the color is twice darker. --- Polyhedron/demo/Polyhedron/Scene.cpp | 7 +- .../Polyhedron/Scene_polygon_soup_item.cpp | 167 +++++++++--------- 2 files changed, 90 insertions(+), 84 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index b0b803caf63..10ce339ebd2 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -22,6 +22,7 @@ #include #include + namespace { void CGALglcolor(QColor c) { @@ -216,10 +217,10 @@ void Scene::initializeGL() //Setting the light options // Create light components - GLfloat ambientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - GLfloat position[] = { 3.0f, 2.0f, 1.0f, 1.0f }; + GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; // Assign created components to GL_LIGHT0 glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); @@ -338,6 +339,8 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) else CGALglcolor(item.color().lighter(50)); + + if(viewer) item.draw_edges(viewer); else diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index c251ca76d2c..418f29c1677 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -26,22 +26,21 @@ std::vector positions_poly(0); std::vector positions_lines(0); std::vector positions_points(0); -std::vector colors(0); std::vector normals(0); GLuint rendering_program; GLuint vertex_array_object; int isInit = 0; -GLint location[6]; +GLint location[7]; GLfloat *mvp_mat; GLfloat *mv_mat; - +GLfloat colors[3]; GLuint vertex_shader; GLuint fragment_shader; GLuint program; GLuint vao; -GLuint buffer[3]; +GLuint buffer[2]; struct light_info { @@ -82,21 +81,12 @@ GLuint compile_shaders(void) ); glEnableVertexAttribArray(0); - - //Bind the second and initialize it glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glBufferData(GL_ARRAY_BUFFER, (colors.size())*sizeof(colors.data()), colors.data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); - //Bind the second and initialize it - glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); - glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_STATIC_DRAW); - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(2); - - //fill the vertex shader static const GLchar* vertex_shader_source[] = @@ -104,17 +94,15 @@ GLuint compile_shaders(void) "#version 300 es \n" " \n" "layout (location = 0) in vec4 positions_poly; \n" - "layout (location = 1) in vec3 vColors; \n" - "layout (location = 2) in vec3 vNormals; \n" + "layout (location = 1) in vec3 vNormals; \n" "uniform mat4 mvp_matrix; \n" - "uniform mat4 mv_matrix; \n" - - " uniform vec3 light_pos; \n" - " uniform vec3 light_diff; \n" - " uniform vec3 light_spec; \n" - " uniform vec3 light_amb; \n" - " float spec_power = 0.0; \n" + "uniform vec3 vColors; \n" + "uniform vec3 light_pos; \n" + "uniform vec3 light_diff; \n" + "uniform vec3 light_spec; \n" + "uniform vec3 light_amb; \n" + "float spec_power = 0.0; \n" "out highp vec3 fColors; \n" "out highp vec3 fNormals; \n" @@ -238,6 +226,7 @@ void render() location[3] = glGetUniformLocation(rendering_program, "light_diff"); location[4] = glGetUniformLocation(rendering_program, "light_spec"); location[5] = glGetUniformLocation(rendering_program, "light_amb"); + location[6] = glGetUniformLocation(rendering_program, "vColors"); //Set the ModelViewProjection and ModelView matrices glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); @@ -248,6 +237,7 @@ void render() glUniform3fv(location[3], 1, light.diffuse); glUniform3fv(location[4], 1, light.specular); glUniform3fv(location[5], 1, light.ambient); + glUniform3fv(location[6], 1, colors); isInit = 1; //draw the polygons @@ -309,25 +299,7 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() mvp_mat = new GLfloat[16]; mv_mat = new GLfloat[16]; - - //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); - - std::cout<<"position : "<color().redF()); - colors.push_back(this->color().greenF()); - colors.push_back(this->color().blueF()); normals.push_back(n.x()); normals.push_back(n.y()); normals.push_back(n.z()); - colors.push_back(this->color().redF()); - colors.push_back(this->color().greenF()); - colors.push_back(this->color().blueF()); + 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()); - colors.push_back(this->color().redF()); - colors.push_back(this->color().greenF()); - colors.push_back(this->color().blueF()); for(size_type i = 0; i < it->size(); ++i) { const Point_3& p = soup->points[it->at(i)]; - positions_poly.push_back(p.x()); positions_poly.push_back(p.y()); positions_poly.push_back(p.z()); positions_poly.push_back(1.0); - - } - } if(soup->display_non_manifold_edges) { @@ -567,11 +524,6 @@ Scene_polygon_soup_item::draw() const { { const Point_3& a = soup->points[edge[0]]; const Point_3& b = soup->points[edge[1]]; - - // ::glBegin(GL_LINES); - // ::glVertex3d(a.x(), a.y(), a.z()); - // ::glVertex3d(b.x(), b.y(), b.z()); - // ::glEnd(); positions_lines.push_back(a.x()); positions_lines.push_back(a.y()); positions_lines.push_back(a.y()); @@ -584,8 +536,8 @@ Scene_polygon_soup_item::draw() const { if(lightning) glEnable(GL_LIGHTING); // ::glColor4dv(current_color); } - } + render(); } @@ -599,6 +551,68 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { GLdouble d_mvp_mat[16]; viewer->camera()->getModelViewProjectionMatrix(d_mvp_mat); viewer->camera()->getModelViewMatrix(mv_mat); + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + + //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]; + + //Convert the GLdoubles matrix in GLfloats + for (int i=0; i<16; ++i) + mvp_mat[i] = GLfloat(d_mvp_mat[i]); + + draw(); +} +void +Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const +{ + typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; + typedef Polygon_soup::Polygons::size_type size_type; + + //Remplit la matrice MVP + GLdouble d_mvp_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mvp_mat); + viewer->camera()->getModelViewMatrix(mv_mat); + colors[0] = this->color().redF()/2.0; + colors[1] = this->color().greenF()/2.0; + colors[2] = this->color().blueF()/2.0; + + //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]; + //Convert the GLdoubles matrix in GLfloats for (int i=0; i<16; ++i) mvp_mat[i] = GLfloat(d_mvp_mat[i]); @@ -623,25 +637,15 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { normals.push_back(n.y()); normals.push_back(n.z()); - colors.push_back(this->color().redF()); - colors.push_back(this->color().greenF()); - colors.push_back(this->color().blueF()); + 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()); - colors.push_back(this->color().redF()); - colors.push_back(this->color().greenF()); - colors.push_back(this->color().blueF()); - - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); - - colors.push_back(this->color().redF()); - colors.push_back(this->color().greenF()); - colors.push_back(this->color().blueF()); for(size_type i = 0; i < it->size(); ++i) { @@ -691,7 +695,6 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { render(); } - void Scene_polygon_soup_item::draw_points() const { From 415d3cc44df99e25523d0f9e85dc9d4c57dceef6 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Feb 2015 15:42:52 +0100 Subject: [PATCH 06/62] color fix Instead of taking the color information on the object in the draw function, I get the current color value, and I don't need the draw_edges function anymore. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 122 +----------------- 1 file changed, 3 insertions(+), 119 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 418f29c1677..66d0e24795b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -34,7 +34,7 @@ int isInit = 0; GLint location[7]; GLfloat *mvp_mat; GLfloat *mv_mat; -GLfloat colors[3]; +GLfloat colors[4]; GLuint vertex_shader; GLuint fragment_shader; @@ -471,7 +471,7 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw() const { - std::cout<<"Erreur de Draw"<camera()->getModelViewProjectionMatrix(d_mvp_mat); viewer->camera()->getModelViewMatrix(mv_mat); - colors[0] = this->color().redF(); - colors[1] = this->color().greenF(); - colors[2] = this->color().blueF(); + glGetFloatv(GL_CURRENT_COLOR, colors ); //position glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); @@ -580,121 +578,7 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { draw(); } -void -Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const -{ - typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; - typedef Polygon_soup::Polygons::size_type size_type; - //Remplit la matrice MVP - GLdouble d_mvp_mat[16]; - viewer->camera()->getModelViewProjectionMatrix(d_mvp_mat); - viewer->camera()->getModelViewMatrix(mv_mat); - colors[0] = this->color().redF()/2.0; - colors[1] = this->color().greenF()/2.0; - colors[2] = this->color().blueF()/2.0; - - //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]; - - //Convert the GLdoubles matrix in GLfloats - for (int i=0; i<16; ++i) - mvp_mat[i] = GLfloat(d_mvp_mat[i]); - - - - if(isInit!=1) - { - for(Polygons_iterator it = soup->polygons.begin(); - it != soup->polygons.end(); ++it) - { - - const Point_3& pa = soup->points[it->at(0)]; - const Point_3& pb = soup->points[it->at(1)]; - const Point_3& pc = soup->points[it->at(2)]; - - Kernel::Vector_3 n = CGAL::cross_product(pb-pa, pc -pa); - n = n / std::sqrt(n * n); - // ::glBegin(GL_POLYGON); - //::glNormal3d(n.x(),n.y(),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()); - - - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); - - - for(size_type i = 0; i < it->size(); ++i) - { - const Point_3& p = soup->points[it->at(i)]; - - positions_poly.push_back(p.x()); - positions_poly.push_back(p.y()); - positions_poly.push_back(p.z()); - positions_poly.push_back(1.0); - - - } - - } - - if(soup->display_non_manifold_edges) { - double current_color[4]; - GLboolean lightning; - ::glGetDoublev(GL_CURRENT_COLOR, current_color); - //::glColor3d(1., 0., 0.); // red - ::glGetBooleanv(GL_LIGHTING, &lightning); - ::glDisable(GL_LIGHTING); - - BOOST_FOREACH(const Polygon_soup::Edge& edge, - soup->non_manifold_edges) - { - const Point_3& a = soup->points[edge[0]]; - const Point_3& b = soup->points[edge[1]]; - - // ::glBegin(GL_LINES); - // ::glVertex3d(a.x(), a.y(), a.z()); - // ::glVertex3d(b.x(), b.y(), b.z()); - // ::glEnd(); - positions_lines.push_back(a.x()); - positions_lines.push_back(a.y()); - positions_lines.push_back(a.y()); - - positions_lines.push_back(b.x()); - positions_lines.push_back(b.y()); - positions_lines.push_back(b.y()); - - } - if(lightning) glEnable(GL_LIGHTING); - // ::glColor4dv(current_color); - } - } - - render(); -} void Scene_polygon_soup_item::draw_points() const { From 991b697af6f0a329a1399720ad281510471009a1 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 08:25:46 +0100 Subject: [PATCH 07/62] Color Change fix I forgot to uncomment the glUseProgram(0) at the end of render(). --- Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 66d0e24795b..413b3b79ed6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -243,7 +243,8 @@ void render() //draw the polygons // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); -//glUseProgram(0); + //Tells OpenGL not to use the program anymore + glUseProgram(0); } struct Polyhedron_to_polygon_soup_writer { @@ -299,7 +300,7 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() mvp_mat = new GLfloat[16]; mv_mat = new GLfloat[16]; - } +} Scene_polygon_soup_item::~Scene_polygon_soup_item() { From e833e28605e6f6712ba2167c657bfeb5778ee8b4 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 09:00:41 +0100 Subject: [PATCH 08/62] Design update No more isInit, the recovery of normals and vertices is now done in the load function. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 287 +++++++++--------- .../demo/Polyhedron/Scene_polygon_soup_item.h | 1 + 2 files changed, 142 insertions(+), 146 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 413b3b79ed6..c04ab2eba78 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -30,7 +30,6 @@ std::vector normals(0); GLuint rendering_program; GLuint vertex_array_object; -int isInit = 0; GLint location[7]; GLfloat *mvp_mat; GLfloat *mv_mat; @@ -58,7 +57,50 @@ struct light_info GLfloat spec_power; }; +struct Polyhedron_to_polygon_soup_writer { + typedef Kernel::Point_3 Point_3; + + Polygon_soup* soup; + Polygon_soup::Polygon_3 polygon; + + Polyhedron_to_polygon_soup_writer(Polygon_soup* soup) : soup(soup), polygon() { + } + + void write_header( std::ostream&, + std::size_t /* vertices */, + std::size_t /* halfedges */, + std::size_t /* facets */, + bool /* normals */ = false ) { + soup->clear(); + } + + void write_footer() { + } + + void write_vertex( const double& x, const double& y, const double& z) { + soup->points.push_back(Point_3(x, y, z)); + } + + void write_normal( const double& /* x */, const double& /* y */, const double& /* z */) { + } + + void write_facet_header() { + } + + void write_facet_begin( std::size_t no) { + polygon.clear(); + polygon.reserve(no); + } + void write_facet_vertex_index( std::size_t index) { + polygon.push_back(index); + } + void write_facet_end() { + soup->polygons.push_back(polygon); + polygon.clear(); + } +}; // end struct Polyhedron_to_soup_writer light_info light; + GLuint compile_shaders(void) { @@ -203,93 +245,75 @@ GLuint compile_shaders(void) glDeleteShader(fragment_shader); return program; } +void +Scene_polygon_soup_item::compute_normals_and_vertices(){ + //get the vertices and normals + typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; + typedef Polygon_soup::Polygons::size_type size_type; + for(Polygons_iterator it = soup->polygons.begin(); + it != soup->polygons.end(); ++it) + { -//The rendering function -void render() -{ - if(isInit !=1) - rendering_program = compile_shaders(); + const Point_3& pa = soup->points[it->at(0)]; + const Point_3& pb = soup->points[it->at(1)]; + const Point_3& pc = soup->points[it->at(2)]; - const GLfloat color[] = { 0.9f, 0.9f, 0.9f, 1.0f }; - if(isInit !=1) - glClearBufferfv(GL_COLOR, 0, color); + Kernel::Vector_3 n = CGAL::cross_product(pb-pa, pc -pa); + n = n / std::sqrt(n * n); - // tells the GPU to use the program just created - glUseProgram(rendering_program); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); - //Allocates a uniform location for the MVP and MV matrices - location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); - location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); - //Allocates a uniform location for the light values - location[2] = glGetUniformLocation(rendering_program, "light_pos"); - location[3] = glGetUniformLocation(rendering_program, "light_diff"); - location[4] = glGetUniformLocation(rendering_program, "light_spec"); - location[5] = glGetUniformLocation(rendering_program, "light_amb"); - location[6] = glGetUniformLocation(rendering_program, "vColors"); - //Set the ModelViewProjection and ModelView matrices - glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); - glUniformMatrix4fv(location[1], 1, GL_FALSE, mv_mat); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); - //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); - glUniform3fv(location[6], 1, colors); - isInit = 1; - //draw the polygons - // the third argument is the number of vec4 that will be entered - glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); - //Tells OpenGL not to use the program anymore - glUseProgram(0); + for(size_type i = 0; i < it->size(); ++i) + { + const Point_3& p = soup->points[it->at(i)]; + positions_poly.push_back(p.x()); + positions_poly.push_back(p.y()); + positions_poly.push_back(p.z()); + positions_poly.push_back(1.0); + } + } + + if(soup->display_non_manifold_edges) { + double current_color[4]; + GLboolean lightning; + ::glGetDoublev(GL_CURRENT_COLOR, current_color); + //::glColor3d(1., 0., 0.); // red + ::glGetBooleanv(GL_LIGHTING, &lightning); + ::glDisable(GL_LIGHTING); + + BOOST_FOREACH(const Polygon_soup::Edge& edge, + soup->non_manifold_edges) + { + const Point_3& a = soup->points[edge[0]]; + const Point_3& b = soup->points[edge[1]]; + positions_lines.push_back(a.x()); + positions_lines.push_back(a.y()); + positions_lines.push_back(a.y()); + + positions_lines.push_back(b.x()); + positions_lines.push_back(b.y()); + positions_lines.push_back(b.y()); + + } + if(lightning) glEnable(GL_LIGHTING); + // ::glColor4dv(current_color); + } + + rendering_program = compile_shaders(); } -struct Polyhedron_to_polygon_soup_writer { - typedef Kernel::Point_3 Point_3; - - Polygon_soup* soup; - Polygon_soup::Polygon_3 polygon; - - Polyhedron_to_polygon_soup_writer(Polygon_soup* soup) : soup(soup), polygon() { - } - - void write_header( std::ostream&, - std::size_t /* vertices */, - std::size_t /* halfedges */, - std::size_t /* facets */, - bool /* normals */ = false ) { - soup->clear(); - } - - void write_footer() { - } - - void write_vertex( const double& x, const double& y, const double& z) { - soup->points.push_back(Point_3(x, y, z)); - } - - void write_normal( const double& /* x */, const double& /* y */, const double& /* z */) { - } - - void write_facet_header() { - } - - void write_facet_begin( std::size_t no) { - polygon.clear(); - polygon.reserve(no); - } - void write_facet_vertex_index( std::size_t index) { - polygon.push_back(index); - } - void write_facet_end() { - soup->polygons.push_back(polygon); - polygon.clear(); - } -}; // end struct Polyhedron_to_soup_writer - Scene_polygon_soup_item::Scene_polygon_soup_item() : Scene_item(), @@ -325,7 +349,10 @@ Scene_polygon_soup_item::load(std::istream& in) { if (!soup) soup=new Polygon_soup(); else soup->clear(); - return CGAL::read_OFF(in, soup->points, soup->polygons); + + bool result = CGAL::read_OFF(in, soup->points, soup->polygons); + compute_normals_and_vertices(); + return result; } void Scene_polygon_soup_item::init_polygon_soup(std::size_t nb_pts, std::size_t nb_polygons){ @@ -473,73 +500,38 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw() const { - typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; - typedef Polygon_soup::Polygons::size_type size_type; - if(isInit!=1) - { - for(Polygons_iterator it = soup->polygons.begin(); - it != soup->polygons.end(); ++it) - { - - const Point_3& pa = soup->points[it->at(0)]; - const Point_3& pb = soup->points[it->at(1)]; - const Point_3& pc = soup->points[it->at(2)]; - - Kernel::Vector_3 n = CGAL::cross_product(pb-pa, pc -pa); - n = n / std::sqrt(n * n); - - 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()); + // tells the GPU to use the program just created + glUseProgram(rendering_program); + //Allocates a uniform location for the MVP and MV matrices + location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); - for(size_type i = 0; i < it->size(); ++i) - { - const Point_3& p = soup->points[it->at(i)]; - positions_poly.push_back(p.x()); - positions_poly.push_back(p.y()); - positions_poly.push_back(p.z()); - positions_poly.push_back(1.0); - } - } + //Allocates a uniform location for the light values + location[2] = glGetUniformLocation(rendering_program, "light_pos"); + location[3] = glGetUniformLocation(rendering_program, "light_diff"); + location[4] = glGetUniformLocation(rendering_program, "light_spec"); + location[5] = glGetUniformLocation(rendering_program, "light_amb"); + location[6] = glGetUniformLocation(rendering_program, "vColors"); - if(soup->display_non_manifold_edges) { - double current_color[4]; - GLboolean lightning; - ::glGetDoublev(GL_CURRENT_COLOR, current_color); - //::glColor3d(1., 0., 0.); // red - ::glGetBooleanv(GL_LIGHTING, &lightning); - ::glDisable(GL_LIGHTING); + //Set the ModelViewProjection and ModelView matrices + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[1], 1, GL_FALSE, mv_mat); - BOOST_FOREACH(const Polygon_soup::Edge& edge, - soup->non_manifold_edges) - { - const Point_3& a = soup->points[edge[0]]; - const Point_3& b = soup->points[edge[1]]; - positions_lines.push_back(a.x()); - positions_lines.push_back(a.y()); - positions_lines.push_back(a.y()); + //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); + glUniform3fv(location[6], 1, colors); - positions_lines.push_back(b.x()); - positions_lines.push_back(b.y()); - positions_lines.push_back(b.y()); - - } - if(lightning) glEnable(GL_LIGHTING); - // ::glColor4dv(current_color); - } - } - - render(); + //draw the polygons + // the third argument is the number of vec4 that will be entered + glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); + //Tells OpenGL not to use the program anymore + glUseProgram(0); } void @@ -549,9 +541,16 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { typedef Polygon_soup::Polygons::size_type size_type; //Remplit la matrice MVP - GLdouble d_mvp_mat[16]; - viewer->camera()->getModelViewProjectionMatrix(d_mvp_mat); - viewer->camera()->getModelViewMatrix(mv_mat); + 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]); + glGetFloatv(GL_CURRENT_COLOR, colors ); //position @@ -573,10 +572,6 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { light.diffuse[1]*=colors[1]; light.diffuse[2]*=colors[2]; - //Convert the GLdoubles matrix in GLfloats - for (int i=0; i<16; ++i) - mvp_mat[i] = GLfloat(d_mvp_mat[i]); - draw(); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index ad955db8270..6335da57c81 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -163,6 +163,7 @@ public slots: private: Polygon_soup* soup; bool oriented; + void compute_normals_and_vertices(); }; // end class Scene_polygon_soup_item #endif // SCENE_POLYGON_SOUP_ITEM_H From e5707a756f5999a565eb486b412db4f9fb889ec5 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 11:51:23 +0100 Subject: [PATCH 09/62] points mode implementation Now you can use the points view. --- Polyhedron/demo/Polyhedron/Scene.cpp | 4 +- .../Polyhedron/Scene_polygon_soup_item.cpp | 111 +++++++++++++----- .../demo/Polyhedron/Scene_polygon_soup_item.h | 1 + 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 10ce339ebd2..b6e47d4e76e 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -272,6 +272,7 @@ Scene::drawWithNames(Viewer_interface* viewer) void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { + // Flat/Gouraud OpenGL drawing for(int index = 0; index < m_entries.size(); ++index) { @@ -284,7 +285,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) { ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); ::glPointSize(2.f); ::glLineWidth(1.0f); if(index == selected_item) @@ -302,6 +303,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) << " with_name = " << std::boolalpha << with_names << std::endl; } + if(viewer) item.draw(viewer); else diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index c04ab2eba78..6b9b7ac4e6d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -245,6 +245,32 @@ GLuint compile_shaders(void) glDeleteShader(fragment_shader); return program; } + +void uniform_attrib() +{ + //Allocates a uniform location for the MVP and MV matrices + location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); + + //Allocates a uniform location for the light values + location[2] = glGetUniformLocation(rendering_program, "light_pos"); + location[3] = glGetUniformLocation(rendering_program, "light_diff"); + location[4] = glGetUniformLocation(rendering_program, "light_spec"); + location[5] = glGetUniformLocation(rendering_program, "light_amb"); + location[6] = glGetUniformLocation(rendering_program, "vColors"); + + //Set the ModelViewProjection and ModelView matrices + 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); + glUniform3fv(location[6], 1, colors); +} + void Scene_polygon_soup_item::compute_normals_and_vertices(){ //get the vertices and normals @@ -499,34 +525,9 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw() const { - - - // tells the GPU to use the program just created glUseProgram(rendering_program); - - //Allocates a uniform location for the MVP and MV matrices - location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); - location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); - - //Allocates a uniform location for the light values - location[2] = glGetUniformLocation(rendering_program, "light_pos"); - location[3] = glGetUniformLocation(rendering_program, "light_diff"); - location[4] = glGetUniformLocation(rendering_program, "light_spec"); - location[5] = glGetUniformLocation(rendering_program, "light_amb"); - location[6] = glGetUniformLocation(rendering_program, "vColors"); - - //Set the ModelViewProjection and ModelView matrices - 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); - glUniform3fv(location[6], 1, colors); - + uniform_attrib(); //draw the polygons // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); @@ -537,9 +538,9 @@ Scene_polygon_soup_item::draw() const { void Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { - typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; + /* typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; typedef Polygon_soup::Polygons::size_type size_type; - +*/ //Remplit la matrice MVP GLdouble d_mat[16]; viewer->camera()->getModelViewProjectionMatrix(d_mat); @@ -581,19 +582,65 @@ Scene_polygon_soup_item::draw_points() const { if(soup == 0) return; //::glBegin(GL_POINTS); - for(Polygon_soup::Points::const_iterator pit = soup->points.begin(), + /* for(Polygon_soup::Points::const_iterator pit = soup->points.begin(), end = soup->points.end(); pit != end; ++pit) { - // ::glVertex3d(pit->x(), pit->y(), pit->z()); + ::glVertex3d(pit->x(), pit->y(), pit->z()); positions_points.push_back(pit->x()); positions_points.push_back(pit->y()); - positions_points.push_back(pit->y()); + positions_points.push_back(pit->z()); } - //::glEnd(); + //::glEnd();*/ + // tells the GPU to use the program just created + glUseProgram(rendering_program); + + uniform_attrib(); + + //draw the polygons + // the third argument is the number of vec4 that will be entered + glDrawArrays(GL_POINTS, 0, positions_poly.size()/4); + //Tells OpenGL not to use the program anymore + glUseProgram(0); } +void +Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { + //Remplit la matrice MVP + 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]); + + + glGetFloatv(GL_CURRENT_COLOR, colors ); + //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]; + + draw_points(); +} bool Scene_polygon_soup_item::isEmpty() const { diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 6335da57c81..70fd5267988 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -140,6 +140,7 @@ public: void draw() const; void draw(Viewer_interface*) const; void draw_points() const; + void draw_points(Viewer_interface*) const; bool isFinite() const { return true; } bool isEmpty() const; From 39811801e45b0f5eae615f85619ade986cacf2d6 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 12:23:41 +0100 Subject: [PATCH 10/62] Uniform allocation moved It is now made only once after the compile_shader. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 6b9b7ac4e6d..2b83744c520 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -248,16 +248,7 @@ GLuint compile_shaders(void) void uniform_attrib() { - //Allocates a uniform location for the MVP and MV matrices - location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); - location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); - //Allocates a uniform location for the light values - location[2] = glGetUniformLocation(rendering_program, "light_pos"); - location[3] = glGetUniformLocation(rendering_program, "light_diff"); - location[4] = glGetUniformLocation(rendering_program, "light_spec"); - location[5] = glGetUniformLocation(rendering_program, "light_amb"); - location[6] = glGetUniformLocation(rendering_program, "vColors"); //Set the ModelViewProjection and ModelView matrices glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); @@ -338,6 +329,16 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ } rendering_program = compile_shaders(); + //Allocates a uniform location for the MVP and MV matrices + location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); + + //Allocates a uniform location for the light values + location[2] = glGetUniformLocation(rendering_program, "light_pos"); + location[3] = glGetUniformLocation(rendering_program, "light_diff"); + location[4] = glGetUniformLocation(rendering_program, "light_spec"); + location[5] = glGetUniformLocation(rendering_program, "light_amb"); + location[6] = glGetUniformLocation(rendering_program, "vColors"); } From a5a5c744643ab888979b8f4bcd5c9e57c20ad84a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 12:31:55 +0100 Subject: [PATCH 11/62] Cleaned the code. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 76 +++++++++---------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 2b83744c520..f725b43f80b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -526,35 +526,12 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw() const { - // tells the GPU to use the program just created - glUseProgram(rendering_program); - uniform_attrib(); - //draw the polygons - // the third argument is the number of vec4 that will be entered - glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); - //Tells OpenGL not to use the program anymore - glUseProgram(0); -} - -void -Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { - - /* typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; - typedef Polygon_soup::Polygons::size_type size_type; -*/ - //Remplit la matrice MVP - 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]); - + //fills the arraw of colors with the current color glGetFloatv(GL_CURRENT_COLOR, colors ); + + //Gets lighting info : + //position glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); @@ -574,6 +551,33 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { light.diffuse[1]*=colors[1]; light.diffuse[2]*=colors[2]; + // tells the GPU to use the program just created + glUseProgram(rendering_program); + uniform_attrib(); + //draw the polygons + // the third argument is the number of vec4 that will be entered + glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); + //Tells OpenGL not to use the program anymore + glUseProgram(0); +} + +void +Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { + + + //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]); + + draw(); } @@ -582,33 +586,21 @@ Scene_polygon_soup_item::draw_points() const { if(soup == 0) return; - //::glBegin(GL_POINTS); - /* for(Polygon_soup::Points::const_iterator pit = soup->points.begin(), - end = soup->points.end(); - pit != end; ++pit) - { - ::glVertex3d(pit->x(), pit->y(), pit->z()); - positions_points.push_back(pit->x()); - positions_points.push_back(pit->y()); - positions_points.push_back(pit->z()); - } - //::glEnd();*/ // tells the GPU to use the program just created glUseProgram(rendering_program); uniform_attrib(); - //draw the polygons - // the third argument is the number of vec4 that will be entered - glDrawArrays(GL_POINTS, 0, positions_poly.size()/4); + //draw the points + glDrawArrays(GL_POINTS, 0, positions_poly.size()); //Tells OpenGL not to use the program anymore glUseProgram(0); } void Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { - //Remplit la matrice MVP + //fills the MVP Matrix GLdouble d_mat[16]; viewer->camera()->getModelViewProjectionMatrix(d_mat); //Convert the GLdoubles matrix in GLfloats From 8c94b8810a3c461ff7e05b768692914fc22990e8 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 20 Feb 2015 13:02:18 +0100 Subject: [PATCH 12/62] Add data files --- .../demo/Polyhedron/data/cube-shuffled.off | 47 + .../demo/Polyhedron/data/cube4-shuffled.off | 41 + .../demo/Polyhedron/data/oblong-shuffled.off | 1291 +++++++++++++++++ 3 files changed, 1379 insertions(+) create mode 100644 Polyhedron/demo/Polyhedron/data/cube-shuffled.off create mode 100644 Polyhedron/demo/Polyhedron/data/cube4-shuffled.off create mode 100644 Polyhedron/demo/Polyhedron/data/oblong-shuffled.off diff --git a/Polyhedron/demo/Polyhedron/data/cube-shuffled.off b/Polyhedron/demo/Polyhedron/data/cube-shuffled.off new file mode 100644 index 00000000000..dee198272cf --- /dev/null +++ b/Polyhedron/demo/Polyhedron/data/cube-shuffled.off @@ -0,0 +1,47 @@ +# Output of a CGAL tool +#CBP +# polyhedral_surface 0 +# halfedges 0 +# triangulated 0 +# non_empty_facets 0 +# terrain 0 +# normalized_to_sphere 0 +# radius 0 +# rounded 0 +# rounded_bits 0 +# ENDCBP + +OFF +8 12 0 + +# 8 vertices +# ------------------------------------------ + + +-1 -1 -1 +-1 1 -1 +1 1 -1 +1 -1 -1 +-1 -1 1 +-1 1 1 +1 1 1 +1 -1 1 + +# 12 facets +# ------------------------------------------ + +3 3 1 0 +3 3 1 2 +3 1 4 0 +3 1 4 5 +3 3 2 7 +3 7 2 6 +3 3 0 4 +3 7 4 3 +3 7 4 6 +3 6 5 4 +3 6 5 1 +3 2 1 6 + + +# End of OFF # diff --git a/Polyhedron/demo/Polyhedron/data/cube4-shuffled.off b/Polyhedron/demo/Polyhedron/data/cube4-shuffled.off new file mode 100644 index 00000000000..e4c11b5fe03 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/data/cube4-shuffled.off @@ -0,0 +1,41 @@ +# Output of a CGAL tool +#CBP +# polyhedral_surface 0 +# halfedges 0 +# triangulated 0 +# non_empty_facets 0 +# terrain 0 +# normalized_to_sphere 0 +# radius 0 +# rounded 0 +# rounded_bits 0 +# ENDCBP + +OFF +8 6 0 + +# 8 vertices +# ------------------------------------------ + + +-1 -1 -1 +-1 1 -1 +1 1 -1 +1 -1 -1 +-1 -1 1 +-1 1 1 +1 1 1 +1 -1 1 + +# 6 facets +# ------------------------------------------ + +4 1 2 3 0 +4 0 1 5 4 +4 2 6 7 3 +4 3 7 4 0 +4 6 5 4 7 +4 6 2 1 5 + + +# End of OFF # diff --git a/Polyhedron/demo/Polyhedron/data/oblong-shuffled.off b/Polyhedron/demo/Polyhedron/data/oblong-shuffled.off new file mode 100644 index 00000000000..9027280ffb7 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/data/oblong-shuffled.off @@ -0,0 +1,1291 @@ +# Output of a CGAL tool +#CBP +# polyhedral_surface 0 +# halfedges 0 +# triangulated 0 +# non_empty_facets 0 +# terrain 0 +# normalized_to_sphere 0 +# radius 0 +# rounded 0 +# rounded_bits 0 +# ENDCBP + +OFF +424 840 0 + +# 424 vertices +# ------------------------------------------ + + +68.7865 31.8449 54 +68.99 29 54 +78 52 54 +57.3041 47.1835 54 +59.8074 45.8167 54 +0 58 54 +0 6 54 +4 6 54 +4 0 54 +27.99 0 54 +27.99 6 54 +29 48.99 54 +49 48.99 54 +50 52 54 +51.8449 48.7865 54 +54.6318 48.1803 54 +62.0907 44.1074 54 +64.1074 42.0907 54 +65.8167 39.8074 54 +54.6318 9.81973 54 +51.8449 9.21347 54 +50.0065 6 54 +49 9.01 54 +68.1803 23.3682 54 +67.1835 20.6959 54 +78 6 54 +65.8167 18.1926 54 +74 6 54 +64.1074 15.9093 54 +74 0 54 +62.0907 13.8926 54 +59.8074 12.1833 54 +68.7865 26.1551 54 +67.1835 37.3041 54 +68.1803 34.6318 54 +9.81974 34.6318 54 +10.8165 37.3041 54 +23.3682 48.1803 54 +26.1551 48.7865 54 +50.0065 0 54 +57.3041 10.8165 54 +9.21347 31.8449 54 +50 58 54 +23.3682 9.81973 54 +26.1551 9.21347 54 +29 9.01 54 +20.6959 10.8165 54 +18.1926 12.1833 54 +15.9093 13.8926 54 +13.8926 15.9093 54 +12.1833 18.1926 54 +10.8165 20.6959 54 +12.1833 39.8074 54 +13.8926 42.0907 54 +15.9093 44.1074 54 +9.81974 23.3682 54 +9.21347 26.1551 54 +9.01 29 54 +18.1926 45.8167 54 +20.6959 47.1835 54 +50.0065 0 0 +74 0 0 +0 58 0 +0 6 0 +4 0 0 +27.99 0 0 +78 6 0 +78 52 0 +50 58 0 +17.9479 46.6482 0 +17 46.2062 0 +16.1433 45.6063 0 +15.4037 44.8667 0 +14.8039 44.01 0 +14.3618 43.0621 0 +74 6 0 +50.0065 6 0 +50 52 0 +20 47.01 0 +18.9581 46.9188 0 +14.3618 14.9379 0 +14.8039 13.99 0 +4 6 0 +15.4037 13.1333 0 +16.1433 12.3937 0 +17 11.7938 0 +14.0912 42.0519 0 +14 41.01 0 +14 16.99 0 +14.0912 15.9481 0 +63.1962 13.99 0 +63.6382 14.9379 0 +63.9088 15.9481 0 +78 6 0 +64 16.99 0 +78 52 0 +64 41.01 0 +63.9088 42.0519 0 +63.6382 43.0621 0 +63.1962 44.01 0 +17.9479 11.3518 0 +27.99 6 0 +60.0521 11.3518 0 +61 11.7938 0 +62.5963 44.8667 0 +61.8567 45.6063 0 +61 46.2062 0 +60.0521 46.6482 0 +59.0419 46.9188 0 +58 47.01 0 +61.8567 12.3937 0 +62.5963 13.1333 0 +18.9581 11.0812 0 +20 10.99 0 +58 10.99 0 +59.0419 11.0812 0 +64 41.01 3 +64 16.99 3 +20 47.01 3 +58 47.01 3 +14 41.01 3 +14 16.99 3 +58 10.99 3 +20 10.99 3 +19.3 31.9445 3 +18.8145 31.6045 3 +22.7 26.0555 3 +56.4791 31.9544 3 +22.1629 25.805 3 +21.5904 25.6516 3 +23.9445 27.3 3 +24.195 27.8371 3 +24.3484 28.4096 3 +55.9739 31.8191 3 +55.5 31.5981 3 +55.0716 31.2981 3 +54.1809 30.0261 3 +54.0456 29.5209 3 +18.3955 31.1855 3 +18.0555 30.7 3 +17.805 30.1629 3 +23.1855 26.3955 3 +23.6045 26.8145 3 +54.7019 30.9284 3 +54.4019 30.5 3 +59.2981 27.0716 3 +59.5981 27.5 3 +24.4 29 3 +24.3484 29.5904 3 +57 32 3 +24.195 30.1629 3 +17.6517 29.5904 3 +17.6 29 3 +17.6517 28.4096 3 +17.805 27.8371 3 +18.0555 27.3 3 +18.3955 26.8145 3 +59.8191 27.9739 3 +59.9544 28.4791 3 +60 29 3 +59.9544 29.5209 3 +59.8191 30.0261 3 +59.5981 30.5 3 +59.2981 30.9284 3 +57.521 31.9544 3 +60.0521 46.6482 3 +59.0419 46.9188 3 +23.9445 30.7 3 +23.6045 31.1855 3 +54 29 3 +54.0456 28.4791 3 +54.1809 27.9739 3 +58.9284 31.2981 3 +58.5 31.5981 3 +63.9088 42.0519 3 +58.0261 31.8191 3 +63.6382 43.0621 3 +63.1962 44.01 3 +62.5963 44.8667 3 +61.8567 45.6063 3 +61 46.2062 3 +23.1855 31.6045 3 +22.7 31.9445 3 +22.1629 32.195 3 +21.5904 32.3484 3 +21 32.4 3 +18.9581 46.9188 3 +20.4096 32.3484 3 +17.9479 46.6482 3 +18.8145 26.3955 3 +19.3 26.0555 3 +14.0912 15.9481 3 +19.8371 25.805 3 +14.3618 14.9379 3 +14.8039 13.99 3 +15.4037 13.1333 3 +16.1433 12.3937 3 +20.4096 25.6516 3 +21 25.6 3 +17.9479 11.3518 3 +17 11.7938 3 +55.9739 26.1809 3 +55.5 26.4019 3 +55.0716 26.7019 3 +17 46.2062 3 +16.1433 45.6063 3 +15.4037 44.8667 3 +19.8371 32.195 3 +14.8039 44.01 3 +14.3618 43.0621 3 +14.0912 42.0519 3 +18.9581 11.0812 3 +54.4019 27.5 3 +54.7019 27.0716 3 +58.0261 26.1809 3 +62.5963 13.1333 3 +57.521 26.0456 3 +61.8567 12.3937 3 +56.4791 26.0456 3 +57 26 3 +59.0419 11.0812 3 +60.0521 11.3518 3 +61 11.7938 3 +63.1962 13.99 3 +63.6382 14.9379 3 +63.9088 15.9481 3 +58.5 26.4019 3 +58.9284 26.7019 3 +17.6517 29.5904 26.25 +17.805 30.1629 26.25 +18.0555 30.7 26.25 +18.3955 31.1855 26.25 +18.8145 31.6045 26.25 +19.3 31.9445 26.25 +19.8371 32.195 26.25 +20.4096 32.3484 26.25 +21 32.4 26.25 +21.5904 32.3484 26.25 +22.1629 32.195 26.25 +22.7 31.9445 26.25 +23.1855 31.6045 26.25 +23.6045 31.1855 26.25 +23.9445 30.7 26.25 +24.195 30.1629 26.25 +24.3484 29.5904 26.25 +24.4 29 26.25 +24.3484 28.4096 26.25 +24.195 27.8371 26.25 +23.9445 27.3 26.25 +23.6045 26.8145 26.25 +23.1855 26.3955 26.25 +22.7 26.0555 26.25 +22.1629 25.805 26.25 +21.5904 25.6516 26.25 +21 25.6 26.25 +20.4096 25.6516 26.25 +19.8371 25.805 26.25 +19.3 26.0555 26.25 +18.8145 26.3955 26.25 +18.3955 26.8145 26.25 +18.0555 27.3 26.25 +17.805 27.8371 26.25 +17.6517 28.4096 26.25 +17.6 29 26.25 +21 29 28.2929 +54.0456 29.5209 29 +54.1809 30.0261 29 +54.4019 30.5 29 +54.7019 30.9284 29 +55.0716 31.2981 29 +55.5 31.5981 29 +55.9739 31.8191 29 +56.4791 31.9544 29 +57 32 29 +57.521 31.9544 29 +58.0261 31.8191 29 +58.5 31.5981 29 +58.9284 31.2981 29 +59.2981 30.9284 29 +59.5981 30.5 29 +59.8191 30.0261 29 +59.9544 29.5209 29 +60 29 29 +59.9544 28.4791 29 +59.8191 27.9739 29 +59.5981 27.5 29 +59.2981 27.0716 29 +58.9284 26.7019 29 +58.5 26.4019 29 +58.0261 26.1809 29 +57.521 26.0456 29 +57 26 29 +56.4791 26.0456 29 +55.9739 26.1809 29 +55.5 26.4019 29 +55.0716 26.7019 29 +54.7019 27.0716 29 +54.4019 27.5 29 +54.1809 27.9739 29 +54.0456 28.4791 29 +54 29 29 +57 29 30.8026 +29 9.01 58 +26.1551 9.21347 58 +23.3682 9.81973 58 +20.6959 10.8165 58 +18.1926 12.1833 58 +15.9093 13.8926 58 +13.8926 15.9093 58 +12.1833 18.1926 58 +10.8165 20.6959 58 +9.81974 23.3682 58 +9.21347 26.1551 58 +9.01 29 58 +9.21347 31.8449 58 +9.81974 34.6318 58 +10.8165 37.3041 58 +12.1833 39.8074 58 +13.8926 42.0907 58 +15.9093 44.1074 58 +18.1926 45.8167 58 +20.6959 47.1835 58 +23.3682 48.1803 58 +26.1551 48.7865 58 +29 48.99 58 +49 9.01 58 +49 48.99 58 +51.8449 48.7865 58 +54.6318 48.1803 58 +57.3041 47.1835 58 +59.8074 45.8167 58 +62.0907 44.1074 58 +64.1074 42.0907 58 +65.8167 39.8074 58 +67.1835 37.3041 58 +68.1803 34.6318 58 +68.7865 31.8449 58 +68.99 29 58 +68.7865 26.1551 58 +68.1803 23.3682 58 +67.1835 20.6959 58 +65.8167 18.1926 58 +64.1074 15.9093 58 +62.0907 13.8926 58 +59.8074 12.1833 58 +57.3041 10.8165 58 +54.6318 9.81973 58 +51.8449 9.21347 58 +55.01 29 58 +54.7916 26.3648 58 +47.7566 15.597 58 +45.4311 14.3385 58 +54.7916 31.6352 58 +54.1425 34.1984 58 +53.0804 21.3801 58 +54.1425 23.8016 58 +53.0804 36.6199 58 +51.6341 38.8335 58 +49.8433 40.7789 58 +42.9302 13.4799 58 +40.3221 13.0447 58 +37.6779 13.0447 58 +35.0698 13.4799 58 +32.5689 14.3385 58 +30.2434 15.597 58 +28.1567 17.2211 58 +51.6341 19.1665 58 +49.8433 17.2211 58 +24.9196 21.3801 58 +26.3659 19.1665 58 +23.8575 23.8016 58 +22.99 29 58 +23.2083 31.6352 58 +30.2434 42.403 58 +32.5689 43.6615 58 +23.2083 26.3648 58 +35.0698 44.5201 58 +37.6779 44.9553 58 +40.3221 44.9553 58 +24.9196 36.6199 58 +23.8575 34.1984 58 +26.3659 38.8335 58 +28.1567 40.7789 58 +47.7566 42.403 58 +45.4311 43.6615 58 +42.9302 44.5201 58 +54.7916 31.6352 54 +54.1425 34.1984 54 +53.0804 36.6199 54 +51.6341 38.8335 54 +49.8433 40.7789 54 +47.7566 42.403 54 +45.4311 43.6615 54 +42.9302 44.5201 54 +40.3221 44.9553 54 +37.6779 44.9553 54 +35.0698 44.5201 54 +32.5689 43.6615 54 +30.2434 42.403 54 +28.1567 40.7789 54 +26.3659 38.8335 54 +24.9196 36.6199 54 +23.8575 34.1984 54 +23.2083 31.6352 54 +22.99 29 54 +23.2083 26.3648 54 +23.8575 23.8016 54 +24.9196 21.3801 54 +26.3659 19.1665 54 +28.1567 17.2211 54 +30.2434 15.597 54 +32.5689 14.3385 54 +35.0698 13.4799 54 +37.6779 13.0447 54 +40.3221 13.0447 54 +42.9302 13.4799 54 +45.4311 14.3385 54 +47.7566 15.597 54 +49.8433 17.2211 54 +51.6341 19.1665 54 +53.0804 21.3801 54 +54.1425 23.8016 54 +54.7916 26.3648 54 +55.01 29 54 + +# 840 facets +# ------------------------------------------ + +3 0 1 2 +3 2 4 3 +3 7 6 5 +3 8 9 7 +3 10 9 7 +3 11 12 13 +3 13 12 14 +3 2 14 13 +3 2 14 15 +3 2 15 3 +3 4 16 2 +3 2 16 17 +3 2 17 18 +3 19 20 21 +3 21 20 22 +3 21 22 10 +3 25 24 23 +3 25 24 26 +3 25 26 27 +3 28 26 27 +3 27 28 29 +3 29 28 30 +3 31 30 29 +3 2 1 25 +3 25 1 32 +3 23 32 25 +3 18 33 2 +3 34 33 2 +3 2 34 0 +3 5 36 35 +3 38 37 5 +3 19 39 21 +3 29 39 19 +3 40 29 19 +3 40 29 31 +3 35 5 41 +3 11 13 38 +3 38 13 42 +3 38 42 5 +3 44 7 43 +3 10 7 44 +3 45 10 44 +3 45 10 22 +3 43 46 7 +3 7 46 47 +3 48 47 7 +3 7 49 48 +3 50 49 7 +3 7 50 51 +3 36 52 5 +3 53 52 5 +3 5 53 54 +3 7 55 51 +3 7 55 56 +3 5 56 7 +3 5 56 57 +3 5 57 41 +3 54 58 5 +3 59 58 5 +3 37 59 5 +3 39 60 29 +3 61 60 29 +3 5 62 6 +3 63 62 6 +3 9 64 8 +3 65 64 9 +3 25 66 2 +3 2 66 67 +3 42 68 5 +3 62 68 5 +3 62 70 69 +3 71 70 62 +3 71 72 62 +3 62 72 73 +3 62 73 74 +3 75 60 61 +3 76 60 75 +3 78 77 68 +3 62 78 68 +3 62 78 79 +3 62 79 69 +3 80 81 82 +3 83 81 82 +3 64 83 82 +3 84 83 64 +3 85 84 64 +3 74 86 62 +3 62 86 87 +3 63 87 62 +3 63 87 88 +3 63 88 82 +3 82 88 89 +3 82 89 80 +3 75 91 90 +3 75 91 92 +3 75 92 93 +3 93 92 94 +3 95 94 93 +3 95 94 96 +3 95 97 96 +3 95 97 98 +3 95 98 99 +3 85 101 100 +3 65 101 85 +3 64 65 85 +3 75 103 102 +3 95 104 99 +3 105 104 95 +3 106 105 95 +3 106 107 95 +3 108 107 95 +3 95 108 77 +3 109 108 77 +3 78 109 77 +3 103 110 75 +3 111 110 75 +3 75 111 90 +3 100 112 101 +3 101 112 113 +3 101 113 76 +3 114 113 76 +3 75 114 76 +3 115 114 75 +3 102 115 75 +3 13 77 42 +3 68 77 42 +3 2 95 13 +3 77 95 13 +3 8 82 7 +3 64 82 8 +3 7 63 6 +3 7 63 82 +3 21 76 39 +3 39 76 60 +3 9 65 10 +3 101 65 10 +3 10 101 21 +3 76 101 21 +3 27 61 29 +3 27 61 75 +3 27 75 25 +3 93 75 25 +3 116 94 96 +3 116 94 117 +3 78 109 118 +3 119 109 118 +3 120 121 87 +3 88 121 87 +3 114 113 122 +3 123 113 122 +3 124 125 120 +3 126 127 128 +3 129 127 128 +3 130 131 127 +3 127 131 132 +3 127 133 129 +3 129 133 134 +3 129 134 135 +3 129 136 137 +3 120 138 125 +3 120 138 139 +3 140 139 120 +3 126 141 127 +3 127 141 142 +3 127 142 130 +3 135 143 129 +3 129 143 144 +3 136 144 129 +3 145 146 117 +3 132 147 127 +3 127 147 148 +3 149 148 127 +3 150 148 149 +3 140 151 120 +3 120 151 152 +3 120 152 121 +3 121 152 153 +3 121 154 153 +3 121 154 155 +3 156 155 121 +3 117 157 146 +3 158 157 117 +3 116 158 117 +3 159 158 116 +3 116 159 160 +3 160 161 116 +3 162 161 116 +3 116 162 163 +3 165 149 164 +3 165 149 150 +3 165 150 166 +3 167 150 166 +3 166 167 119 +3 168 167 119 +3 137 169 129 +3 170 169 129 +3 129 170 171 +3 116 172 163 +3 173 172 116 +3 174 173 116 +3 174 173 175 +3 174 175 176 +3 178 176 177 +3 178 176 175 +3 178 175 179 +3 179 175 164 +3 180 164 179 +3 165 164 180 +3 168 181 119 +3 119 181 182 +3 119 182 118 +3 118 182 183 +3 183 184 118 +3 118 184 185 +3 186 185 118 +3 186 185 187 +3 188 187 186 +3 121 189 156 +3 190 189 121 +3 121 190 191 +3 191 190 192 +3 191 192 193 +3 194 193 195 +3 195 193 192 +3 195 192 196 +3 197 192 196 +3 198 199 197 +3 197 199 200 +3 196 200 197 +3 202 122 201 +3 202 122 123 +3 202 123 203 +3 204 188 205 +3 187 188 205 +3 205 187 206 +3 207 187 206 +3 206 207 208 +3 208 207 124 +3 208 124 209 +3 209 124 120 +3 209 120 210 +3 199 129 198 +3 171 129 199 +3 211 171 199 +3 211 171 212 +3 123 212 211 +3 123 212 213 +3 123 213 203 +3 216 215 214 +3 216 215 217 +3 122 218 201 +3 219 218 122 +3 220 219 122 +3 220 219 216 +3 220 216 221 +3 217 216 221 +3 221 217 222 +3 224 215 223 +3 224 215 214 +3 224 214 225 +3 226 214 225 +3 117 226 225 +3 117 226 227 +3 145 227 117 +3 79 118 78 +3 186 118 79 +3 69 186 79 +3 188 186 69 +3 69 188 70 +3 70 188 204 +3 70 204 71 +3 205 204 71 +3 71 205 72 +3 72 205 206 +3 72 206 73 +3 208 206 73 +3 74 208 73 +3 209 208 74 +3 86 209 74 +3 210 209 86 +3 87 210 86 +3 120 210 87 +3 97 116 96 +3 174 116 97 +3 98 174 97 +3 98 174 176 +3 99 176 98 +3 99 176 177 +3 104 177 99 +3 104 177 178 +3 104 178 105 +3 179 178 105 +3 106 179 105 +3 180 179 106 +3 107 180 106 +3 165 180 107 +3 108 165 107 +3 108 165 166 +3 109 166 108 +3 109 166 119 +3 115 122 114 +3 115 122 220 +3 102 220 115 +3 221 220 102 +3 102 221 103 +3 103 221 222 +3 110 222 103 +3 110 222 217 +3 110 217 111 +3 215 217 111 +3 111 215 90 +3 90 215 223 +3 90 223 91 +3 224 223 91 +3 92 224 91 +3 92 224 225 +3 92 225 94 +3 117 225 94 +3 89 121 88 +3 89 121 191 +3 80 191 89 +3 80 191 193 +3 81 193 80 +3 194 193 81 +3 81 194 83 +3 195 194 83 +3 84 195 83 +3 84 195 196 +3 84 196 85 +3 85 196 200 +3 85 200 100 +3 199 200 100 +3 112 199 100 +3 112 199 211 +3 113 211 112 +3 113 211 123 +3 229 151 228 +3 140 151 229 +3 230 140 229 +3 230 140 139 +3 230 139 231 +3 138 139 231 +3 231 138 232 +3 125 138 232 +3 233 125 232 +3 233 125 124 +3 233 124 234 +3 234 124 207 +3 234 207 235 +3 235 207 187 +3 235 187 236 +3 236 187 185 +3 236 185 237 +3 237 185 184 +3 237 184 238 +3 183 184 238 +3 238 183 239 +3 182 183 239 +3 240 182 239 +3 240 182 181 +3 240 181 241 +3 241 181 168 +3 241 168 242 +3 242 168 167 +3 243 167 242 +3 243 167 150 +3 243 150 244 +3 148 150 244 +3 244 148 245 +3 245 148 147 +3 245 147 246 +3 132 147 246 +3 246 132 247 +3 131 132 247 +3 248 131 247 +3 248 131 130 +3 248 130 249 +3 249 130 142 +3 249 142 250 +3 250 142 141 +3 250 141 251 +3 126 141 251 +3 252 126 251 +3 128 126 252 +3 252 128 253 +3 129 128 253 +3 254 129 253 +3 198 129 254 +3 255 198 254 +3 197 198 255 +3 255 197 256 +3 256 197 192 +3 256 192 257 +3 190 192 257 +3 258 190 257 +3 258 190 189 +3 258 189 259 +3 259 189 156 +3 259 156 260 +3 260 156 155 +3 260 155 261 +3 261 155 154 +3 261 154 262 +3 153 154 262 +3 262 153 263 +3 152 153 263 +3 228 152 263 +3 228 152 151 +3 263 228 264 +3 232 264 231 +3 264 230 229 +3 234 264 235 +3 232 233 264 +3 237 264 238 +3 264 236 235 +3 240 264 241 +3 264 239 238 +3 244 264 243 +3 264 242 241 +3 246 264 247 +3 244 245 264 +3 249 264 250 +3 247 248 264 +3 253 264 252 +3 264 251 250 +3 255 264 256 +3 264 254 253 +3 258 264 259 +3 256 257 264 +3 261 264 262 +3 259 260 264 +3 264 263 262 +3 264 260 261 +3 258 257 264 +3 264 254 255 +3 252 251 264 +3 249 248 264 +3 264 245 246 +3 264 242 243 +3 240 239 264 +3 237 236 264 +3 264 233 234 +3 231 230 264 +3 264 228 229 +3 266 137 265 +3 266 137 136 +3 266 136 267 +3 144 136 267 +3 268 144 267 +3 268 144 143 +3 268 143 269 +3 269 143 135 +3 269 135 270 +3 134 135 270 +3 271 134 270 +3 133 134 271 +3 272 133 271 +3 272 133 127 +3 273 127 272 +3 149 127 273 +3 273 149 274 +3 274 149 164 +3 275 164 274 +3 175 164 275 +3 275 175 276 +3 276 175 173 +3 277 173 276 +3 172 173 277 +3 278 172 277 +3 163 172 278 +3 279 163 278 +3 162 163 279 +3 279 162 280 +3 161 162 280 +3 280 161 281 +3 281 161 160 +3 281 160 282 +3 159 160 282 +3 283 159 282 +3 283 159 158 +3 284 158 283 +3 284 158 157 +3 284 157 285 +3 285 157 146 +3 285 146 286 +3 286 146 145 +3 286 145 287 +3 227 145 287 +3 288 227 287 +3 288 227 226 +3 289 226 288 +3 289 226 214 +3 290 214 289 +3 216 214 290 +3 290 216 291 +3 219 216 291 +3 292 219 291 +3 218 219 292 +3 293 218 292 +3 201 218 293 +3 294 201 293 +3 202 201 294 +3 294 202 295 +3 295 202 203 +3 296 203 295 +3 213 203 296 +3 296 213 297 +3 212 213 297 +3 297 212 298 +3 298 212 171 +3 298 171 299 +3 299 171 170 +3 300 170 299 +3 169 170 300 +3 265 169 300 +3 265 169 137 +3 301 265 300 +3 268 301 269 +3 266 267 301 +3 271 301 272 +3 269 270 301 +3 275 301 274 +3 301 273 272 +3 277 301 278 +3 301 276 275 +3 281 301 280 +3 301 279 278 +3 283 301 284 +3 281 282 301 +3 286 301 287 +3 301 285 284 +3 290 301 289 +3 301 288 287 +3 293 301 292 +3 290 291 301 +3 295 301 296 +3 301 294 293 +3 298 301 299 +3 301 297 296 +3 299 300 301 +3 301 297 298 +3 295 294 301 +3 292 291 301 +3 301 288 289 +3 286 285 301 +3 283 282 301 +3 280 279 301 +3 277 276 301 +3 274 273 301 +3 271 270 301 +3 301 267 268 +3 266 265 301 +3 45 302 44 +3 44 302 303 +3 43 303 44 +3 43 303 304 +3 46 304 43 +3 305 304 46 +3 46 305 47 +3 306 305 47 +3 48 306 47 +3 307 306 48 +3 48 307 49 +3 308 307 49 +3 49 308 50 +3 309 308 50 +3 51 309 50 +3 51 309 310 +3 55 310 51 +3 55 310 311 +3 56 311 55 +3 56 311 312 +3 56 312 57 +3 313 312 57 +3 41 313 57 +3 41 313 314 +3 41 314 35 +3 35 314 315 +3 36 315 35 +3 36 315 316 +3 36 316 52 +3 52 316 317 +3 52 317 53 +3 318 317 53 +3 54 318 53 +3 54 318 319 +3 58 319 54 +3 320 319 58 +3 58 320 59 +3 59 320 321 +3 37 321 59 +3 37 321 322 +3 37 322 38 +3 323 322 38 +3 38 323 11 +3 11 323 324 +3 22 302 325 +3 45 302 22 +3 14 326 12 +3 14 326 327 +3 14 327 15 +3 15 327 328 +3 3 328 15 +3 329 328 3 +3 3 329 4 +3 4 329 330 +3 4 330 16 +3 331 330 16 +3 17 331 16 +3 17 331 332 +3 18 332 17 +3 18 332 333 +3 33 333 18 +3 33 333 334 +3 33 334 34 +3 335 334 34 +3 34 335 0 +3 0 335 336 +3 0 336 1 +3 337 336 1 +3 1 337 32 +3 32 337 338 +3 23 338 32 +3 339 338 23 +3 23 339 24 +3 24 339 340 +3 24 340 26 +3 341 340 26 +3 26 341 28 +3 342 341 28 +3 28 342 30 +3 343 342 30 +3 30 343 31 +3 31 343 344 +3 40 344 31 +3 345 344 40 +3 19 345 40 +3 346 345 19 +3 19 346 20 +3 347 346 20 +3 20 347 22 +3 22 347 325 +3 324 326 11 +3 12 326 11 +3 349 348 338 +3 350 351 325 +3 348 337 338 +3 348 337 336 +3 352 336 348 +3 352 336 335 +3 353 335 352 +3 354 341 355 +3 355 341 340 +3 349 340 355 +3 339 340 349 +3 338 339 349 +3 356 331 357 +3 357 331 330 +3 358 330 357 +3 335 334 353 +3 353 334 333 +3 353 333 356 +3 356 333 332 +3 331 332 356 +3 351 359 325 +3 360 359 325 +3 325 360 302 +3 302 360 361 +3 302 362 361 +3 363 362 302 +3 303 363 302 +3 303 363 364 +3 303 364 304 +3 304 364 365 +3 366 343 354 +3 354 343 342 +3 341 342 354 +3 350 347 325 +3 350 347 346 +3 350 346 367 +3 367 346 345 +3 367 345 366 +3 344 345 366 +3 343 344 366 +3 368 307 369 +3 306 307 369 +3 369 306 365 +3 305 306 365 +3 304 305 365 +3 370 309 368 +3 368 309 308 +3 368 308 307 +3 314 371 372 +3 373 374 324 +3 371 313 314 +3 312 313 371 +3 371 312 375 +3 375 312 311 +3 375 311 370 +3 370 311 310 +3 370 310 309 +3 374 376 324 +3 377 376 324 +3 326 377 324 +3 326 377 378 +3 380 317 379 +3 380 317 316 +3 380 316 372 +3 315 316 372 +3 314 315 372 +3 379 319 381 +3 379 319 318 +3 379 318 317 +3 324 323 373 +3 322 323 373 +3 382 322 373 +3 382 322 321 +3 382 321 381 +3 381 321 320 +3 381 320 319 +3 358 329 330 +3 328 329 358 +3 358 328 383 +3 383 328 327 +3 383 327 384 +3 384 327 326 +3 384 326 385 +3 378 326 385 +3 387 352 386 +3 387 352 353 +3 387 353 388 +3 388 353 356 +3 389 356 388 +3 357 356 389 +3 389 357 390 +3 390 357 358 +3 391 358 390 +3 383 358 391 +3 391 383 392 +3 384 383 392 +3 392 384 393 +3 393 384 385 +3 393 385 394 +3 378 385 394 +3 395 378 394 +3 395 378 377 +3 395 377 396 +3 376 377 396 +3 397 376 396 +3 374 376 397 +3 397 374 398 +3 398 374 373 +3 399 373 398 +3 382 373 399 +3 400 382 399 +3 381 382 400 +3 400 381 401 +3 379 381 401 +3 402 379 401 +3 402 379 380 +3 402 380 403 +3 372 380 403 +3 404 372 403 +3 404 372 371 +3 405 371 404 +3 405 371 375 +3 405 375 406 +3 370 375 406 +3 407 370 406 +3 368 370 407 +3 408 368 407 +3 408 368 369 +3 408 369 409 +3 409 369 365 +3 409 365 410 +3 364 365 410 +3 410 364 411 +3 363 364 411 +3 412 363 411 +3 412 363 362 +3 413 362 412 +3 413 362 361 +3 414 361 413 +3 414 361 360 +3 415 360 414 +3 415 360 359 +3 415 359 416 +3 416 359 351 +3 416 351 417 +3 417 351 350 +3 417 350 418 +3 367 350 418 +3 418 367 419 +3 419 367 366 +3 419 366 420 +3 420 366 354 +3 420 354 421 +3 355 354 421 +3 421 355 422 +3 422 355 349 +3 423 349 422 +3 423 349 348 +3 386 348 423 +3 352 348 386 +3 392 393 394 +3 411 412 413 +3 419 418 417 +3 410 409 397 +3 394 414 413 +3 415 414 394 +3 394 415 416 +3 397 411 410 +3 397 411 413 +3 396 413 397 +3 396 413 394 +3 396 394 395 +3 398 399 397 +3 405 399 397 +3 408 409 407 +3 397 409 407 +3 406 397 407 +3 405 397 406 +3 405 400 399 +3 405 400 401 +3 405 401 404 +3 404 401 402 +3 404 402 403 +3 419 388 387 +3 389 388 419 +3 390 389 419 +3 419 420 387 +3 421 420 387 +3 386 421 387 +3 386 421 422 +3 423 422 386 +3 416 417 394 +3 394 417 419 +3 392 419 394 +3 392 419 390 +3 392 390 391 + + +# End of OFF # From 7110d40e76bcf37a3bbe6d6d03e48921b364b3ec Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 14:24:18 +0100 Subject: [PATCH 13/62] Design update All the global variables are now member, buffers are deleted and the function changed() is implemented. --- Polyhedron/demo/Polyhedron/Scene.cpp | 1182 +++++++++-------- .../Polyhedron/Scene_polygon_soup_item.cpp | 102 +- .../demo/Polyhedron/Scene_polygon_soup_item.h | 23 +- 3 files changed, 637 insertions(+), 670 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index b6e47d4e76e..b81137790cd 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -24,10 +24,10 @@ namespace { - void CGALglcolor(QColor c) - { +void CGALglcolor(QColor c) +{ ::glColor4d(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); - } +} } #ifdef CGAL_GLEW_ENABLED @@ -35,157 +35,157 @@ GlSplat::SplatRenderer* Scene::ms_splatting = 0; int Scene::ms_splattingCounter = 0; GlSplat::SplatRenderer* Scene::splatting() { - assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); - return ms_splatting; + assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); + return ms_splatting; } #endif Scene::Scene(QObject* parent) - : QAbstractListModel(parent), - selected_item(-1), - item_A(-1), - item_B(-1) + : QAbstractListModel(parent), + selected_item(-1), + item_A(-1), + item_B(-1) { - connect(this, SIGNAL(selectionRay(double, double, double, - double, double, double)), - this, SLOT(setSelectionRay(double, double, double, - double, double, double))); + connect(this, SIGNAL(selectionRay(double, double, double, + double, double, double)), + this, SLOT(setSelectionRay(double, double, double, + double, double, double))); #ifdef CGAL_GLEW_ENABLED - if(ms_splatting==0) - ms_splatting = new GlSplat::SplatRenderer(); - ms_splattingCounter++; + if(ms_splatting==0) + ms_splatting = new GlSplat::SplatRenderer(); + ms_splattingCounter++; #endif } Scene::Item_id Scene::addItem(Scene_item* item) { - Bbox bbox_before = bbox(); - m_entries.push_back(item); - connect(item, SIGNAL(itemChanged()), - this, SLOT(itemChanged())); - if(bbox_before + item->bbox() != bbox_before) - { emit updated_bbox(); } - emit updated(); - QAbstractListModel::reset(); - Item_id id = m_entries.size() - 1; - emit newItem(id); - return id; + Bbox bbox_before = bbox(); + m_entries.push_back(item); + connect(item, SIGNAL(itemChanged()), + this, SLOT(itemChanged())); + if(bbox_before + item->bbox() != bbox_before) + { emit updated_bbox(); } + emit updated(); + QAbstractListModel::reset(); + Item_id id = m_entries.size() - 1; + emit newItem(id); + return id; } Scene_item* Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_to_be_destroyed) { - if(index < 0 || index >= m_entries.size()) - return 0; + if(index < 0 || index >= m_entries.size()) + return 0; - if(emit_item_about_to_be_destroyed) { - emit itemAboutToBeDestroyed(m_entries[index]); - } + if(emit_item_about_to_be_destroyed) { + emit itemAboutToBeDestroyed(m_entries[index]); + } - connect(item, SIGNAL(itemChanged()), - this, SLOT(itemChanged())); - std::swap(m_entries[index], item); + connect(item, SIGNAL(itemChanged()), + this, SLOT(itemChanged())); + std::swap(m_entries[index], item); - if ( item->isFinite() && !item->isEmpty() && - m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && - item->bbox()!=m_entries[index]->bbox() ) - { - emit updated_bbox(); - } - emit updated(); - itemChanged(index); - // QAbstractListModel::reset(); - return item; + if ( item->isFinite() && !item->isEmpty() && + m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && + item->bbox()!=m_entries[index]->bbox() ) + { + emit updated_bbox(); + } + emit updated(); + itemChanged(index); + // QAbstractListModel::reset(); + return item; } int Scene::erase(int index) { - if(index < 0 || index >= m_entries.size()) + if(index < 0 || index >= m_entries.size()) + return -1; + + Scene_item* item = m_entries[index]; + emit itemAboutToBeDestroyed(item); + delete item; + m_entries.removeAt(index); + + selected_item = -1; + emit updated(); + QAbstractListModel::reset(); + + if(--index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; return -1; - - Scene_item* item = m_entries[index]; - emit itemAboutToBeDestroyed(item); - delete item; - m_entries.removeAt(index); - - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); - - if(--index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; - return -1; } int Scene::erase(QList indices) { - QList to_be_removed; + QList to_be_removed; - int max_index = -1; - Q_FOREACH(int index, indices) { - if(index < 0 || index >= m_entries.size()) - continue; - max_index = (std::max)(max_index, index); - Scene_item* item = m_entries[index]; - to_be_removed.push_back(item); - emit itemAboutToBeDestroyed(item); - delete item; - } + int max_index = -1; + Q_FOREACH(int index, indices) { + if(index < 0 || index >= m_entries.size()) + continue; + max_index = (std::max)(max_index, index); + Scene_item* item = m_entries[index]; + to_be_removed.push_back(item); + emit itemAboutToBeDestroyed(item); + delete item; + } - Q_FOREACH(Scene_item* item, to_be_removed) { - m_entries.removeAll(item); - } + Q_FOREACH(Scene_item* item, to_be_removed) { + m_entries.removeAll(item); + } - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); + selected_item = -1; + emit updated(); + QAbstractListModel::reset(); - int index = max_index + 1 - indices.size(); - if(index >= m_entries.size()) { - index = m_entries.size() - 1; - } - if(index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; - return -1; + int index = max_index + 1 - indices.size(); + if(index >= m_entries.size()) { + index = m_entries.size() - 1; + } + if(index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; + return -1; } Scene::~Scene() { - Q_FOREACH(Scene_item* item_ptr, m_entries) - { - delete item_ptr; - } - m_entries.clear(); + Q_FOREACH(Scene_item* item_ptr, m_entries) + { + delete item_ptr; + } + m_entries.clear(); #ifdef CGAL_GLEW_ENABLED - if((--ms_splattingCounter)==0) - delete ms_splatting; + if((--ms_splattingCounter)==0) + delete ms_splatting; #endif } Scene_item* Scene::item(Item_id index) const { - return m_entries.value(index); // QList::value checks bounds + return m_entries.value(index); // QList::value checks bounds } Scene::Item_id Scene::item_id(Scene_item* scene_item) const { - return m_entries.indexOf(scene_item); + return m_entries.indexOf(scene_item); } int Scene::numberOfEntries() const { - return m_entries.size(); + return m_entries.size(); } // Duplicate a scene item. @@ -193,40 +193,40 @@ Scene::numberOfEntries() const Scene::Item_id Scene::duplicate(Item_id index) { - if(index < 0 || index >= m_entries.size()) - return -1; + if(index < 0 || index >= m_entries.size()) + return -1; - const Scene_item* item = m_entries[index]; - Scene_item* new_item = item->clone(); - if(new_item) { - new_item->setName(tr("%1 (copy)").arg(item->name())); - new_item->setColor(item->color()); - new_item->setVisible(item->visible()); - addItem(new_item); - return m_entries.size() - 1; - } - else - return -1; + const Scene_item* item = m_entries[index]; + Scene_item* new_item = item->clone(); + if(new_item) { + new_item->setName(tr("%1 (copy)").arg(item->name())); + new_item->setColor(item->color()); + new_item->setVisible(item->visible()); + addItem(new_item); + return m_entries.size() - 1; + } + else + return -1; } void Scene::initializeGL() { #ifdef CGAL_GLEW_ENABLED - ms_splatting->init(); + ms_splatting->init(); - //Setting the light options + //Setting the light options - // Create light components - GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; - GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; - GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; + // Create light components + GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; + GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; - // Assign created components to GL_LIGHT0 - glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); - glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); - glLightfv(GL_LIGHT0, GL_POSITION, position); + // Assign created components to GL_LIGHT0 + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); + glLightfv(GL_LIGHT0, GL_POSITION, position); #endif } @@ -238,191 +238,193 @@ void Scene::initializeGL() bool Scene::keyPressEvent(QKeyEvent* e){ - bool res=false; - for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); - it!=endit;++it) - { - Scene_item* item=m_entries[*it]; - res |= item->keyPressEvent(e); - } - return res; + bool res=false; + for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); + it!=endit;++it) + { + Scene_item* item=m_entries[*it]; + res |= item->keyPressEvent(e); + } + return res; } void Scene::draw() { - draw_aux(false, 0); + draw_aux(false, 0); } void Scene::draw(Viewer_interface* viewer) { - draw_aux(false, viewer); + draw_aux(false, viewer); } void Scene::drawWithNames() { - draw_aux(true, 0); + draw_aux(true, 0); } void Scene::drawWithNames(Viewer_interface* viewer) { - draw_aux(true, viewer); + draw_aux(true, viewer); } void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { - // Flat/Gouraud OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *m_entries[index]; - if(item.visible()) + // Flat/Gouraud OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) { - if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - if(item.renderingMode() == Gouraud) - ::glShadeModel(GL_SMOOTH); - else - ::glShadeModel(GL_FLAT); - - if(CGAL::check_gl_error(__FILE__, __LINE__)) { - std::cerr << "GL error was before the drawing of the item \"" - << qPrintable(item.name()) << "\"\n" - << " with_name = " << std::boolalpha << with_names - << std::endl; + if(with_names) { + ::glPushName(index); } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) + { + ::glEnable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(item.color().lighter(120)); + else + CGALglcolor(item.color()); + if(item.renderingMode() == Gouraud) + ::glShadeModel(GL_SMOOTH); + else + ::glShadeModel(GL_FLAT); - if(viewer) - item.draw(viewer); - else - item.draw(); - if(CGAL::check_gl_error(__FILE__, __LINE__)) { - std::cerr << "GL error was after the drawing of the item \"" - << qPrintable(item.name()) << "\"\n" - << " with_name = " << std::boolalpha << with_names - << std::endl; + if(CGAL::check_gl_error(__FILE__, __LINE__)) { + std::cerr << "GL error was before the drawing of the item \"" + << qPrintable(item.name()) << "\"\n" + << " with_name = " << std::boolalpha << with_names + << std::endl; + } + item.changed(); + if(viewer) + item.draw(viewer); + else + item.draw(); + if(CGAL::check_gl_error(__FILE__, __LINE__)) { + std::cerr << "GL error was after the drawing of the item \"" + << qPrintable(item.name()) << "\"\n" + << " with_name = " << std::boolalpha << with_names + << std::endl; + } + } + } + if(with_names) { + ::glPopName(); } - } } - if(with_names) { - ::glPopName(); - } - } - // Wireframe OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *m_entries[index]; - if(item.visible()) + // Wireframe OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) { - if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(Qt::black); - else - CGALglcolor(item.color().lighter(50)); - - - - if(viewer) - item.draw_edges(viewer); - else - item.draw_edges(); - } - else{ - if( item.renderingMode() == PointsPlusNormals ){ - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - if(viewer) - item.draw_edges(viewer); - else - item.draw_edges(); + if(with_names) { + ::glPushName(index); } - } - } - if(with_names) { - ::glPopName(); - } - } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) + { + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(Qt::black); + else + CGALglcolor(item.color().lighter(50)); - // Points OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); + item.changed(); + + if(viewer) + item.draw_edges(viewer); + else + item.draw_edges(); + } + else{ + if( item.renderingMode() == PointsPlusNormals ){ + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(item.color().lighter(120)); + else + CGALglcolor(item.color()); + item.changed(); + if(viewer) + item.draw_edges(viewer); + else + item.draw_edges(); + } + } + } + if(with_names) { + ::glPopName(); + } } - Scene_item& item = *m_entries[index]; - if(item.visible()) + + // Points OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) { - if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - CGALglcolor(item.color()); + if(with_names) { + ::glPushName(index); + } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) + { + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + CGALglcolor(item.color()); - if(viewer) - item.draw_points(viewer); - else - item.draw_points(); - } + item.changed(); + if(viewer) + item.draw_points(viewer); + else + item.draw_points(); + } + } + if(with_names) { + ::glPopName(); + } } - if(with_names) { - ::glPopName(); - } - } #ifdef CGAL_GLEW_ENABLED - // Splatting - if(!with_names && ms_splatting->isSupported()) - { - ms_splatting->beginVisibilityPass(); - for(int index = 0; index < m_entries.size(); ++index) + // Splatting + if(!with_names && ms_splatting->isSupported()) { - Scene_item& item = *m_entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - item.draw_splats(); - } + ms_splatting->beginVisibilityPass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + item.draw_splats(); + } + } + ms_splatting->beginAttributePass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + CGALglcolor(item.color()); + item.draw_splats(); + } + } + ms_splatting->finalize(); } - ms_splatting->beginAttributePass(); - for(int index = 0; index < m_entries.size(); ++index) - { - Scene_item& item = *m_entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - CGALglcolor(item.color()); - item.draw_splats(); - } - } - ms_splatting->finalize(); - } #endif } @@ -433,360 +435,360 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) int Scene::rowCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else - return m_entries.size(); + if (parent.isValid()) + return 0; + else + return m_entries.size(); } int Scene::columnCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else - return NumberOfColumns; + if (parent.isValid()) + return 0; + else + return NumberOfColumns; } QVariant Scene::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); - if(index.row() < 0 || index.row() >= m_entries.size()) - return QVariant(); + if(index.row() < 0 || index.row() >= m_entries.size()) + return QVariant(); - if(role == ::Qt::ToolTipRole) - { - return m_entries[index.row()]->toolTip(); - } - switch(index.column()) - { - case ColorColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->color(); - else if(role == ::Qt::DecorationRole) - return m_entries.value(index.row())->color(); - break; - case NameColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->name(); - if(role == ::Qt::FontRole) - return m_entries.value(index.row())->font(); - break; - case RenderingModeColumn: - if(role == ::Qt::DisplayRole) { - return m_entries.value(index.row())->renderingModeName(); + if(role == ::Qt::ToolTipRole) + { + return m_entries[index.row()]->toolTip(); } - else if(role == ::Qt::EditRole) { - return static_cast(m_entries.value(index.row())->renderingMode()); + switch(index.column()) + { + case ColorColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->color(); + else if(role == ::Qt::DecorationRole) + return m_entries.value(index.row())->color(); + break; + case NameColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->name(); + if(role == ::Qt::FontRole) + return m_entries.value(index.row())->font(); + break; + case RenderingModeColumn: + if(role == ::Qt::DisplayRole) { + return m_entries.value(index.row())->renderingModeName(); + } + else if(role == ::Qt::EditRole) { + return static_cast(m_entries.value(index.row())->renderingMode()); + } + else if(role == ::Qt::TextAlignmentRole) { + return ::Qt::AlignCenter; + } + break; + case ABColumn: + if(role == ::Qt::DisplayRole) { + if(index.row() == item_A) + return "A"; + if(index.row() == item_B) + return "B"; + } + else if(role == ::Qt::TextAlignmentRole) { + return ::Qt::AlignCenter; + } + break; + case VisibleColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->visible(); + break; + default: + return QVariant(); } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case ABColumn: - if(role == ::Qt::DisplayRole) { - if(index.row() == item_A) - return "A"; - if(index.row() == item_B) - return "B"; - } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case VisibleColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->visible(); - break; - default: return QVariant(); - } - return QVariant(); } QVariant Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const { - if(orientation == ::Qt::Horizontal) { - if (role == ::Qt::DisplayRole) - { - switch(section) - { - case NameColumn: - return tr("Name"); - break; - case ColorColumn: - return tr("Color"); - break; - case RenderingModeColumn: - return tr("Mode"); - case ABColumn: - return tr("A/B"); - break; - case VisibleColumn: - return tr("View"); - break; - default: - return QVariant(); - } + if(orientation == ::Qt::Horizontal) { + if (role == ::Qt::DisplayRole) + { + switch(section) + { + case NameColumn: + return tr("Name"); + break; + case ColorColumn: + return tr("Color"); + break; + case RenderingModeColumn: + return tr("Mode"); + case ABColumn: + return tr("A/B"); + break; + case VisibleColumn: + return tr("View"); + break; + default: + return QVariant(); + } + } + else if(role == ::Qt::ToolTipRole) { + if(section == RenderingModeColumn) { + return tr("Rendering mode (points/wireframe/flat/flat+edges/Gouraud)"); + } + else if(section == ABColumn) { + return tr("Selection A/Selection B"); + } + } } - else if(role == ::Qt::ToolTipRole) { - if(section == RenderingModeColumn) { - return tr("Rendering mode (points/wireframe/flat/flat+edges/Gouraud)"); - } - else if(section == ABColumn) { - return tr("Selection A/Selection B"); - } - } - } - return QAbstractListModel::headerData(section, orientation, role); + return QAbstractListModel::headerData(section, orientation, role); } Qt::ItemFlags Scene::flags ( const QModelIndex & index ) const { - if (index.isValid() && index.column() == NameColumn) { - return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; - } - else { - return QAbstractListModel::flags(index); - } + if (index.isValid() && index.column() == NameColumn) { + return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; + } + else { + return QAbstractListModel::flags(index); + } } bool Scene::setData(const QModelIndex &index, - const QVariant &value, - int role) + const QVariant &value, + int role) { - if( role != ::Qt::EditRole || !index.isValid() ) - return false; + if( role != ::Qt::EditRole || !index.isValid() ) + return false; - if(index.row() < 0 || index.row() >= m_entries.size()) - return false; + if(index.row() < 0 || index.row() >= m_entries.size()) + return false; - Scene_item* item = m_entries[index.row()]; - if(!item) return false; - switch(index.column()) - { - case NameColumn: - item->setName(value.toString()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case ColorColumn: - item->setColor(value.value()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case RenderingModeColumn: - { - RenderingMode rendering_mode = static_cast(value.toInt()); - // Find next supported rendering mode - while ( ! item->supportsRenderingMode(rendering_mode) -#ifdef CGAL_GLEW_ENABLED - || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) -#endif - ) + Scene_item* item = m_entries[index.row()]; + if(!item) return false; + switch(index.column()) { - rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); + case NameColumn: + item->setName(value.toString()); + item->changed(); + emit dataChanged(index, index); + return true; + break; + case ColorColumn: + item->setColor(value.value()); + item->changed(); + emit dataChanged(index, index); + return true; + break; + case RenderingModeColumn: + { + RenderingMode rendering_mode = static_cast(value.toInt()); + // Find next supported rendering mode + while ( ! item->supportsRenderingMode(rendering_mode) + #ifdef CGAL_GLEW_ENABLED + || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) + #endif + ) + { + rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); + } + item->setRenderingMode(rendering_mode); + item->changed(); + emit dataChanged(index, index); + return true; + break; + } + case VisibleColumn: + item->setVisible(value.toBool()); + item->changed(); + emit dataChanged(index, index); + return true; + default: + return false; } - item->setRenderingMode(rendering_mode); - item->changed(); - emit dataChanged(index, index); - return true; - break; - } - case VisibleColumn: - item->setVisible(value.toBool()); - item->changed(); - emit dataChanged(index, index); - return true; - default: return false; - } - return false; } Scene::Item_id Scene::mainSelectionIndex() const { - return selected_item; + return selected_item; } QList Scene::selectionIndices() const { - return selected_items_list; + return selected_items_list; } int Scene::selectionAindex() const { - return item_A; + return item_A; } int Scene::selectionBindex() const { - return item_B; + return item_B; } QItemSelection Scene::createSelection(int i) { - return QItemSelection(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + return QItemSelection(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } QItemSelection Scene::createSelectionAll() { - return QItemSelection(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1 , LastColumn)); + return QItemSelection(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1 , LastColumn)); } void Scene::itemChanged() { - Scene_item* item = qobject_cast(sender()); - if(item) - itemChanged(item); + Scene_item* item = qobject_cast(sender()); + if(item) + itemChanged(item); } void Scene::itemChanged(Item_id i) { - if(i < 0 || i >= m_entries.size()) - return; + if(i < 0 || i >= m_entries.size()) + return; - m_entries[i]->changed(); - emit dataChanged(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + m_entries[i]->changed(); + emit dataChanged(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } void Scene::itemChanged(Scene_item* item) { - item->changed(); - emit dataChanged(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1, LastColumn)); + item->changed(); + emit dataChanged(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1, LastColumn)); } bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, - const QModelIndex &index) + const QStyleOptionViewItem &option, + const QModelIndex &index) { - QAbstractProxyModel* proxyModel = dynamic_cast(model); - Q_ASSERT(proxyModel); - Scene *scene = dynamic_cast(proxyModel->sourceModel()); - Q_ASSERT(scene); - switch(index.column()) { - case Scene::VisibleColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - int x = mouseEvent->pos().x() - option.rect.x(); - if(x >= (option.rect.width() - size)/2 && - x <= (option.rect.width() + size)/2) { - model->setData(index, ! model->data(index).toBool() ); - } - } - return false; //so that the selection can change - } - return true; - break; - case Scene::ColorColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - QColor color = - QColorDialog::getColor(model->data(index).value(), - 0/*, - tr("Select color"), - QColorDialog::ShowAlphaChannel*/); - if (color.isValid()) { - model->setData(index, color ); + QAbstractProxyModel* proxyModel = dynamic_cast(model); + Q_ASSERT(proxyModel); + Scene *scene = dynamic_cast(proxyModel->sourceModel()); + Q_ASSERT(scene); + switch(index.column()) { + case Scene::VisibleColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + int x = mouseEvent->pos().x() - option.rect.x(); + if(x >= (option.rect.width() - size)/2 && + x <= (option.rect.width() + size)/2) { + model->setData(index, ! model->data(index).toBool() ); + } + } + return false; //so that the selection can change } - } + return true; + break; + case Scene::ColorColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + QColor color = + QColorDialog::getColor(model->data(index).value(), + 0/*, + tr("Select color"), + QColorDialog::ShowAlphaChannel*/); + if (color.isValid()) { + model->setData(index, color ); + } + } + } + else if(event->type() == QEvent::MouseButtonDblClick) { + return true; // block double-click + } + return false; + break; + case Scene::RenderingModeColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + // Switch rendering mode + /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); + rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; + model->setData(index, rendering_mode); + } + } + else if(event->type() == QEvent::MouseButtonDblClick) { + return true; // block double-click + } + return false; + break; + case Scene::ABColumn: + if (event->type() == QEvent::MouseButtonPress) { + if(index.row() == scene->item_B) { + scene->item_A = index.row(); + scene->item_B = -1; + } + else if(index.row() == scene->item_A) { + scene->item_B = index.row(); + scene->item_A = -1; + } + else if(scene->item_A == -1) { + scene->item_A = index.row(); + } + else { + scene->item_B = index.row(); + } + scene->dataChanged(scene->createIndex(0, Scene::ABColumn), + scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); + } + return false; + break; + default: + return QItemDelegate::editorEvent(event, model, option, index); } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::RenderingModeColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - // Switch rendering mode - /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); - rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; - model->setData(index, rendering_mode); - } - } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::ABColumn: - if (event->type() == QEvent::MouseButtonPress) { - if(index.row() == scene->item_B) { - scene->item_A = index.row(); - scene->item_B = -1; - } - else if(index.row() == scene->item_A) { - scene->item_B = index.row(); - scene->item_A = -1; - } - else if(scene->item_A == -1) { - scene->item_A = index.row(); - } - else { - scene->item_B = index.row(); - } - scene->dataChanged(scene->createIndex(0, Scene::ABColumn), - scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); - } - return false; - break; - default: - return QItemDelegate::editorEvent(event, model, option, index); - } } void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const + const QModelIndex &index) const { - if (index.column() != Scene::VisibleColumn) { - QItemDelegate::paint(painter, option, index); - } else { - const QAbstractItemModel *model = index.model(); - QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? - (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; + if (index.column() != Scene::VisibleColumn) { + QItemDelegate::paint(painter, option, index); + } else { + const QAbstractItemModel *model = index.model(); + QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? + (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; - if (option.state & QStyle::State_Selected) - painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); - bool checked = model->data(index, ::Qt::DisplayRole).toBool(); - int width = option.rect.width(); - int height = option.rect.height(); - size = (std::min)(width, height); - int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; - int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); - if(checked) { - painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); + bool checked = model->data(index, ::Qt::DisplayRole).toBool(); + int width = option.rect.width(); + int height = option.rect.height(); + size = (std::min)(width, height); + int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; + int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); + if(checked) { + painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } + else { + painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } + drawFocus(painter, option, option.rect); // since we draw the grid ourselves } - else { - painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - drawFocus(painter, option, option.rect); // since we draw the grid ourselves - } } void Scene::setItemVisible(int index, bool b) { - if( index < 0 || index >= m_entries.size() ) - return; - m_entries[index]->setVisible(b); - emit dataChanged(this->createIndex(index, VisibleColumn), - this->createIndex(index, VisibleColumn)); + if( index < 0 || index >= m_entries.size() ) + return; + m_entries[index]->setVisible(b); + emit dataChanged(this->createIndex(index, VisibleColumn), + this->createIndex(index, VisibleColumn)); } void Scene::setSelectionRay(double orig_x, @@ -796,58 +798,58 @@ void Scene::setSelectionRay(double orig_x, double dir_y, double dir_z) { - Scene_item* item = this->item(selected_item); - if(item) item->select(orig_x, - orig_y, - orig_z, - dir_x, - dir_y, - dir_z); + Scene_item* item = this->item(selected_item); + if(item) item->select(orig_x, + orig_y, + orig_z, + dir_x, + dir_y, + dir_z); } void Scene::setItemA(int i) { - item_A = i; - if(item_A == item_B) - { - item_B = -1; - } - emit dataChanged(this->createIndex(0, ABColumn), - this->createIndex(m_entries.size()-1, ABColumn)); + item_A = i; + if(item_A == item_B) + { + item_B = -1; + } + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } void Scene::setItemB(int i) { - item_B = i; - if(item_A == item_B) - { - item_A = -1; - } - emit updated(); - emit dataChanged(this->createIndex(0, ABColumn), - this->createIndex(m_entries.size()-1, ABColumn)); + item_B = i; + if(item_A == item_B) + { + item_A = -1; + } + emit updated(); + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } Scene::Bbox Scene::bbox() const { - if(m_entries.empty()) - return Bbox(); + if(m_entries.empty()) + return Bbox(); - bool bbox_initialized = false; - Bbox bbox; - Q_FOREACH(Scene_item* item, m_entries) - { - if(item->isFinite() && !item->isEmpty()) { - if(bbox_initialized) { - bbox = bbox + item->bbox(); - } - else { - bbox = item->bbox(); - bbox_initialized = true; - } + bool bbox_initialized = false; + Bbox bbox; + Q_FOREACH(Scene_item* item, m_entries) + { + if(item->isFinite() && !item->isEmpty()) { + if(bbox_initialized) { + bbox = bbox + item->bbox(); + } + else { + bbox = item->bbox(); + bbox_initialized = true; + } + } } - } - return bbox; + return bbox; } #include "Scene_find_items.h" @@ -859,13 +861,13 @@ Scene_item* findItem(const Scene_interface* scene_interface, const QMetaObject& metaobj, QString name, Scene_item_name_fn_ptr fn) { - const Scene* scene = dynamic_cast(scene_interface); - if(!scene) return 0; - Q_FOREACH(Scene_item* item, scene->entries()) { - Scene_item* ptr = qobject_cast(metaobj.cast(item)); - if(ptr && ((ptr->*fn)() == name)) return ptr; - } - return 0; + const Scene* scene = dynamic_cast(scene_interface); + if(!scene) return 0; + Q_FOREACH(Scene_item* item, scene->entries()) { + Scene_item* ptr = qobject_cast(metaobj.cast(item)); + if(ptr && ((ptr->*fn)() == name)) return ptr; + } + return 0; } Q_DECL_EXPORT @@ -874,20 +876,20 @@ findItems(const Scene_interface* scene_interface, const QMetaObject&, QString name, Scene_item_name_fn_ptr fn) { - const Scene* scene = dynamic_cast(scene_interface); - QList list; - if(!scene) return list; + const Scene* scene = dynamic_cast(scene_interface); + QList list; + if(!scene) return list; - Q_FOREACH(Scene_item* item, scene->entries()) { - Scene_item* ptr = qobject_cast(item); - if(ptr && ((ptr->*fn)() == name)) { - list << ptr; + Q_FOREACH(Scene_item* item, scene->entries()) { + Scene_item* ptr = qobject_cast(item); + if(ptr && ((ptr->*fn)() == name)) { + list << ptr; + } } - } - return list; + return list; } } // end namespace details -} // end namespace scene + } // end namespace scene #include "Scene.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index f725b43f80b..411317193fa 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -23,23 +23,7 @@ -std::vector positions_poly(0); -std::vector positions_lines(0); -std::vector positions_points(0); -std::vector normals(0); -GLuint rendering_program; -GLuint vertex_array_object; -GLint location[7]; -GLfloat *mvp_mat; -GLfloat *mv_mat; -GLfloat colors[4]; - -GLuint vertex_shader; -GLuint fragment_shader; -GLuint program; -GLuint vao; -GLuint buffer[2]; struct light_info { @@ -101,7 +85,8 @@ struct Polyhedron_to_polygon_soup_writer { }; // end struct Polyhedron_to_soup_writer light_info light; -GLuint compile_shaders(void) +GLuint +Scene_polygon_soup_item::compile_shaders(void) { @@ -109,7 +94,7 @@ GLuint compile_shaders(void) glGenVertexArrays(1, &vao); glBindVertexArray(vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(3, buffer); + glGenBuffers(2, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); @@ -245,8 +230,8 @@ GLuint compile_shaders(void) glDeleteShader(fragment_shader); return program; } - -void uniform_attrib() +void +Scene_polygon_soup_item::uniform_attrib(void) const { @@ -302,31 +287,6 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ } } - if(soup->display_non_manifold_edges) { - double current_color[4]; - GLboolean lightning; - ::glGetDoublev(GL_CURRENT_COLOR, current_color); - //::glColor3d(1., 0., 0.); // red - ::glGetBooleanv(GL_LIGHTING, &lightning); - ::glDisable(GL_LIGHTING); - - BOOST_FOREACH(const Polygon_soup::Edge& edge, - soup->non_manifold_edges) - { - const Point_3& a = soup->points[edge[0]]; - const Point_3& b = soup->points[edge[1]]; - positions_lines.push_back(a.x()); - positions_lines.push_back(a.y()); - positions_lines.push_back(a.y()); - - positions_lines.push_back(b.x()); - positions_lines.push_back(b.y()); - positions_lines.push_back(b.y()); - - } - if(lightning) glEnable(GL_LIGHTING); - // ::glColor4dv(current_color); - } rendering_program = compile_shaders(); //Allocates a uniform location for the MVP and MV matrices @@ -344,7 +304,7 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ Scene_polygon_soup_item::Scene_polygon_soup_item() : Scene_item(), - soup(0), + soup(0),positions_poly(0), normals(0), oriented(false) { glewInit(); @@ -355,9 +315,9 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() Scene_polygon_soup_item::~Scene_polygon_soup_item() { - glDeleteVertexArrays(1, &vertex_array_object); + glDeleteBuffers(2, buffer); + glDeleteVertexArrays(1, &vao); glDeleteProgram(rendering_program); - glDeleteVertexArrays(1, &vertex_array_object); delete soup; } @@ -527,29 +487,7 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw() const { - //fills the arraw of colors with the current color - glGetFloatv(GL_CURRENT_COLOR, colors ); - //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]; // tells the GPU to use the program just created glUseProgram(rendering_program); @@ -612,7 +550,23 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { mv_mat[i] = GLfloat(d_mat[i]); - glGetFloatv(GL_CURRENT_COLOR, colors ); + draw_points(); +} +bool +Scene_polygon_soup_item::isEmpty() const { + + return (soup == 0 || soup->points.empty()); +} +void +Scene_polygon_soup_item::changed() +{ + //fills the arraw of colors with the current color + GLfloat temp[4]; + glGetFloatv(GL_CURRENT_COLOR, temp); + for(int i=0; i<4; i++) + colors[i] = temp[i]; + //Gets lighting info : + //position glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); @@ -632,12 +586,6 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { light.diffuse[1]*=colors[1]; light.diffuse[2]*=colors[2]; - draw_points(); -} -bool -Scene_polygon_soup_item::isEmpty() const { - - return (soup == 0 || soup->points.empty()); } Scene_polygon_soup_item::Bbox diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 70fd5267988..c54d309ef55 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -140,8 +140,8 @@ public: void draw() const; void draw(Viewer_interface*) const; void draw_points() const; - void draw_points(Viewer_interface*) const; - + void draw_points(Viewer_interface*) const; + void changed(); bool isFinite() const { return true; } bool isEmpty() const; Bbox bbox() const; @@ -164,7 +164,24 @@ public slots: private: Polygon_soup* soup; bool oriented; - void compute_normals_and_vertices(); + std::vector positions_poly; + std::vector normals; + + GLuint rendering_program; + GLint location[7]; + GLfloat *mvp_mat; + GLfloat *mv_mat; + GLfloat colors[4]; + + GLuint vertex_shader; + GLuint fragment_shader; + GLuint program; + GLuint vao; + GLuint buffer[2]; + GLuint compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(void) const; + }; // end class Scene_polygon_soup_item #endif // SCENE_POLYGON_SOUP_ITEM_H From 3419da3b3b6b856bd1d42f6f28356ed787dd34d6 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 14:37:00 +0100 Subject: [PATCH 14/62] Design correction No changed function after all. --- Polyhedron/demo/Polyhedron/Scene.cpp | 1191 ++++++++--------- .../Polyhedron/Scene_polygon_soup_item.cpp | 54 +- .../demo/Polyhedron/Scene_polygon_soup_item.h | 2 +- 3 files changed, 623 insertions(+), 624 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index b81137790cd..1def3840171 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -24,10 +24,10 @@ namespace { -void CGALglcolor(QColor c) -{ + void CGALglcolor(QColor c) + { ::glColor4d(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); -} + } } #ifdef CGAL_GLEW_ENABLED @@ -35,157 +35,157 @@ GlSplat::SplatRenderer* Scene::ms_splatting = 0; int Scene::ms_splattingCounter = 0; GlSplat::SplatRenderer* Scene::splatting() { - assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); - return ms_splatting; + assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); + return ms_splatting; } #endif Scene::Scene(QObject* parent) - : QAbstractListModel(parent), - selected_item(-1), - item_A(-1), - item_B(-1) + : QAbstractListModel(parent), + selected_item(-1), + item_A(-1), + item_B(-1) { - connect(this, SIGNAL(selectionRay(double, double, double, - double, double, double)), - this, SLOT(setSelectionRay(double, double, double, - double, double, double))); + connect(this, SIGNAL(selectionRay(double, double, double, + double, double, double)), + this, SLOT(setSelectionRay(double, double, double, + double, double, double))); #ifdef CGAL_GLEW_ENABLED - if(ms_splatting==0) - ms_splatting = new GlSplat::SplatRenderer(); - ms_splattingCounter++; + if(ms_splatting==0) + ms_splatting = new GlSplat::SplatRenderer(); + ms_splattingCounter++; #endif } Scene::Item_id Scene::addItem(Scene_item* item) { - Bbox bbox_before = bbox(); - m_entries.push_back(item); - connect(item, SIGNAL(itemChanged()), - this, SLOT(itemChanged())); - if(bbox_before + item->bbox() != bbox_before) - { emit updated_bbox(); } - emit updated(); - QAbstractListModel::reset(); - Item_id id = m_entries.size() - 1; - emit newItem(id); - return id; + Bbox bbox_before = bbox(); + m_entries.push_back(item); + connect(item, SIGNAL(itemChanged()), + this, SLOT(itemChanged())); + if(bbox_before + item->bbox() != bbox_before) + { emit updated_bbox(); } + emit updated(); + QAbstractListModel::reset(); + Item_id id = m_entries.size() - 1; + emit newItem(id); + return id; } Scene_item* Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_to_be_destroyed) { - if(index < 0 || index >= m_entries.size()) - return 0; + if(index < 0 || index >= m_entries.size()) + return 0; - if(emit_item_about_to_be_destroyed) { - emit itemAboutToBeDestroyed(m_entries[index]); - } + if(emit_item_about_to_be_destroyed) { + emit itemAboutToBeDestroyed(m_entries[index]); + } - connect(item, SIGNAL(itemChanged()), - this, SLOT(itemChanged())); - std::swap(m_entries[index], item); + connect(item, SIGNAL(itemChanged()), + this, SLOT(itemChanged())); + std::swap(m_entries[index], item); - if ( item->isFinite() && !item->isEmpty() && - m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && - item->bbox()!=m_entries[index]->bbox() ) - { - emit updated_bbox(); - } - emit updated(); - itemChanged(index); - // QAbstractListModel::reset(); - return item; + if ( item->isFinite() && !item->isEmpty() && + m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && + item->bbox()!=m_entries[index]->bbox() ) + { + emit updated_bbox(); + } + emit updated(); + itemChanged(index); + // QAbstractListModel::reset(); + return item; } int Scene::erase(int index) { - if(index < 0 || index >= m_entries.size()) - return -1; - - Scene_item* item = m_entries[index]; - emit itemAboutToBeDestroyed(item); - delete item; - m_entries.removeAt(index); - - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); - - if(--index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; + if(index < 0 || index >= m_entries.size()) return -1; + + Scene_item* item = m_entries[index]; + emit itemAboutToBeDestroyed(item); + delete item; + m_entries.removeAt(index); + + selected_item = -1; + emit updated(); + QAbstractListModel::reset(); + + if(--index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; + return -1; } int Scene::erase(QList indices) { - QList to_be_removed; + QList to_be_removed; - int max_index = -1; - Q_FOREACH(int index, indices) { - if(index < 0 || index >= m_entries.size()) - continue; - max_index = (std::max)(max_index, index); - Scene_item* item = m_entries[index]; - to_be_removed.push_back(item); - emit itemAboutToBeDestroyed(item); - delete item; - } + int max_index = -1; + Q_FOREACH(int index, indices) { + if(index < 0 || index >= m_entries.size()) + continue; + max_index = (std::max)(max_index, index); + Scene_item* item = m_entries[index]; + to_be_removed.push_back(item); + emit itemAboutToBeDestroyed(item); + delete item; + } - Q_FOREACH(Scene_item* item, to_be_removed) { - m_entries.removeAll(item); - } + Q_FOREACH(Scene_item* item, to_be_removed) { + m_entries.removeAll(item); + } - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); + selected_item = -1; + emit updated(); + QAbstractListModel::reset(); - int index = max_index + 1 - indices.size(); - if(index >= m_entries.size()) { - index = m_entries.size() - 1; - } - if(index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; - return -1; + int index = max_index + 1 - indices.size(); + if(index >= m_entries.size()) { + index = m_entries.size() - 1; + } + if(index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; + return -1; } Scene::~Scene() { - Q_FOREACH(Scene_item* item_ptr, m_entries) - { - delete item_ptr; - } - m_entries.clear(); + Q_FOREACH(Scene_item* item_ptr, m_entries) + { + delete item_ptr; + } + m_entries.clear(); #ifdef CGAL_GLEW_ENABLED - if((--ms_splattingCounter)==0) - delete ms_splatting; + if((--ms_splattingCounter)==0) + delete ms_splatting; #endif } Scene_item* Scene::item(Item_id index) const { - return m_entries.value(index); // QList::value checks bounds + return m_entries.value(index); // QList::value checks bounds } Scene::Item_id Scene::item_id(Scene_item* scene_item) const { - return m_entries.indexOf(scene_item); + return m_entries.indexOf(scene_item); } int Scene::numberOfEntries() const { - return m_entries.size(); + return m_entries.size(); } // Duplicate a scene item. @@ -193,40 +193,40 @@ Scene::numberOfEntries() const Scene::Item_id Scene::duplicate(Item_id index) { - if(index < 0 || index >= m_entries.size()) - return -1; + if(index < 0 || index >= m_entries.size()) + return -1; - const Scene_item* item = m_entries[index]; - Scene_item* new_item = item->clone(); - if(new_item) { - new_item->setName(tr("%1 (copy)").arg(item->name())); - new_item->setColor(item->color()); - new_item->setVisible(item->visible()); - addItem(new_item); - return m_entries.size() - 1; - } - else - return -1; + const Scene_item* item = m_entries[index]; + Scene_item* new_item = item->clone(); + if(new_item) { + new_item->setName(tr("%1 (copy)").arg(item->name())); + new_item->setColor(item->color()); + new_item->setVisible(item->visible()); + addItem(new_item); + return m_entries.size() - 1; + } + else + return -1; } void Scene::initializeGL() { #ifdef CGAL_GLEW_ENABLED - ms_splatting->init(); + ms_splatting->init(); - //Setting the light options + //Setting the light options - // Create light components - GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; - GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; - GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; + // Create light components + GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; + GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; - // Assign created components to GL_LIGHT0 - glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); - glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); - glLightfv(GL_LIGHT0, GL_POSITION, position); + // Assign created components to GL_LIGHT0 + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); + glLightfv(GL_LIGHT0, GL_POSITION, position); #endif } @@ -238,193 +238,190 @@ void Scene::initializeGL() bool Scene::keyPressEvent(QKeyEvent* e){ - bool res=false; - for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); - it!=endit;++it) - { - Scene_item* item=m_entries[*it]; - res |= item->keyPressEvent(e); - } - return res; + bool res=false; + for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); + it!=endit;++it) + { + Scene_item* item=m_entries[*it]; + res |= item->keyPressEvent(e); + } + return res; } void Scene::draw() { - draw_aux(false, 0); + draw_aux(false, 0); } void Scene::draw(Viewer_interface* viewer) { - draw_aux(false, viewer); + draw_aux(false, viewer); } void Scene::drawWithNames() { - draw_aux(true, 0); + draw_aux(true, 0); } void Scene::drawWithNames(Viewer_interface* viewer) { - draw_aux(true, viewer); + draw_aux(true, viewer); } void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { - // Flat/Gouraud OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *m_entries[index]; - if(item.visible()) - { - if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - if(item.renderingMode() == Gouraud) - ::glShadeModel(GL_SMOOTH); - else - ::glShadeModel(GL_FLAT); - - if(CGAL::check_gl_error(__FILE__, __LINE__)) { - std::cerr << "GL error was before the drawing of the item \"" - << qPrintable(item.name()) << "\"\n" - << " with_name = " << std::boolalpha << with_names - << std::endl; - } - item.changed(); - if(viewer) - item.draw(viewer); - else - item.draw(); - if(CGAL::check_gl_error(__FILE__, __LINE__)) { - std::cerr << "GL error was after the drawing of the item \"" - << qPrintable(item.name()) << "\"\n" - << " with_name = " << std::boolalpha << with_names - << std::endl; - } - } - } - if(with_names) { - ::glPopName(); - } + // Flat/Gouraud OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) + { + if(with_names) { + ::glPushName(index); } - - // Wireframe OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) + Scene_item& item = *m_entries[index]; + if(item.visible()) { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *m_entries[index]; - if(item.visible()) - { - if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(Qt::black); - else - CGALglcolor(item.color().lighter(50)); + if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) + { + ::glEnable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(item.color().lighter(120)); + else + CGALglcolor(item.color()); + if(item.renderingMode() == Gouraud) + ::glShadeModel(GL_SMOOTH); + else + ::glShadeModel(GL_FLAT); - item.changed(); - - if(viewer) - item.draw_edges(viewer); - else - item.draw_edges(); - } - else{ - if( item.renderingMode() == PointsPlusNormals ){ - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - item.changed(); - if(viewer) - item.draw_edges(viewer); - else - item.draw_edges(); - } - } + if(CGAL::check_gl_error(__FILE__, __LINE__)) { + std::cerr << "GL error was before the drawing of the item \"" + << qPrintable(item.name()) << "\"\n" + << " with_name = " << std::boolalpha << with_names + << std::endl; } - if(with_names) { - ::glPopName(); + if(viewer) + item.draw(viewer); + else + item.draw(); + if(CGAL::check_gl_error(__FILE__, __LINE__)) { + std::cerr << "GL error was after the drawing of the item \"" + << qPrintable(item.name()) << "\"\n" + << " with_name = " << std::boolalpha << with_names + << std::endl; } + } } + if(with_names) { + ::glPopName(); + } + } - // Points OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) + // Wireframe OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) + { + if(with_names) { + ::glPushName(index); + } + Scene_item& item = *m_entries[index]; + if(item.visible()) { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *m_entries[index]; - if(item.visible()) - { - if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - CGALglcolor(item.color()); + if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) + { + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(Qt::black); + else + CGALglcolor(item.color().lighter(50)); - item.changed(); - if(viewer) - item.draw_points(viewer); - else - item.draw_points(); - } - } - if(with_names) { - ::glPopName(); + + + if(viewer) + item.draw_edges(viewer); + else + item.draw_edges(); + } + else{ + if( item.renderingMode() == PointsPlusNormals ){ + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(item.color().lighter(120)); + else + CGALglcolor(item.color()); + if(viewer) + item.draw_edges(viewer); + else + item.draw_edges(); } + } } + if(with_names) { + ::glPopName(); + } + } + + // Points OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) + { + if(with_names) { + ::glPushName(index); + } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) + { + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + CGALglcolor(item.color()); + + if(viewer) + item.draw_points(viewer); + else + item.draw_points(); + } + } + if(with_names) { + ::glPopName(); + } + } #ifdef CGAL_GLEW_ENABLED - // Splatting - if(!with_names && ms_splatting->isSupported()) + // Splatting + if(!with_names && ms_splatting->isSupported()) + { + ms_splatting->beginVisibilityPass(); + for(int index = 0; index < m_entries.size(); ++index) { - ms_splatting->beginVisibilityPass(); - for(int index = 0; index < m_entries.size(); ++index) - { - Scene_item& item = *m_entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - item.draw_splats(); - } - } - ms_splatting->beginAttributePass(); - for(int index = 0; index < m_entries.size(); ++index) - { - Scene_item& item = *m_entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - CGALglcolor(item.color()); - item.draw_splats(); - } - } - ms_splatting->finalize(); + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + item.draw_splats(); + } } + ms_splatting->beginAttributePass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + CGALglcolor(item.color()); + item.draw_splats(); + } + } + ms_splatting->finalize(); + } #endif } @@ -435,127 +432,127 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) int Scene::rowCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else - return m_entries.size(); + if (parent.isValid()) + return 0; + else + return m_entries.size(); } int Scene::columnCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else - return NumberOfColumns; + if (parent.isValid()) + return 0; + else + return NumberOfColumns; } QVariant Scene::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); - - if(index.row() < 0 || index.row() >= m_entries.size()) - return QVariant(); - - if(role == ::Qt::ToolTipRole) - { - return m_entries[index.row()]->toolTip(); - } - switch(index.column()) - { - case ColorColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->color(); - else if(role == ::Qt::DecorationRole) - return m_entries.value(index.row())->color(); - break; - case NameColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->name(); - if(role == ::Qt::FontRole) - return m_entries.value(index.row())->font(); - break; - case RenderingModeColumn: - if(role == ::Qt::DisplayRole) { - return m_entries.value(index.row())->renderingModeName(); - } - else if(role == ::Qt::EditRole) { - return static_cast(m_entries.value(index.row())->renderingMode()); - } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case ABColumn: - if(role == ::Qt::DisplayRole) { - if(index.row() == item_A) - return "A"; - if(index.row() == item_B) - return "B"; - } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case VisibleColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->visible(); - break; - default: - return QVariant(); - } + if (!index.isValid()) return QVariant(); + + if(index.row() < 0 || index.row() >= m_entries.size()) + return QVariant(); + + if(role == ::Qt::ToolTipRole) + { + return m_entries[index.row()]->toolTip(); + } + switch(index.column()) + { + case ColorColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->color(); + else if(role == ::Qt::DecorationRole) + return m_entries.value(index.row())->color(); + break; + case NameColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->name(); + if(role == ::Qt::FontRole) + return m_entries.value(index.row())->font(); + break; + case RenderingModeColumn: + if(role == ::Qt::DisplayRole) { + return m_entries.value(index.row())->renderingModeName(); + } + else if(role == ::Qt::EditRole) { + return static_cast(m_entries.value(index.row())->renderingMode()); + } + else if(role == ::Qt::TextAlignmentRole) { + return ::Qt::AlignCenter; + } + break; + case ABColumn: + if(role == ::Qt::DisplayRole) { + if(index.row() == item_A) + return "A"; + if(index.row() == item_B) + return "B"; + } + else if(role == ::Qt::TextAlignmentRole) { + return ::Qt::AlignCenter; + } + break; + case VisibleColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->visible(); + break; + default: + return QVariant(); + } + return QVariant(); } QVariant Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const { - if(orientation == ::Qt::Horizontal) { - if (role == ::Qt::DisplayRole) - { - switch(section) - { - case NameColumn: - return tr("Name"); - break; - case ColorColumn: - return tr("Color"); - break; - case RenderingModeColumn: - return tr("Mode"); - case ABColumn: - return tr("A/B"); - break; - case VisibleColumn: - return tr("View"); - break; - default: - return QVariant(); - } - } - else if(role == ::Qt::ToolTipRole) { - if(section == RenderingModeColumn) { - return tr("Rendering mode (points/wireframe/flat/flat+edges/Gouraud)"); - } - else if(section == ABColumn) { - return tr("Selection A/Selection B"); - } - } + if(orientation == ::Qt::Horizontal) { + if (role == ::Qt::DisplayRole) + { + switch(section) + { + case NameColumn: + return tr("Name"); + break; + case ColorColumn: + return tr("Color"); + break; + case RenderingModeColumn: + return tr("Mode"); + case ABColumn: + return tr("A/B"); + break; + case VisibleColumn: + return tr("View"); + break; + default: + return QVariant(); + } } - return QAbstractListModel::headerData(section, orientation, role); + else if(role == ::Qt::ToolTipRole) { + if(section == RenderingModeColumn) { + return tr("Rendering mode (points/wireframe/flat/flat+edges/Gouraud)"); + } + else if(section == ABColumn) { + return tr("Selection A/Selection B"); + } + } + } + return QAbstractListModel::headerData(section, orientation, role); } Qt::ItemFlags Scene::flags ( const QModelIndex & index ) const { - if (index.isValid() && index.column() == NameColumn) { - return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; - } - else { - return QAbstractListModel::flags(index); - } + if (index.isValid() && index.column() == NameColumn) { + return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; + } + else { + return QAbstractListModel::flags(index); + } } bool @@ -563,232 +560,232 @@ Scene::setData(const QModelIndex &index, const QVariant &value, int role) { - if( role != ::Qt::EditRole || !index.isValid() ) - return false; - - if(index.row() < 0 || index.row() >= m_entries.size()) - return false; - - Scene_item* item = m_entries[index.row()]; - if(!item) return false; - switch(index.column()) - { - case NameColumn: - item->setName(value.toString()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case ColorColumn: - item->setColor(value.value()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case RenderingModeColumn: - { - RenderingMode rendering_mode = static_cast(value.toInt()); - // Find next supported rendering mode - while ( ! item->supportsRenderingMode(rendering_mode) - #ifdef CGAL_GLEW_ENABLED - || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) - #endif - ) - { - rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); - } - item->setRenderingMode(rendering_mode); - item->changed(); - emit dataChanged(index, index); - return true; - break; - } - case VisibleColumn: - item->setVisible(value.toBool()); - item->changed(); - emit dataChanged(index, index); - return true; - default: - return false; - } + if( role != ::Qt::EditRole || !index.isValid() ) return false; + + if(index.row() < 0 || index.row() >= m_entries.size()) + return false; + + Scene_item* item = m_entries[index.row()]; + if(!item) return false; + switch(index.column()) + { + case NameColumn: + item->setName(value.toString()); + item->changed(); + emit dataChanged(index, index); + return true; + break; + case ColorColumn: + item->setColor(value.value()); + item->changed(); + emit dataChanged(index, index); + return true; + break; + case RenderingModeColumn: + { + RenderingMode rendering_mode = static_cast(value.toInt()); + // Find next supported rendering mode + while ( ! item->supportsRenderingMode(rendering_mode) +#ifdef CGAL_GLEW_ENABLED + || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) +#endif + ) + { + rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); + } + item->setRenderingMode(rendering_mode); + item->changed(); + emit dataChanged(index, index); + return true; + break; + } + case VisibleColumn: + item->setVisible(value.toBool()); + item->changed(); + emit dataChanged(index, index); + return true; + default: + return false; + } + return false; } Scene::Item_id Scene::mainSelectionIndex() const { - return selected_item; + return selected_item; } QList Scene::selectionIndices() const { - return selected_items_list; + return selected_items_list; } int Scene::selectionAindex() const { - return item_A; + return item_A; } int Scene::selectionBindex() const { - return item_B; + return item_B; } QItemSelection Scene::createSelection(int i) { - return QItemSelection(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + return QItemSelection(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } QItemSelection Scene::createSelectionAll() { - return QItemSelection(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1 , LastColumn)); + return QItemSelection(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1 , LastColumn)); } void Scene::itemChanged() { - Scene_item* item = qobject_cast(sender()); - if(item) - itemChanged(item); + Scene_item* item = qobject_cast(sender()); + if(item) + itemChanged(item); } void Scene::itemChanged(Item_id i) { - if(i < 0 || i >= m_entries.size()) - return; + if(i < 0 || i >= m_entries.size()) + return; - m_entries[i]->changed(); - emit dataChanged(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + m_entries[i]->changed(); + emit dataChanged(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } void Scene::itemChanged(Scene_item* item) { - item->changed(); - emit dataChanged(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1, LastColumn)); + item->changed(); + emit dataChanged(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1, LastColumn)); } bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { - QAbstractProxyModel* proxyModel = dynamic_cast(model); - Q_ASSERT(proxyModel); - Scene *scene = dynamic_cast(proxyModel->sourceModel()); - Q_ASSERT(scene); - switch(index.column()) { - case Scene::VisibleColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - int x = mouseEvent->pos().x() - option.rect.x(); - if(x >= (option.rect.width() - size)/2 && - x <= (option.rect.width() + size)/2) { - model->setData(index, ! model->data(index).toBool() ); - } - } - return false; //so that the selection can change + QAbstractProxyModel* proxyModel = dynamic_cast(model); + Q_ASSERT(proxyModel); + Scene *scene = dynamic_cast(proxyModel->sourceModel()); + Q_ASSERT(scene); + switch(index.column()) { + case Scene::VisibleColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + int x = mouseEvent->pos().x() - option.rect.x(); + if(x >= (option.rect.width() - size)/2 && + x <= (option.rect.width() + size)/2) { + model->setData(index, ! model->data(index).toBool() ); } - return true; - break; - case Scene::ColorColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - QColor color = - QColorDialog::getColor(model->data(index).value(), - 0/*, - tr("Select color"), - QColorDialog::ShowAlphaChannel*/); - if (color.isValid()) { - model->setData(index, color ); - } - } - } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::RenderingModeColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - // Switch rendering mode - /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); - rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; - model->setData(index, rendering_mode); - } - } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::ABColumn: - if (event->type() == QEvent::MouseButtonPress) { - if(index.row() == scene->item_B) { - scene->item_A = index.row(); - scene->item_B = -1; - } - else if(index.row() == scene->item_A) { - scene->item_B = index.row(); - scene->item_A = -1; - } - else if(scene->item_A == -1) { - scene->item_A = index.row(); - } - else { - scene->item_B = index.row(); - } - scene->dataChanged(scene->createIndex(0, Scene::ABColumn), - scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); - } - return false; - break; - default: - return QItemDelegate::editorEvent(event, model, option, index); + } + return false; //so that the selection can change } + return true; + break; + case Scene::ColorColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + QColor color = + QColorDialog::getColor(model->data(index).value(), + 0/*, + tr("Select color"), + QColorDialog::ShowAlphaChannel*/); + if (color.isValid()) { + model->setData(index, color ); + } + } + } + else if(event->type() == QEvent::MouseButtonDblClick) { + return true; // block double-click + } + return false; + break; + case Scene::RenderingModeColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + // Switch rendering mode + /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); + rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; + model->setData(index, rendering_mode); + } + } + else if(event->type() == QEvent::MouseButtonDblClick) { + return true; // block double-click + } + return false; + break; + case Scene::ABColumn: + if (event->type() == QEvent::MouseButtonPress) { + if(index.row() == scene->item_B) { + scene->item_A = index.row(); + scene->item_B = -1; + } + else if(index.row() == scene->item_A) { + scene->item_B = index.row(); + scene->item_A = -1; + } + else if(scene->item_A == -1) { + scene->item_A = index.row(); + } + else { + scene->item_B = index.row(); + } + scene->dataChanged(scene->createIndex(0, Scene::ABColumn), + scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); + } + return false; + break; + default: + return QItemDelegate::editorEvent(event, model, option, index); + } } void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - if (index.column() != Scene::VisibleColumn) { - QItemDelegate::paint(painter, option, index); - } else { - const QAbstractItemModel *model = index.model(); - QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? - (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; + if (index.column() != Scene::VisibleColumn) { + QItemDelegate::paint(painter, option, index); + } else { + const QAbstractItemModel *model = index.model(); + QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? + (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; - if (option.state & QStyle::State_Selected) - painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); - bool checked = model->data(index, ::Qt::DisplayRole).toBool(); - int width = option.rect.width(); - int height = option.rect.height(); - size = (std::min)(width, height); - int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; - int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); - if(checked) { - painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - else { - painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - drawFocus(painter, option, option.rect); // since we draw the grid ourselves + bool checked = model->data(index, ::Qt::DisplayRole).toBool(); + int width = option.rect.width(); + int height = option.rect.height(); + size = (std::min)(width, height); + int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; + int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); + if(checked) { + painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); } + else { + painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } + drawFocus(painter, option, option.rect); // since we draw the grid ourselves + } } void Scene::setItemVisible(int index, bool b) { - if( index < 0 || index >= m_entries.size() ) - return; - m_entries[index]->setVisible(b); - emit dataChanged(this->createIndex(index, VisibleColumn), - this->createIndex(index, VisibleColumn)); + if( index < 0 || index >= m_entries.size() ) + return; + m_entries[index]->setVisible(b); + emit dataChanged(this->createIndex(index, VisibleColumn), + this->createIndex(index, VisibleColumn)); } void Scene::setSelectionRay(double orig_x, @@ -798,58 +795,58 @@ void Scene::setSelectionRay(double orig_x, double dir_y, double dir_z) { - Scene_item* item = this->item(selected_item); - if(item) item->select(orig_x, - orig_y, - orig_z, - dir_x, - dir_y, - dir_z); + Scene_item* item = this->item(selected_item); + if(item) item->select(orig_x, + orig_y, + orig_z, + dir_x, + dir_y, + dir_z); } void Scene::setItemA(int i) { - item_A = i; - if(item_A == item_B) - { - item_B = -1; - } - emit dataChanged(this->createIndex(0, ABColumn), - this->createIndex(m_entries.size()-1, ABColumn)); + item_A = i; + if(item_A == item_B) + { + item_B = -1; + } + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } void Scene::setItemB(int i) { - item_B = i; - if(item_A == item_B) - { - item_A = -1; - } - emit updated(); - emit dataChanged(this->createIndex(0, ABColumn), - this->createIndex(m_entries.size()-1, ABColumn)); + item_B = i; + if(item_A == item_B) + { + item_A = -1; + } + emit updated(); + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } Scene::Bbox Scene::bbox() const { - if(m_entries.empty()) - return Bbox(); + if(m_entries.empty()) + return Bbox(); - bool bbox_initialized = false; - Bbox bbox; - Q_FOREACH(Scene_item* item, m_entries) - { - if(item->isFinite() && !item->isEmpty()) { - if(bbox_initialized) { - bbox = bbox + item->bbox(); - } - else { - bbox = item->bbox(); - bbox_initialized = true; - } - } + bool bbox_initialized = false; + Bbox bbox; + Q_FOREACH(Scene_item* item, m_entries) + { + if(item->isFinite() && !item->isEmpty()) { + if(bbox_initialized) { + bbox = bbox + item->bbox(); + } + else { + bbox = item->bbox(); + bbox_initialized = true; + } } - return bbox; + } + return bbox; } #include "Scene_find_items.h" @@ -861,13 +858,13 @@ Scene_item* findItem(const Scene_interface* scene_interface, const QMetaObject& metaobj, QString name, Scene_item_name_fn_ptr fn) { - const Scene* scene = dynamic_cast(scene_interface); - if(!scene) return 0; - Q_FOREACH(Scene_item* item, scene->entries()) { - Scene_item* ptr = qobject_cast(metaobj.cast(item)); - if(ptr && ((ptr->*fn)() == name)) return ptr; - } - return 0; + const Scene* scene = dynamic_cast(scene_interface); + if(!scene) return 0; + Q_FOREACH(Scene_item* item, scene->entries()) { + Scene_item* ptr = qobject_cast(metaobj.cast(item)); + if(ptr && ((ptr->*fn)() == name)) return ptr; + } + return 0; } Q_DECL_EXPORT @@ -876,20 +873,20 @@ findItems(const Scene_interface* scene_interface, const QMetaObject&, QString name, Scene_item_name_fn_ptr fn) { - const Scene* scene = dynamic_cast(scene_interface); - QList list; - if(!scene) return list; + const Scene* scene = dynamic_cast(scene_interface); + QList list; + if(!scene) return list; - Q_FOREACH(Scene_item* item, scene->entries()) { - Scene_item* ptr = qobject_cast(item); - if(ptr && ((ptr->*fn)() == name)) { - list << ptr; - } + Q_FOREACH(Scene_item* item, scene->entries()) { + Scene_item* ptr = qobject_cast(item); + if(ptr && ((ptr->*fn)() == name)) { + list << ptr; } - return list; + } + return list; } } // end namespace details - } // end namespace scene +} // end namespace scene #include "Scene.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 411317193fa..c38c8bd7016 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -83,7 +83,6 @@ struct Polyhedron_to_polygon_soup_writer { polygon.clear(); } }; // end struct Polyhedron_to_soup_writer -light_info light; GLuint Scene_polygon_soup_item::compile_shaders(void) @@ -233,6 +232,34 @@ Scene_polygon_soup_item::compile_shaders(void) void Scene_polygon_soup_item::uniform_attrib(void) const { + GLfloat colors[4]; + light_info light; + + //fills the arraw of colors with the current color + GLfloat temp[4]; + glGetFloatv(GL_CURRENT_COLOR, temp); + for(int i=0; i<4; i++) + colors[i] = temp[i]; + //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]; //Set the ModelViewProjection and ModelView matrices @@ -560,31 +587,6 @@ Scene_polygon_soup_item::isEmpty() const { void Scene_polygon_soup_item::changed() { - //fills the arraw of colors with the current color - GLfloat temp[4]; - glGetFloatv(GL_CURRENT_COLOR, temp); - for(int i=0; i<4; i++) - colors[i] = temp[i]; - //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]; } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index c54d309ef55..b025aef16b4 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -171,7 +171,7 @@ private: GLint location[7]; GLfloat *mvp_mat; GLfloat *mv_mat; - GLfloat colors[4]; + GLuint vertex_shader; GLuint fragment_shader; From f9701452e61e1aa8af6b36c5ceeedc6fbd037424 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 15:15:26 +0100 Subject: [PATCH 15/62] Draw Two Side implementation The shader is now able to "draw two sides". --- .../demo/Polyhedron/Scene_polygon_soup_item.cpp | 14 ++++++++++++-- .../demo/Polyhedron/Scene_polygon_soup_item.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index c38c8bd7016..6b874bb35fd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -123,6 +123,8 @@ Scene_polygon_soup_item::compile_shaders(void) "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 vColors; \n" "uniform vec3 light_pos; \n" "uniform vec3 light_diff; \n" @@ -146,8 +148,11 @@ Scene_polygon_soup_item::compile_shaders(void) "V = normalize(V); \n" "vec3 R = reflect(-L, N); \n" - - "vec3 diffuse = max(dot(N,L), 0.0) * light_diff; \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" @@ -234,6 +239,9 @@ Scene_polygon_soup_item::uniform_attrib(void) const { GLfloat colors[4]; light_info light; + GLint is_both_sides = 0; + + glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); //fills the arraw of colors with the current color GLfloat temp[4]; @@ -272,6 +280,7 @@ Scene_polygon_soup_item::uniform_attrib(void) const glUniform3fv(location[4], 1, light.specular); glUniform3fv(location[5], 1, light.ambient); glUniform3fv(location[6], 1, colors); + glUniform1i(location[7], is_both_sides); } void @@ -326,6 +335,7 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ location[4] = glGetUniformLocation(rendering_program, "light_spec"); location[5] = glGetUniformLocation(rendering_program, "light_amb"); location[6] = glGetUniformLocation(rendering_program, "vColors"); + location[7] = glGetUniformLocation(rendering_program, "is_two_side"); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index b025aef16b4..3c03895a52d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -168,7 +168,7 @@ private: std::vector normals; GLuint rendering_program; - GLint location[7]; + GLint location[8]; GLfloat *mvp_mat; GLfloat *mv_mat; From 1fc89d64e414ee246274d7ee773ed6d3c8aa2f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 18 Feb 2015 16:22:57 +0100 Subject: [PATCH 16/62] applicable now depends on the action (cherry picked from commit b9fbda6c0c8bd168da75ed644594ed86f40fbbdf) --- .../demo/Polyhedron/Io_implicit_function_plugin.cpp | 2 +- Polyhedron/demo/Polyhedron/MainWindow.cpp | 10 ++-------- .../Polyhedron_demo_camera_positions_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_corefinement_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp | 2 +- .../Polyhedron_demo_edit_polyhedron_plugin.cpp | 4 ++-- .../Polyhedron/Polyhedron_demo_inside_out_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_intersection_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp | 2 +- ...Polyhedron_demo_join_and_split_polyhedra_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp | 2 +- .../Polyhedron_demo_mesh_segmentation_plugin.cpp | 2 +- .../Polyhedron_demo_mesh_simplification_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_nef_plugin.cpp | 2 +- .../Polyhedron_demo_normal_estimation_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp | 6 +++++- .../Polyhedron_demo_parameterization_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_pca_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_plugin_interface.h | 2 +- .../Polyhedron_demo_point_inside_polyhedron_plugin.cpp | 2 +- ...olyhedron_demo_point_set_average_spacing_plugin.cpp | 2 +- ...lyhedron_demo_point_set_outliers_removal_plugin.cpp | 2 +- ...Polyhedron_demo_point_set_simplification_plugin.cpp | 2 +- .../Polyhedron_demo_point_set_smoothing_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp | 2 +- .../Polyhedron_demo_polyhedron_slicer_plugin.cpp | 2 +- .../Polyhedron_demo_polyhedron_stitching_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_remeshing_plugin.cpp | 2 +- ...lyhedron_demo_scale_space_reconstruction_plugin.cpp | 2 +- .../Polyhedron/Polyhedron_demo_selection_plugin.cpp | 2 +- .../Polyhedron_demo_self_intersection_plugin.cpp | 2 +- .../Polyhedron_demo_subdivision_methods_plugin.cpp | 2 +- .../Polyhedron_demo_transform_polyhedron_plugin.cpp | 2 +- .../Polyhedron_demo_triangulate_facets_plugin.cpp | 2 +- .../demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp | 2 +- 37 files changed, 43 insertions(+), 45 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Io_implicit_function_plugin.cpp b/Polyhedron/demo/Polyhedron/Io_implicit_function_plugin.cpp index 7843cee826f..eed51138917 100644 --- a/Polyhedron/demo/Polyhedron/Io_implicit_function_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Io_implicit_function_plugin.cpp @@ -54,7 +54,7 @@ public: Io_implicit_function_plugin(); virtual ~Io_implicit_function_plugin() {} - bool applicable() const { return true; } + bool applicable(QAction*) const { return true; } QString name() const { return "implicit functions"; } // QString nameFilters() const { return ""; } diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 4e9406d2366..9da72a7519a 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -340,14 +340,8 @@ MainWindow::MainWindow(QWidget* parent) void MainWindow::filterOperations() { Q_FOREACH(const PluginNamePair& p, plugins) { - if(p.first->applicable()) { - Q_FOREACH(QAction* action, p.first->actions()) { - action->setVisible(true); - } - } else { - Q_FOREACH(QAction* action, p.first->actions()) { - action->setVisible(false); - } + Q_FOREACH(QAction* action, p.first->actions()) { + action->setVisible( p.first->applicable(action) ); } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_camera_positions_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_camera_positions_plugin.cpp index c1a41e8e354..d78b5079c8f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_camera_positions_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_camera_positions_plugin.cpp @@ -26,7 +26,7 @@ public: bool canSave(const Scene_item*) { return false; } bool save(const Scene_item*, QFileInfo ) {return false; } - bool applicable() const {return false;} + bool applicable(QAction*) const {return false;} private: Camera_positions_list* cpl; }; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp index 07fc6cb5012..c0f91fcd42d 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp @@ -29,7 +29,7 @@ public: return QStringList() << "actionConvexHull"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())) || diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp index 7c73d4ec92d..242d113d898 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp @@ -28,7 +28,7 @@ class Polyhedron_demo_corefinement_plugin : public: - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp index 62dc22469e3..ec98cb56588 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp @@ -172,7 +172,7 @@ public: virtual ~Polyhedron_demo_cut_plugin(); - bool applicable() const { + bool applicable(QAction*) const { // returns true if one polyhedron is in the entries for (int i=0; i< scene->numberOfEntries(); ++i) { diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp index d27c8efa5ee..9a256f53a9f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp @@ -26,7 +26,7 @@ public: void init(QMainWindow* mainWindow, Scene_interface* scene_interface); QList actions() const; - bool applicable() const; + bool applicable(QAction*) const; public slots: void on_actionDeformation_triggered(); @@ -69,7 +69,7 @@ private: QList Polyhedron_demo_edit_polyhedron_plugin::actions() const { return QList() << actionDeformation; } -bool Polyhedron_demo_edit_polyhedron_plugin::applicable() const { +bool Polyhedron_demo_edit_polyhedron_plugin::applicable(QAction*) const { Q_FOREACH(Scene_interface::Item_id i, scene->selectionIndices()) { if(qobject_cast(scene->item(i)) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp index 25469ebef8a..ef86455fa47 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp @@ -22,7 +22,7 @@ public: return QStringList() << "actionInsideOut"; } - bool applicable() const { + bool applicable(QAction*) const { const Scene_interface::Item_id index = scene->mainSelectionIndex(); return qobject_cast(scene->item(index)) || qobject_cast(scene->item(index)); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp index 42d952df9bb..79c04e5259b 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp @@ -33,7 +33,7 @@ class Polyhedron_demo_intersection_plugin : public: - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp index a985d8a937a..24dbe6bb254 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp @@ -25,7 +25,7 @@ public: return QStringList() << "actionEstimateCurvature"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp index 68fb6316288..ec4d38cd559 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp @@ -37,7 +37,7 @@ public: Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); } - bool applicable() const { + bool applicable(QAction*) const { Q_FOREACH(int index, scene->selectionIndices()) { if ( qobject_cast(scene->item(index)) ) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp index eacc0d2b8a0..e5bf8357450 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp @@ -37,7 +37,7 @@ public: return QStringList() << "actionKernel"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp index c37865a9bc1..fb36761e628 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp @@ -47,7 +47,7 @@ public: return QList() << actionMesh_3; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } public slots: diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp index 9f1ea88fba1..2a03de8c432 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp @@ -57,7 +57,7 @@ public: return QList() << actionSegmentation; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp index e6881669c49..a5c6e67d293 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp @@ -26,7 +26,7 @@ public: return QStringList() << "actionSimplify"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } public slots: diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_nef_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_nef_plugin.cpp index c2da2c8f1e4..d67bd490d98 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_nef_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_nef_plugin.cpp @@ -30,7 +30,7 @@ public: << "actionMinkowskiSum"; } - bool applicable() const { + bool applicable(QAction*) const { const int indexA = scene->selectionAindex(); const int indexB = scene->selectionBindex(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp index 48ccec330e8..dc5b2502fa6 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp @@ -50,7 +50,7 @@ public: return QList() << actionNormalEstimation << actionNormalInversion; } - bool applicable() const { + bool applicable(QAction*) const { #if CGAL_DISABLE_NORMAL_ESTIMATION_PLUGIN return false; #else diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp index 7ce9e84c45a..f84cc31aae8 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp @@ -23,10 +23,14 @@ public: Scene_interface* scene_interface, Messages_interface* m); - bool applicable() const { + bool applicable(QAction* action) const { Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices()) { if(qobject_cast(scene->item(index))) return true; + else + if (action==actionShuffle && + qobject_cast(scene->item(index))) + return true; } return false; } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp index 8a3855285b5..8b3d53e2718 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp @@ -37,7 +37,7 @@ public: << "actionDCP"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_pca_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_pca_plugin.cpp index b7af60450a6..751bf7d6453 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_pca_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_pca_plugin.cpp @@ -38,7 +38,7 @@ public: << "actionFitLine"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_interface.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_interface.h index 8f0bd1b553d..1e2628ba97c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_interface.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_interface.h @@ -26,7 +26,7 @@ public: //! //! @returns \c true, if the plugin is applicable, \c false //! otherwise - virtual bool applicable() const = 0; + virtual bool applicable(QAction*) const = 0; virtual QList actions() const = 0; }; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp index e5e32426cdf..3da1a232839 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp @@ -36,7 +36,7 @@ class Polyhedron_demo_point_inside_polyhedron_plugin : Q_INTERFACES(Polyhedron_demo_plugin_interface) public: - bool applicable() const + bool applicable(QAction*) const { bool poly_item_exists = false; bool point_item_exists = false; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_average_spacing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_average_spacing_plugin.cpp index 1473fd0fa62..1faac876543 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_average_spacing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_average_spacing_plugin.cpp @@ -39,7 +39,7 @@ public: //! Applicable if the currently selected item is a //! points_with_normal_item. - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp index e827a4776d1..1a8130fb553 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp @@ -36,7 +36,7 @@ public: } //! Applicate for Point_sets with normals. - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp index 38aed1a8f79..81619adce96 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp @@ -34,7 +34,7 @@ public: Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp index b88a73e59f2..bb6001e6390 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp @@ -32,7 +32,7 @@ public: return QList() << actionJetSmoothing; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp index 5fcd45ddeda..9f0926a4b32 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp @@ -40,7 +40,7 @@ public: } //! Applicate for Point_sets with normals. - bool applicable() const { + bool applicable(QAction*) const { Scene_points_with_normal_item* item = qobject_cast(scene->item(scene->mainSelectionIndex())); return item && item->has_normals(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp index 6697ab9a5e8..4a139ee8ef3 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp @@ -35,7 +35,7 @@ class Polyhedron_demo_polyhedron_slicer_plugin : Q_INTERFACES(Polyhedron_demo_plugin_interface) public: - bool applicable() const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } void print_message(QString message) { messages->information(message);} void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* m); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp index 553520e4528..c6b90c21a39 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp @@ -50,7 +50,7 @@ public: Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); } - bool applicable() const { + bool applicable(QAction*) const { Q_FOREACH(int index, scene->selectionIndices()) { if ( qobject_cast(scene->item(index)) ) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp index 88b1172f1bb..03e903f8efe 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp @@ -39,7 +39,7 @@ public: } } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp index a824fe690f3..34c2ed33518 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp @@ -50,7 +50,7 @@ public: } //! Applicate for Point_sets with normals. - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp index 6993b50d879..320871dd063 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp @@ -24,7 +24,7 @@ class Polyhedron_demo_selection_plugin : Q_INTERFACES(Polyhedron_demo_plugin_interface) public: - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp index e69beea7897..a9edbb6413f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp @@ -30,7 +30,7 @@ public: return QStringList() << "actionSelfIntersection"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp index b5a3b4eac6c..4bf357255f6 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp @@ -23,7 +23,7 @@ public: << "actionSqrt3"; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } public slots: diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_transform_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_transform_polyhedron_plugin.cpp index a2585d5080c..408ef6c9859 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_transform_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_transform_polyhedron_plugin.cpp @@ -30,7 +30,7 @@ public: return QList() << actionTransformPolyhedron; } - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp index 89833af3130..e84e76730f3 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp @@ -44,7 +44,7 @@ public: << actionUnTriangulateFacets; } - bool applicable() const { + bool applicable(QAction*) const { Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices()) { Scene_polyhedron_item* item = qobject_cast(scene->item(index)); if(!item) return false; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp index 03b4c6de85d..8bed5d1ad8e 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp @@ -103,7 +103,7 @@ public: return QList() << actionBbox; } - bool applicable() const { + bool applicable(QAction*) const { return true; } public slots: From 2a667cef90993c8b86614d3c1ac4c1c174e5a309 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 16:56:46 +0100 Subject: [PATCH 17/62] Points view fix The size of the data passed to the buffer was too large, noise was passed. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 6b874bb35fd..2f53b13497a 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -97,7 +97,7 @@ Scene_polygon_soup_item::compile_shaders(void) glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_DYNAMIC_DRAW); glVertexAttribPointer(0, //number of the buffer 4, //number of floats to be taken GL_FLOAT, // type of data @@ -106,10 +106,9 @@ Scene_polygon_soup_item::compile_shaders(void) NULL //no offset (seperated in several buffers) ); glEnableVertexAttribArray(0); - //Bind the second and initialize it glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_DYNAMIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); @@ -218,6 +217,7 @@ Scene_polygon_soup_item::compile_shaders(void) glAttachShader(program, fragment_shader); glLinkProgram(program); + glGetProgramiv(program,GL_LINK_STATUS,&result); if(result == GL_TRUE){ std::cout<<"Link OK"<polygons.begin(); it != soup->polygons.end(); ++it) { @@ -352,8 +356,9 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() Scene_polygon_soup_item::~Scene_polygon_soup_item() { - glDeleteBuffers(2, buffer); - glDeleteVertexArrays(1, &vao); + + //glDeleteBuffers(2, buffer); + //glDeleteVertexArrays(1, &vao); glDeleteProgram(rendering_program); delete soup; @@ -525,7 +530,6 @@ void Scene_polygon_soup_item::draw() const { - // tells the GPU to use the program just created glUseProgram(rendering_program); uniform_attrib(); @@ -568,7 +572,7 @@ Scene_polygon_soup_item::draw_points() const { uniform_attrib(); //draw the points - glDrawArrays(GL_POINTS, 0, positions_poly.size()); + glDrawArrays(GL_POINTS, 0, positions_poly.size()/4); //Tells OpenGL not to use the program anymore glUseProgram(0); } From de58fbbc68642f9b27837f08b59cb7b8d272d05e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Feb 2015 17:41:00 +0100 Subject: [PATCH 18/62] Multiple objects rendering fix The buffers was only bound once at the creation of the object, which means that only the last object created had its buffers right. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 2f53b13497a..d2cc08b26f9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -357,8 +357,8 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() Scene_polygon_soup_item::~Scene_polygon_soup_item() { - //glDeleteBuffers(2, buffer); - //glDeleteVertexArrays(1, &vao); + glDeleteBuffers(2, buffer); + glDeleteVertexArrays(1, &vao); glDeleteProgram(rendering_program); delete soup; @@ -529,6 +529,16 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw() const { + //Calls the buffer info again so that it's the right one used even if there are several objects drawn + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_DYNAMIC_DRAW); + glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,0, NULL); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_DYNAMIC_DRAW); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(1); // tells the GPU to use the program just created glUseProgram(rendering_program); @@ -537,7 +547,11 @@ Scene_polygon_soup_item::draw() const { // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); //Tells OpenGL not to use the program anymore + glUseProgram(0); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); } void @@ -566,6 +580,17 @@ Scene_polygon_soup_item::draw_points() const { if(soup == 0) return; + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + + glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_DYNAMIC_DRAW); + glVertexAttribPointer(0,4,GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(0); + //Bind the second and initialize it + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_DYNAMIC_DRAW); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(1); + // tells the GPU to use the program just created glUseProgram(rendering_program); From 911731eceb4fdf4f4ecf69b0ad9b27da13da449f Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 20 Feb 2015 20:00:39 +0100 Subject: [PATCH 19/62] Call compute_normals_and_vertices() in changed() --- Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index d2cc08b26f9..73f6cb3c474 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -380,7 +380,7 @@ Scene_polygon_soup_item::load(std::istream& in) else soup->clear(); bool result = CGAL::read_OFF(in, soup->points, soup->polygons); - compute_normals_and_vertices(); + emit changed(); return result; } @@ -626,7 +626,7 @@ Scene_polygon_soup_item::isEmpty() const { void Scene_polygon_soup_item::changed() { - + compute_normals_and_vertices(); } Scene_polygon_soup_item::Bbox From e16cca10eff7ea45a4588953c74f279c00e5b3ef Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 20 Feb 2015 20:01:34 +0100 Subject: [PATCH 20/62] Call compile_shaders() in the constructor Ideally, the shaders should static variables. --- Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 73f6cb3c474..04c8548b018 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -328,7 +328,6 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ } - rendering_program = compile_shaders(); //Allocates a uniform location for the MVP and MV matrices location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); @@ -352,6 +351,7 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() mvp_mat = new GLfloat[16]; mv_mat = new GLfloat[16]; + rendering_program = compile_shaders(); } Scene_polygon_soup_item::~Scene_polygon_soup_item() From ecea7c3ef6df7cad455458754fc5d938749689bc Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 20 Feb 2015 20:03:40 +0100 Subject: [PATCH 21/62] Split compile_shaders() New function initialize_buffers(), that is called in changed(). compile_shaders() is only call once, in the constructor (but it should be a static initialization). glGenBuffers() and others are also called in the constructor. Add cleanup code at the end of initialize_buffers(). --- .../Polyhedron/Scene_polygon_soup_item.cpp | 52 ++++++++++++------- .../demo/Polyhedron/Scene_polygon_soup_item.h | 1 + 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 04c8548b018..e4edfdb78f3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -84,20 +84,16 @@ struct Polyhedron_to_polygon_soup_writer { } }; // end struct Polyhedron_to_soup_writer -GLuint -Scene_polygon_soup_item::compile_shaders(void) +void +Scene_polygon_soup_item::initialize_buffers() { - - - - glGenVertexArrays(1, &vao); glBindVertexArray(vao); - //Generates an integer which will be used as ID for each buffer - glGenBuffers(2, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - - glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, + (positions_poly.size())*sizeof(positions_poly.data()), + positions_poly.data(), + GL_STATIC_DRAW); glVertexAttribPointer(0, //number of the buffer 4, //number of floats to be taken GL_FLOAT, // type of data @@ -105,14 +101,26 @@ Scene_polygon_soup_item::compile_shaders(void) 0, //compact data (not in a struct) NULL //no offset (seperated in several buffers) ); - glEnableVertexAttribArray(0); - //Bind the second and initialize it + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_DYNAMIC_DRAW); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(1); - + glBufferData(GL_ARRAY_BUFFER, + (normals.size())*sizeof(normals.data()), + normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(1, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + // Clean-up + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} +GLuint +Scene_polygon_soup_item::compile_shaders(void) +{ //fill the vertex shader static const GLchar* vertex_shader_source[] = { @@ -347,16 +355,15 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() soup(0),positions_poly(0), normals(0), oriented(false) { - glewInit(); - mvp_mat = new GLfloat[16]; - mv_mat = new GLfloat[16]; + glGenVertexArrays(1, &vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(2, buffer); rendering_program = compile_shaders(); } Scene_polygon_soup_item::~Scene_polygon_soup_item() { - glDeleteBuffers(2, buffer); glDeleteVertexArrays(1, &vao); glDeleteProgram(rendering_program); @@ -627,6 +634,7 @@ void Scene_polygon_soup_item::changed() { compute_normals_and_vertices(); + initialize_buffers(); } Scene_polygon_soup_item::Bbox @@ -666,3 +674,7 @@ Scene_polygon_soup_item::new_triangle(const std::size_t i, } #include "Scene_polygon_soup_item.moc" + +// Local Variables: +// c-basic-offset: 4 +// End: diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 3c03895a52d..7c725a9c50c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -178,6 +178,7 @@ private: GLuint program; GLuint vao; GLuint buffer[2]; + void initialize_buffers(); GLuint compile_shaders(void); void compute_normals_and_vertices(void); void uniform_attrib(void) const; From 27a5ff51b55eae03ab05115faa818de2f6169f69 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 20 Feb 2015 20:10:33 +0100 Subject: [PATCH 22/62] Cleaner drawing code uniform_attrib() takes the viewer as argument. That way, `mvp_mat` and `mv_mat` can be local variables of the method. The two drawing method draw() and draw_points() both take the viewer as argument, and no longer setup the buffers (they only use them). Add cleanup code at the end of the drawing methods. (See ../../../Mesh_3/demo/Mesh_3/Scene_segmented_image_item.cpp for a very clean OpenGL code.) --- .../Polyhedron/Scene_polygon_soup_item.cpp | 100 +++++++----------- .../demo/Polyhedron/Scene_polygon_soup_item.h | 7 +- 2 files changed, 42 insertions(+), 65 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index e4edfdb78f3..957101fee78 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -245,19 +245,32 @@ Scene_polygon_soup_item::compile_shaders(void) return program; } void -Scene_polygon_soup_item::uniform_attrib(void) const +Scene_polygon_soup_item::uniform_attrib(Viewer_interface* viewer) const { GLfloat colors[4]; 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]); + glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); //fills the arraw of colors with the current color - GLfloat temp[4]; - glGetFloatv(GL_CURRENT_COLOR, temp); - for(int i=0; i<4; i++) - colors[i] = temp[i]; + glGetFloatv(GL_CURRENT_COLOR, colors); + //Gets lighting info : //position @@ -534,97 +547,64 @@ Scene_polygon_soup_item::toolTip() const } void -Scene_polygon_soup_item::draw() const { +Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { + if(soup == 0) return; - //Calls the buffer info again so that it's the right one used even if there are several objects drawn + //Calls the buffer info again so that it's the right one used even if + //there are several objects drawn + + glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_DYNAMIC_DRAW); - glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,0, NULL); glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_DYNAMIC_DRAW); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); // tells the GPU to use the program just created glUseProgram(rendering_program); - uniform_attrib(); + uniform_attrib(viewer); //draw the polygons // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); //Tells OpenGL not to use the program anymore + // Clean-up glUseProgram(0); - - glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } void -Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { - - - //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]); - - - draw(); -} - -void -Scene_polygon_soup_item::draw_points() const { - - +Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { if(soup == 0) return; - glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBindVertexArray(vao); - glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(positions_poly.data()), positions_poly.data(), GL_DYNAMIC_DRAW); - glVertexAttribPointer(0,4,GL_FLOAT, GL_FALSE, 0, NULL); + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glEnableVertexAttribArray(0); //Bind the second and initialize it glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glBufferData(GL_ARRAY_BUFFER, (normals.size())*sizeof(normals.data()), normals.data(), GL_DYNAMIC_DRAW); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); // tells the GPU to use the program just created glUseProgram(rendering_program); - uniform_attrib(); + uniform_attrib(viewer); //draw the points glDrawArrays(GL_POINTS, 0, positions_poly.size()/4); - //Tells OpenGL not to use the program anymore + + // Clean-up glUseProgram(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } -void -Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { - //fills the MVP Matrix - 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]); - - - draw_points(); -} bool Scene_polygon_soup_item::isEmpty() const { diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 7c725a9c50c..173911379f3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -137,9 +137,8 @@ public: // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! // OpenGL drawing in a display list - void draw() const; + void draw() const {} void draw(Viewer_interface*) const; - void draw_points() const; void draw_points(Viewer_interface*) const; void changed(); bool isFinite() const { return true; } @@ -169,8 +168,6 @@ private: GLuint rendering_program; GLint location[8]; - GLfloat *mvp_mat; - GLfloat *mv_mat; GLuint vertex_shader; @@ -181,7 +178,7 @@ private: void initialize_buffers(); GLuint compile_shaders(void); void compute_normals_and_vertices(void); - void uniform_attrib(void) const; + void uniform_attrib(Viewer_interface*) const; }; // end class Scene_polygon_soup_item From 9fd3d43aa27c8b1000764755cec0a2092bbcf6d2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 23 Feb 2015 16:14:05 +0100 Subject: [PATCH 23/62] First upgrade of polyhedron item Now using a shader to draw. Remaining a strange bug in which gouraud and flat modes are exchanged. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 3 - .../demo/Polyhedron/Scene_polyhedron_item.cpp | 1040 ++++++++++++----- .../demo/Polyhedron/Scene_polyhedron_item.h | 32 +- 3 files changed, 780 insertions(+), 295 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 957101fee78..f8ea9d49e88 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -140,7 +140,6 @@ Scene_polygon_soup_item::compile_shaders(void) "float spec_power = 0.0; \n" "out highp vec3 fColors; \n" - "out highp vec3 fNormals; \n" " \n" "void main(void) \n" @@ -165,7 +164,6 @@ Scene_polygon_soup_item::compile_shaders(void) "fColors = light_amb + diffuse + specular ; \n" "gl_Position = mvp_matrix * positions_poly; \n" - "fNormals = vNormals; \n" "} \n" }; //fill the fragment shader @@ -174,7 +172,6 @@ Scene_polygon_soup_item::compile_shaders(void) "#version 300 es \n" " \n" "in highp vec3 fColors; \n" - "in highp vec3 fNormals; \n" "out highp vec3 color; \n" " \n" diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 1ef110f8c51..aceafb719a5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -10,6 +10,7 @@ #include #include +#include typedef CGAL::AABB_face_graph_triangle_primitive Primitive; typedef CGAL::AABB_traits AABB_traits; @@ -19,38 +20,38 @@ const char* aabb_property_name = "Scene_polyhedron_item aabb tree"; Input_facets_AABB_tree* get_aabb_tree(Scene_polyhedron_item* item) { - QVariant aabb_tree_property = item->property(aabb_property_name); - if(aabb_tree_property.isValid()) { - void* ptr = aabb_tree_property.value(); - return static_cast(ptr); - } - else { - Polyhedron* poly = item->polyhedron(); - if(poly) { - Input_facets_AABB_tree* tree = - new Input_facets_AABB_tree(faces(*poly).first, - faces(*poly).second, - *poly); - item->setProperty(aabb_property_name, - QVariant::fromValue(tree)); - return tree; + QVariant aabb_tree_property = item->property(aabb_property_name); + if(aabb_tree_property.isValid()) { + void* ptr = aabb_tree_property.value(); + return static_cast(ptr); + } + else { + Polyhedron* poly = item->polyhedron(); + if(poly) { + Input_facets_AABB_tree* tree = + new Input_facets_AABB_tree(faces(*poly).first, + faces(*poly).second, + *poly); + item->setProperty(aabb_property_name, + QVariant::fromValue(tree)); + return tree; + } + else return 0; } - else return 0; - } } void delete_aabb_tree(Scene_polyhedron_item* item) { - QVariant aabb_tree_property = item->property(aabb_property_name); - if(aabb_tree_property.isValid()) { - void* ptr = aabb_tree_property.value(); - Input_facets_AABB_tree* tree = static_cast(ptr); - if(tree) { - delete tree; - tree = 0; + QVariant aabb_tree_property = item->property(aabb_property_name); + if(aabb_tree_property.isValid()) { + void* ptr = aabb_tree_property.value(); + Input_facets_AABB_tree* tree = static_cast(ptr); + if(tree) { + delete tree; + tree = 0; + } + item->setProperty(aabb_property_name, QVariant()); } - item->setProperty(aabb_property_name, QVariant()); - } } #include @@ -58,41 +59,473 @@ void delete_aabb_tree(Scene_polyhedron_item* item) #include #include -Scene_polyhedron_item::Scene_polyhedron_item() - : Scene_item_with_display_list(), - poly(new Polyhedron), - show_only_feature_edges_m(false), - facet_picking_m(false), - erase_next_picked_facet_m(false), - plugin_has_set_color_vector_m(false) +struct light_info { - //init(); + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; + GLfloat spec_power; + +}; + +void +Scene_polyhedron_item::initialize_buffers() +{ + + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_facets.size())*sizeof(positions_facets.data()), + positions_facets.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) + ); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + glBufferData(GL_ARRAY_BUFFER, + (positions_lines.size())*sizeof(positions_lines.data()), + positions_lines.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) + ); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); + glBufferData(GL_ARRAY_BUFFER, + (normals.size())*sizeof(normals.data()), + normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + + // Clean-up + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + +} + +GLuint +Scene_polyhedron_item::compile_shaders(void) +{ + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec4 positions_facets; \n" + "layout (location = 1) in vec4 positions_lines; \n" + "layout (location = 2) in vec3 vNormals; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform mat4 mv_matrix; \n" + + "uniform int is_two_side; \n" + "uniform int is_wire; \n" + "uniform vec3 vColors; \n" + "uniform vec3 light_pos; \n" + "uniform vec3 light_diff; \n" + "uniform vec3 light_spec; \n" + "uniform vec3 light_amb; \n" + "float spec_power = 0.0; \n" + + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + "vec4 P; \n" + "vec3 N; \n" + "vec3 L; \n" + "vec3 V; \n" + "vec3 R; \n" + "if(is_wire !=6913){ \n" //number for the mode wireframe + " P = mv_matrix * positions_facets; \n" + " N = mat3(mv_matrix)* vNormals; \n" + " L = light_pos - P.xyz; \n" + " V = -P.xyz; \n" + + " N = normalize(N); \n" + " L = normalize(L); \n" + " V = normalize(V); \n" + + " 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" + "else{ \n" + " fColors = vColors; \n" + " gl_Position = mvp_matrix * positions_lines;} \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" + "/* Lighting gestion */ \n" + " color = fColors; \n" //polygons de couleur rouge + "} \n" + }; + + //creates and compiles the vertex shader + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); + glCompileShader(vertex_shader); + + GLint result; + glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); + if(result == GL_TRUE){ + std::cout<<"Vertex compilation OK"<facets_begin(), end = poly->facets_end() ; - fit != end; ++fit) + typedef Polyhedron::Facet_iterator Facet_iterator; + + if ( !plugin_has_set_color_vector_m ) { - max = (std::max)(max, fit->patch_id()); + // Fill indices map and get max subdomain value + int max = 0; + for(Facet_iterator fit = poly->facets_begin(), end = poly->facets_end() ; + fit != end; ++fit) + { + max = (std::max)(max, fit->patch_id()); + } + + colors_.clear(); + compute_color_map(this->color(), max + 1, + std::back_inserter(colors_)); } - - colors_.clear(); - compute_color_map(this->color(), max + 1, - std::back_inserter(colors_)); - } } Scene_polyhedron_item* Scene_polyhedron_item::clone() const { - return new Scene_polyhedron_item(*poly); -} + return new Scene_polyhedron_item(*poly);} // Load polyhedron from .OFF file bool Scene_polyhedron_item::load(std::istream& in) { - in >> *poly; - - if ( in && !isEmpty() ) - { - changed(); - return true; - } - return false; + in >> *poly; + + if ( in && !isEmpty() ) + { + changed(); + return true; + } + return false; } // Write polyhedron to .OFF file bool Scene_polyhedron_item::save(std::ostream& out) const { - out.precision(13); - out << *poly; - return (bool) out; + out.precision(13); + out << *poly; + return (bool) out; } QString Scene_polyhedron_item::toolTip() const { - if(!poly) - return QString(); + if(!poly) + return QString(); - return QObject::tr("

Polyhedron %1 (mode: %5, color: %6)

" - "

Number of vertices: %2
" - "Number of edges: %3
" - "Number of facets: %4

") - .arg(this->name()) - .arg(poly->size_of_vertices()) - .arg(poly->size_of_halfedges()/2) - .arg(poly->size_of_facets()) - .arg(this->renderingModeName()) - .arg(this->color().name()); + return QObject::tr("

Polyhedron %1 (mode: %5, color: %6)

" + "

Number of vertices: %2
" + "Number of edges: %3
" + "Number of facets: %4

") + .arg(this->name()) + .arg(poly->size_of_vertices()) + .arg(poly->size_of_halfedges()/2) + .arg(poly->size_of_facets()) + .arg(this->renderingModeName()) + .arg(this->color().name()); } QMenu* Scene_polyhedron_item::contextMenu() { - const char* prop_name = "Menu modified by Scene_polyhedron_item."; + const char* prop_name = "Menu modified by Scene_polyhedron_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) { + if(!menuChanged) { - QAction* actionShowOnlyFeatureEdges = - menu->addAction(tr("Show only &feature edges")); - actionShowOnlyFeatureEdges->setCheckable(true); - actionShowOnlyFeatureEdges->setObjectName("actionShowOnlyFeatureEdges"); - connect(actionShowOnlyFeatureEdges, SIGNAL(toggled(bool)), - this, SLOT(show_only_feature_edges(bool))); + QAction* actionShowOnlyFeatureEdges = + menu->addAction(tr("Show only &feature edges")); + actionShowOnlyFeatureEdges->setCheckable(true); + actionShowOnlyFeatureEdges->setObjectName("actionShowOnlyFeatureEdges"); + connect(actionShowOnlyFeatureEdges, SIGNAL(toggled(bool)), + this, SLOT(show_only_feature_edges(bool))); - QAction* actionPickFacets = - menu->addAction(tr("Facets picking")); - actionPickFacets->setCheckable(true); - actionPickFacets->setObjectName("actionPickFacets"); - connect(actionPickFacets, SIGNAL(toggled(bool)), - this, SLOT(enable_facets_picking(bool))); + QAction* actionPickFacets = + menu->addAction(tr("Facets picking")); + actionPickFacets->setCheckable(true); + actionPickFacets->setObjectName("actionPickFacets"); + connect(actionPickFacets, SIGNAL(toggled(bool)), + this, SLOT(enable_facets_picking(bool))); - QAction* actionEraseNextFacet = - menu->addAction(tr("Erase next picked facet")); - actionEraseNextFacet->setCheckable(true); - actionEraseNextFacet->setObjectName("actionEraseNextFacet"); - connect(actionEraseNextFacet, SIGNAL(toggled(bool)), - this, SLOT(set_erase_next_picked_facet(bool))); + QAction* actionEraseNextFacet = + menu->addAction(tr("Erase next picked facet")); + actionEraseNextFacet->setCheckable(true); + actionEraseNextFacet->setObjectName("actionEraseNextFacet"); + connect(actionEraseNextFacet, SIGNAL(toggled(bool)), + this, SLOT(set_erase_next_picked_facet(bool))); - menu->setProperty(prop_name, true); - } - QAction* action = menu->findChild("actionPickFacets"); - if(action) action->setChecked(facet_picking_m); - action = menu->findChild("actionEraseNextFacet"); - if(action) action->setChecked(erase_next_picked_facet_m); - return menu; + menu->setProperty(prop_name, true); + } + QAction* action = menu->findChild("actionPickFacets"); + if(action) action->setChecked(facet_picking_m); + action = menu->findChild("actionEraseNextFacet"); + if(action) action->setChecked(erase_next_picked_facet_m); + return menu; } void Scene_polyhedron_item::show_only_feature_edges(bool b) { - show_only_feature_edges_m = b; - emit itemChanged(); + show_only_feature_edges_m = b; + emit itemChanged(); } void Scene_polyhedron_item::enable_facets_picking(bool b) { - facet_picking_m = b; + facet_picking_m = b; } void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) { - if(b) { facet_picking_m = true; } // automatically activate facet_picking - erase_next_picked_facet_m = b; + if(b) { facet_picking_m = true; } // automatically activate facet_picking + erase_next_picked_facet_m = b; } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list -void Scene_polyhedron_item::direct_draw() const { - gl_render_facets(*poly,colors_); +void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { + + glBindVertexArray(vao); + + //Binds the buffer used for the flat and gouraud rendering + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glEnableVertexAttribArray(0); + //Binds the buffer used for normals + glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); + glEnableVertexAttribArray(2); + + // tells the GPU to use the program just created + glUseProgram(rendering_program); + uniform_attrib(viewer); + //draw the polygons + // the third argument is the number of vec4 that will be entered + + + glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); + + //Tells OpenGL not to use the program anymore + + // Clean-up + glUseProgram(0); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + //gl_render_facets(*poly,colors_); } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list -void Scene_polyhedron_item::direct_draw_edges() const { - typedef Kernel::Point_3 Point; - typedef Polyhedron::Edge_iterator Edge_iterator; +void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { + glBindVertexArray(vao); - ::glBegin(GL_LINES); - Edge_iterator he; - if(!show_only_feature_edges_m) { - for(he = poly->edges_begin(); - he != poly->edges_end(); - he++) - { - if(he->is_feature_edge()) continue; - const Point& a = he->vertex()->point(); - const Point& b = he->opposite()->vertex()->point(); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - } - } - ::glColor3d(1.0, 0.0, 0.0); - for(he = poly->edges_begin(); - he != poly->edges_end(); - he++) - { - if(!he->is_feature_edge()) continue; - const Point& a = he->vertex()->point(); - const Point& b = he->opposite()->vertex()->point(); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - } - ::glEnd(); + //Binds the buffer used for the wireframe rendering + glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); + glEnableVertexAttribArray(2); + + // tells the GPU to use the program just created + glUseProgram(rendering_program); + + uniform_attrib(viewer); + + //draw the edges + glDrawArrays(GL_LINES, 0, positions_lines.size()/4); + // Clean-up + glUseProgram(0); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } +/*void Scene_polyhedron_item::direct_draw_edges(Viewer_interface* viewer) const { + + direct_draw_edges(); +}*/ + Polyhedron* Scene_polyhedron_item::polyhedron() { return poly; } const Polyhedron* @@ -279,20 +742,20 @@ Scene_polyhedron_item::polyhedron() const { return poly; } bool Scene_polyhedron_item::isEmpty() const { - return (poly == 0) || poly->empty(); + return (poly == 0) || poly->empty(); } Scene_polyhedron_item::Bbox Scene_polyhedron_item::bbox() const { - const Kernel::Point_3& p = *(poly->points_begin()); - CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); - for(Polyhedron::Point_iterator it = poly->points_begin(); - it != poly->points_end(); - ++it) { - bbox = bbox + it->bbox(); - } - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + const Kernel::Point_3& p = *(poly->points_begin()); + CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); + for(Polyhedron::Point_iterator it = poly->points_begin(); + it != poly->points_end(); + ++it) { + bbox = bbox + it->bbox(); + } + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); } @@ -300,10 +763,13 @@ void Scene_polyhedron_item:: changed() { - emit item_is_about_to_be_changed(); - delete_aabb_tree(this); - init(); - Base::changed(); + std::cout<<"changed"< Intersections; - Intersections intersections; + typedef std::list Intersections; + Intersections intersections; - aabb_tree->all_intersections(ray, std::back_inserter(intersections)); + aabb_tree->all_intersections(ray, std::back_inserter(intersections)); - Intersections::iterator closest = intersections.begin(); - if(closest != intersections.end()) { - const Kernel::Point_3* closest_point = - CGAL::object_cast(&closest->first); + Intersections::iterator closest = intersections.begin(); + if(closest != intersections.end()) { + const Kernel::Point_3* closest_point = + CGAL::object_cast(&closest->first); - for(Intersections::iterator - it = boost::next(intersections.begin()), - end = intersections.end(); - it != end; ++it) - { - if(! closest_point) { - closest = it; - } - else { - const Kernel::Point_3* it_point = - CGAL::object_cast(&it->first); - if(it_point && - (ray_dir * (*it_point - *closest_point)) < 0) - { - closest = it; - closest_point = it_point; + for(Intersections::iterator + it = boost::next(intersections.begin()), + end = intersections.end(); + it != end; ++it) + { + if(! closest_point) { + closest = it; + } + else { + const Kernel::Point_3* it_point = + CGAL::object_cast(&it->first); + if(it_point && + (ray_dir * (*it_point - *closest_point)) < 0) + { + closest = it; + closest_point = it_point; + } + } + } + if(closest_point) { + Polyhedron::Facet_handle selected_fh = closest->second; + + // The computation of the nearest vertex may be costly. Only + // do it if some objects are connected to the signal + // 'selected_vertex'. + if(QObject::receivers(SIGNAL(selected_vertex(void*))) > 0) + { + Polyhedron::Halfedge_around_facet_circulator + he_it = selected_fh->facet_begin(), + around_end = he_it; + + Polyhedron::Vertex_handle v = he_it->vertex(), nearest_v = v; + + Kernel::FT sq_dist = CGAL::squared_distance(*closest_point, + v->point()); + + while(++he_it != around_end) { + v = he_it->vertex(); + Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point, + v->point()); + if(new_sq_dist < sq_dist) { + sq_dist = new_sq_dist; + nearest_v = v; + } + } + + emit selected_vertex((void*)(&*nearest_v)); + } + + if(QObject::receivers(SIGNAL(selected_edge(void*))) > 0 + || QObject::receivers(SIGNAL(selected_halfedge(void*))) > 0) + { + Polyhedron::Halfedge_around_facet_circulator + he_it = selected_fh->facet_begin(), + around_end = he_it; + + Polyhedron::Halfedge_handle nearest_h = he_it; + Kernel::FT sq_dist = CGAL::squared_distance(*closest_point, + Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point())); + + while(++he_it != around_end) { + Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point, + Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point())); + if(new_sq_dist < sq_dist) { + sq_dist = new_sq_dist; + nearest_h = he_it; + } + } + + emit selected_halfedge((void*)(&*nearest_h)); + emit selected_edge((void*)(std::min)(&*nearest_h, &*nearest_h->opposite())); + } + + emit selected_facet((void*)(&*selected_fh)); + if(erase_next_picked_facet_m) { + polyhedron()->erase_facet(selected_fh->halfedge()); + polyhedron()->normalize_border(); + //set_erase_next_picked_facet(false); + changed(); + emit itemChanged(); + } + } } - } } - if(closest_point) { - Polyhedron::Facet_handle selected_fh = closest->second; - - // The computation of the nearest vertex may be costly. Only - // do it if some objects are connected to the signal - // 'selected_vertex'. - if(QObject::receivers(SIGNAL(selected_vertex(void*))) > 0) - { - Polyhedron::Halfedge_around_facet_circulator - he_it = selected_fh->facet_begin(), - around_end = he_it; - - Polyhedron::Vertex_handle v = he_it->vertex(), nearest_v = v; - - Kernel::FT sq_dist = CGAL::squared_distance(*closest_point, - v->point()); - - while(++he_it != around_end) { - v = he_it->vertex(); - Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point, - v->point()); - if(new_sq_dist < sq_dist) { - sq_dist = new_sq_dist; - nearest_v = v; - } - } - - emit selected_vertex((void*)(&*nearest_v)); - } - - if(QObject::receivers(SIGNAL(selected_edge(void*))) > 0 - || QObject::receivers(SIGNAL(selected_halfedge(void*))) > 0) - { - Polyhedron::Halfedge_around_facet_circulator - he_it = selected_fh->facet_begin(), - around_end = he_it; - - Polyhedron::Halfedge_handle nearest_h = he_it; - Kernel::FT sq_dist = CGAL::squared_distance(*closest_point, - Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point())); - - while(++he_it != around_end) { - Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point, - Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point())); - if(new_sq_dist < sq_dist) { - sq_dist = new_sq_dist; - nearest_h = he_it; - } - } - - emit selected_halfedge((void*)(&*nearest_h)); - emit selected_edge((void*)(std::min)(&*nearest_h, &*nearest_h->opposite())); - } - - emit selected_facet((void*)(&*selected_fh)); - if(erase_next_picked_facet_m) { - polyhedron()->erase_facet(selected_fh->halfedge()); - polyhedron()->normalize_border(); - //set_erase_next_picked_facet(false); - changed(); - emit itemChanged(); - } - } - } } - } - Base::select(orig_x, orig_y, orig_z, dir_x, dir_y, dir_z); + Base::select(orig_x, orig_y, orig_z, dir_x, dir_y, dir_z); } void Scene_polyhedron_item::update_vertex_indices() { - std::size_t id=0; - for (Polyhedron::Vertex_iterator vit = polyhedron()->vertices_begin(), - vit_end = polyhedron()->vertices_end(); vit != vit_end; ++vit) - { - vit->id()=id++; - } + std::size_t id=0; + for (Polyhedron::Vertex_iterator vit = polyhedron()->vertices_begin(), + vit_end = polyhedron()->vertices_end(); vit != vit_end; ++vit) + { + vit->id()=id++; + } } void Scene_polyhedron_item::update_facet_indices() { - std::size_t id=0; - for (Polyhedron::Facet_iterator fit = polyhedron()->facets_begin(), - fit_end = polyhedron()->facets_end(); fit != fit_end; ++fit) - { - fit->id()=id++; - } + std::size_t id=0; + for (Polyhedron::Facet_iterator fit = polyhedron()->facets_begin(), + fit_end = polyhedron()->facets_end(); fit != fit_end; ++fit) + { + fit->id()=id++; + } } void Scene_polyhedron_item::update_halfedge_indices() { - std::size_t id=0; - for (Polyhedron::Halfedge_iterator hit = polyhedron()->halfedges_begin(), - hit_end = polyhedron()->halfedges_end(); hit != hit_end; ++hit) - { - hit->id()=id++; - } + std::size_t id=0; + for (Polyhedron::Halfedge_iterator hit = polyhedron()->halfedges_begin(), + hit_end = polyhedron()->halfedges_end(); hit != hit_end; ++hit) + { + hit->id()=id++; + } } #include "Scene_polyhedron_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index ca522dee9aa..e1bdf9921a4 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -1,9 +1,11 @@ #ifndef SCENE_POLYHEDRON_ITEM_H #define SCENE_POLYHEDRON_ITEM_H +#include #include "Scene_polyhedron_item_config.h" -#include "Scene_item_with_display_list.h" +#include "Scene_item.h" //<- modif ? #include "Polyhedron_type_fwd.h" +#include "Viewer.h" #include #include @@ -15,7 +17,7 @@ class QMenu; // This class represents a polyhedron in the OpenGL scene class SCENE_POLYHEDRON_ITEM_EXPORT Scene_polyhedron_item - : public Scene_item_with_display_list { + : public Scene_item{ Q_OBJECT public: Scene_polyhedron_item(); @@ -39,8 +41,10 @@ public: // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list - virtual void direct_draw() const; - virtual void direct_draw_edges() const; + void draw() const {} + virtual void draw(Viewer_interface*) const; + virtual void draw_edges() const {} +virtual void draw_edges(Viewer_interface* viewer) const; // Get wrapped polyhedron Polyhedron* polyhedron(); @@ -85,7 +89,7 @@ private: Polyhedron* poly; private: - typedef Scene_item_with_display_list Base; + typedef Scene_item Base; typedef std::vector Color_vector; Color_vector colors_; @@ -95,6 +99,24 @@ private: bool erase_next_picked_facet_m; //the following variable is used to indicate if the color vector must not be automatically updated. bool plugin_has_set_color_vector_m; + + std::vector positions_lines; + std::vector positions_facets; + std::vector normals; + + GLuint rendering_program; + GLint location[9]; + + + GLuint vertex_shader; + GLuint fragment_shader; + GLuint program; + GLuint vao; + GLuint buffer[3]; + void initialize_buffers(); // a mettre a jour + GLuint compile_shaders(void); //a mettre a jour + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*) const;//fini }; // end class Scene_polyhedron_item #endif // SCENE_POLYHEDRON_ITEM_H From d20b7d3ce3e8070ff8f60643fdc4b36135a37ae6 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 24 Feb 2015 12:33:09 +0100 Subject: [PATCH 24/62] Better use of Vertex Array Object Once the VAO is fully set up, the drawing functions only have to bind it and unbind it. No need to bind/unbind and setup the VBOs. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index f8ea9d49e88..7212a323ca7 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -101,6 +101,7 @@ Scene_polygon_soup_item::initialize_buffers() 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, @@ -113,9 +114,10 @@ Scene_polygon_soup_item::initialize_buffers() 0, NULL ); + glEnableVertexAttribArray(1); + // Clean-up - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + glBindVertexArray(0); } GLuint @@ -549,18 +551,13 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { //Calls the buffer info again so that it's the right one used even if //there are several objects drawn - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - glEnableVertexAttribArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glEnableVertexAttribArray(1); - // tells the GPU to use the program just created glUseProgram(rendering_program); + uniform_attrib(viewer); + //draw the polygons // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); @@ -568,9 +565,6 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { // Clean-up glUseProgram(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } @@ -580,12 +574,6 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - glEnableVertexAttribArray(0); - //Bind the second and initialize it - glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glEnableVertexAttribArray(1); - // tells the GPU to use the program just created glUseProgram(rendering_program); @@ -595,10 +583,6 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { glDrawArrays(GL_POINTS, 0, positions_poly.size()/4); // Clean-up - glUseProgram(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } From cae8bd242c7e9f545ee1a9883e91c83c7a252a68 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 24 Feb 2015 15:04:43 +0100 Subject: [PATCH 25/62] Just to test the magic cout is at line 326. --- Polyhedron/demo/Polyhedron/Scene.cpp | 1 + Polyhedron/demo/Polyhedron/Scene_item.cpp | 110 +++++----- Polyhedron/demo/Polyhedron/Scene_item.h | 5 +- .../Polyhedron/Scene_polygon_soup_item.cpp | 4 +- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 192 ++++++++++++------ .../demo/Polyhedron/Scene_polyhedron_item.h | 13 +- 6 files changed, 205 insertions(+), 120 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 1def3840171..85778f72330 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -297,6 +297,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) else ::glShadeModel(GL_FLAT); + item.shading_mode_changed(); if(CGAL::check_gl_error(__FILE__, __LINE__)) { std::cerr << "GL error was before the drawing of the item \"" << qPrintable(item.name()) << "\"\n" diff --git a/Polyhedron/demo/Polyhedron/Scene_item.cpp b/Polyhedron/demo/Polyhedron/Scene_item.cpp index c20f3189257..0942192fb73 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_item.cpp @@ -5,97 +5,101 @@ const QColor Scene_item::defaultColor = QColor(100, 100, 255); Scene_item::~Scene_item() { - delete defaultContextMenu; + delete defaultContextMenu; } void Scene_item::itemAboutToBeDestroyed(Scene_item* item) { - if(this == item) - emit aboutToBeDestroyed(); + if(this == item) + emit aboutToBeDestroyed(); } QString modeName(RenderingMode mode) { - switch(mode) - { + switch(mode) + { case Points: - return QObject::tr("points"); + return QObject::tr("points"); case Wireframe: - return QObject::tr("wire"); + return QObject::tr("wire"); case Flat: - return QObject::tr("flat"); + return QObject::tr("flat"); case FlatPlusEdges: - return QObject::tr("flat+edges"); + return QObject::tr("flat+edges"); case Gouraud: - return QObject::tr("Gouraud"); + return QObject::tr("Gouraud"); case PointsPlusNormals: - return QObject::tr("pts+normals"); + return QObject::tr("pts+normals"); case Splatting: - return QObject::tr("splats"); + return QObject::tr("splats"); default: - Q_ASSERT(false); - return QObject::tr("unknown"); - } + Q_ASSERT(false); + return QObject::tr("unknown"); + } } const char* slotName(RenderingMode mode) { - switch(mode) - { + switch(mode) + { case Points: - return SLOT(setPointsMode()); + return SLOT(setPointsMode()); case Wireframe: - return SLOT(setWireframeMode()); + return SLOT(setWireframeMode()); case Flat: - return SLOT(setFlatMode()); + return SLOT(setFlatMode()); case FlatPlusEdges: - return SLOT(setFlatPlusEdgesMode()); + return SLOT(setFlatPlusEdgesMode()); case Gouraud: - return SLOT(setGouraudMode()); + return SLOT(setGouraudMode()); case PointsPlusNormals: - return SLOT(setPointsPlusNormalsMode()); + return SLOT(setPointsPlusNormalsMode()); case Splatting: - return SLOT(setSplattingMode()); + return SLOT(setSplattingMode()); default: - Q_ASSERT(false); - return ""; - } + Q_ASSERT(false); + return ""; + } } // Rendering mode as a human readable string QString Scene_item::renderingModeName() const { - return modeName(renderingMode()); + return modeName(renderingMode()); } QMenu* Scene_item::contextMenu() { - if(defaultContextMenu) { - defaultContextMenu->setTitle(name()); - return defaultContextMenu; - } + if(defaultContextMenu) { + defaultContextMenu->setTitle(name()); + return defaultContextMenu; + } - defaultContextMenu = new QMenu(name()); - // defaultContextMenu->addAction(name()); - // defaultContextMenu->addSeparator(); - // QMenu* modeMenu = new QMenu(QObject::tr("Rendering mode"), - // defaultContextMenu); - for(unsigned int mode = 0; mode < NumberOfRenderingMode; - ++mode) - { - if(!supportsRenderingMode(RenderingMode(mode))) continue; - QString mName = modeName(RenderingMode(mode)); - QAction* action = - defaultContextMenu->addAction(tr("Set %1 mode") - .arg(mName), - this, - slotName(RenderingMode(mode))); - QObject::connect(action, SIGNAL(triggered()), - this, SIGNAL(itemChanged())); - } - // defaultContextMenu->addAction(modeMenu->menuAction()); - return defaultContextMenu; + defaultContextMenu = new QMenu(name()); + // defaultContextMenu->addAction(name()); + // defaultContextMenu->addSeparator(); + // QMenu* modeMenu = new QMenu(QObject::tr("Rendering mode"), + // defaultContextMenu); + for(unsigned int mode = 0; mode < NumberOfRenderingMode; + ++mode) + { + if(!supportsRenderingMode(RenderingMode(mode))) continue; + QString mName = modeName(RenderingMode(mode)); + QAction* action = + defaultContextMenu->addAction(tr("Set %1 mode") + .arg(mName), + this, + slotName(RenderingMode(mode))); + QObject::connect(action, SIGNAL(triggered()), + this, SIGNAL(itemChanged())); + } + // defaultContextMenu->addAction(modeMenu->menuAction()); + return defaultContextMenu; } void Scene_item::changed() { - // emit itemChanged(); + // emit itemChanged(); +} +void Scene_item::shading_mode_changed() +{ + } void Scene_item::select(double /*orig_x*/, diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 183b6d07717..3074d4662de 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -1,6 +1,5 @@ #ifndef SCENE_ITEM_H #define SCENE_ITEM_H - #include "Scene_item_config.h" #include "Scene_interface.h" #include @@ -85,6 +84,7 @@ public slots: // Call that once you have finished changing something in the item // (either the properties or internal data) virtual void changed(); + virtual void shading_mode_changed(); // Setters for the four basic properties virtual void setColor(QColor c) { color_ = c; } @@ -150,6 +150,9 @@ protected: RenderingMode rendering_mode; QMenu* defaultContextMenu; + int prev_shading; + int cur_shading; + }; // end class Scene_item diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 7212a323ca7..5e407ebc6a9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -134,7 +134,6 @@ Scene_polygon_soup_item::compile_shaders(void) "uniform mat4 mv_matrix; \n" "uniform int is_two_side; \n" - "uniform vec3 vColors; \n" "uniform vec3 light_pos; \n" "uniform vec3 light_diff; \n" "uniform vec3 light_spec; \n" @@ -301,7 +300,6 @@ Scene_polygon_soup_item::uniform_attrib(Viewer_interface* viewer) const glUniform3fv(location[3], 1, light.diffuse); glUniform3fv(location[4], 1, light.specular); glUniform3fv(location[5], 1, light.ambient); - glUniform3fv(location[6], 1, colors); glUniform1i(location[7], is_both_sides); } @@ -357,7 +355,7 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ location[3] = glGetUniformLocation(rendering_program, "light_diff"); location[4] = glGetUniformLocation(rendering_program, "light_spec"); location[5] = glGetUniformLocation(rendering_program, "light_amb"); - location[6] = glGetUniformLocation(rendering_program, "vColors"); + // location[6] = glGetUniformLocation(rendering_program, "vColors"); location[7] = glGetUniformLocation(rendering_program, "is_two_side"); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index aceafb719a5..3c3bb1ece01 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -119,6 +119,28 @@ Scene_polyhedron_item::initialize_buffers() 0, NULL ); + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glBufferData(GL_ARRAY_BUFFER, + (color_facets.size())*sizeof(color_facets.data()), + color_facets.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glBufferData(GL_ARRAY_BUFFER, + (color_lines.size())*sizeof(color_lines.data()), + color_lines.data(), GL_STATIC_DRAW); + glVertexAttribPointer(4, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); // Clean-up glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -137,18 +159,19 @@ Scene_polyhedron_item::compile_shaders(void) "layout (location = 0) in vec4 positions_facets; \n" "layout (location = 1) in vec4 positions_lines; \n" "layout (location = 2) in vec3 vNormals; \n" + "layout (location = 3) in vec3 color_facets; \n" + "layout (location = 4) in vec3 color_lines; \n" "uniform mat4 mvp_matrix; \n" "uniform mat4 mv_matrix; \n" "uniform int is_two_side; \n" "uniform int is_wire; \n" - "uniform vec3 vColors; \n" "uniform vec3 light_pos; \n" "uniform vec3 light_diff; \n" "uniform vec3 light_spec; \n" "uniform vec3 light_amb; \n" - "float spec_power = 0.0; \n" + "float spec_power = 128.0; \n" "out highp vec3 fColors; \n" " \n" @@ -173,17 +196,19 @@ Scene_polyhedron_item::compile_shaders(void) " R = reflect(-L, N); \n" " vec3 diffuse; \n" " if(is_two_side == 1) \n" - " diffuse = abs(dot(N,L)) * light_diff; \n" + " diffuse = abs(dot(N,L)) * light_diff * color_facets; \n" " else \n" - " diffuse = max(dot(N,L), 0.0) * light_diff; \n" + " diffuse = max(dot(N,L), 0.0) * light_diff * color_facets; \n" " vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - " fColors = light_amb + diffuse + specular ; \n" + " fColors = light_amb*color_facets + diffuse + specular ; \n" - " gl_Position = mvp_matrix * positions_facets;} \n" + " gl_Position = mvp_matrix *positions_facets; \n" + "} \n" "else{ \n" - " fColors = vColors; \n" - " gl_Position = mvp_matrix * positions_lines;} \n" + " fColors = color_lines; \n" + " gl_Position = mvp_matrix * positions_lines; \n" + "} \n" "} \n" }; //fill the fragment shader @@ -266,7 +291,6 @@ void Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const { - GLfloat colors[4]; light_info light; GLint is_both_sides = 0; GLint is_wire = 0; @@ -278,9 +302,11 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const GLdouble d_mat[16]; viewer->camera()->getModelViewProjectionMatrix(d_mat); //Convert the GLdoubles matrix in GLfloats - for (int i=0; i<16; ++i) + 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]); @@ -289,18 +315,18 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); glGetIntegerv(GL_POLYGON_MODE, &is_wire); //fills the arraw of colors with the current color - glGetFloatv(GL_CURRENT_COLOR, colors); + //Gets lighting info : //position glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); + //ligne ne servant a rien mais si on l'enleve plus rien ne marche... + std::cout<camera()->position().x<<" "<camera()->position().y<<" "<camera()->position().z<<" "<facets_begin(); f != poly->facets_end(); f++) { - const int this_patch_id = f->patch_id(); - if(patch_id != this_patch_id) { - CGALglcolor(colors_[this_patch_id]); - patch_id = this_patch_id; - } - //::glBegin(GL_POLYGON); + HF_circulator he = f->facet_begin(); HF_circulator end = he; CGAL_For_all(he,end) { // If Flat shading:1 normal per polygon added once per vertex - if (shading == GL_FLAT) + if (cur_shading == GL_FLAT) { Vector n = compute_facet_normal(*f); - normals.push_back(n.x());//::glNormal3d(n.x(),n.y(),n.z()); + normals.push_back(n.x()); normals.push_back(n.y()); normals.push_back(n.z()); } @@ -383,31 +398,37 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) // If Gouraud shading: 1 normal per vertex - if (shading == GL_SMOOTH) + if (cur_shading == GL_SMOOTH) { Vector n = compute_vertex_normal(*he->vertex()); - //::glNormal3d(n.x(),n.y(),n.z()); normals.push_back(n.x()); normals.push_back(n.y()); normals.push_back(n.z()); } + const int this_patch_id = f->patch_id(); + //if(patch_id != this_patch_id) { + //CGALglcolor(colors_[this_patch_id]); + color_facets.push_back(colors_[this_patch_id].redF()); + color_facets.push_back(colors_[this_patch_id].greenF()); + color_facets.push_back(colors_[this_patch_id].blueF()); + // patch_id = this_patch_id; + //} + //position const Point& p = he->vertex()->point(); - //::glVertex3d(p.x(),p.y(),p.z()); positions_facets.push_back(p.x()); positions_facets.push_back(p.y()); positions_facets.push_back(p.z()); positions_facets.push_back(1.0); - // ::glEnd(); } } //Lines typedef Kernel::Point_3 Point; typedef Polyhedron::Edge_iterator Edge_iterator; - - //::glBegin(GL_LINES); + //GLfloat colors[4]; + //glGetFloatv(GL_CURRENT_COLOR, colors); Edge_iterator he; if(!show_only_feature_edges_m) { for(he = poly->edges_begin(); @@ -426,11 +447,18 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) positions_lines.push_back(b.y()); positions_lines.push_back(b.z()); positions_lines.push_back(1.0); - // ::glVertex3d(a.x(),a.y(),a.z()); - // ::glVertex3d(b.x(),b.y(),b.z()); + + color_lines.push_back(1.0);//colors[0]); + color_lines.push_back(0.0);//colors[1]); + color_lines.push_back(0.0);//colors[2]); + + color_lines.push_back(1.0);//colors[0]); + color_lines.push_back(0.0);//colors[1]); + color_lines.push_back(0.0);//colors[2]); + } } - ::glColor3d(1.0, 0.0, 0.0); //<<------ passe les edges en rouge + // ::glColor3d(1.0, 0.0, 0.0); //<<------ passe les edges en rouge for(he = poly->edges_begin(); he != poly->edges_end(); he++) @@ -438,8 +466,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) if(!he->is_feature_edge()) continue; const Point& a = he->vertex()->point(); const Point& b = he->opposite()->vertex()->point(); - // ::glVertex3d(a.x(),a.y(),a.z()); - // ::glVertex3d(b.x(),b.y(),b.z()); + positions_lines.push_back(a.x()); positions_lines.push_back(a.y()); positions_lines.push_back(a.z()); @@ -449,8 +476,15 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) positions_lines.push_back(b.y()); 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); } - //::glEnd(); //Allocates a uniform location for the MVP and MV matrices location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); @@ -461,9 +495,8 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) location[3] = glGetUniformLocation(rendering_program, "light_diff"); location[4] = glGetUniformLocation(rendering_program, "light_spec"); location[5] = glGetUniformLocation(rendering_program, "light_amb"); - location[6] = glGetUniformLocation(rendering_program, "vColors"); - location[7] = glGetUniformLocation(rendering_program, "is_two_side"); - location[8] = glGetUniformLocation(rendering_program, "is_wire"); + location[6] = glGetUniformLocation(rendering_program, "is_two_side"); + location[7] = glGetUniformLocation(rendering_program, "is_wire"); } @@ -478,10 +511,11 @@ Scene_polyhedron_item::Scene_polyhedron_item() erase_next_picked_facet_m(false), plugin_has_set_color_vector_m(false) { + cur_shading=GL_FLAT; //init(); glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(3, buffer); + glGenBuffers(5, buffer); rendering_program = compile_shaders(); } @@ -497,10 +531,11 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) erase_next_picked_facet_m(false), plugin_has_set_color_vector_m(false) { + cur_shading=GL_FLAT; init(); glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(3, buffer); + glGenBuffers(5, buffer); rendering_program = compile_shaders(); } @@ -516,10 +551,11 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) erase_next_picked_facet_m(false), plugin_has_set_color_vector_m(false) { + cur_shading=GL_FLAT; init(); glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(3, buffer); + glGenBuffers(5, buffer); rendering_program = compile_shaders(); } @@ -533,7 +569,7 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) Scene_polyhedron_item::~Scene_polyhedron_item() { - glDeleteBuffers(3, buffer); + glDeleteBuffers(5, buffer); glDeleteVertexArrays(1, &vao); glDeleteProgram(rendering_program); @@ -574,6 +610,8 @@ Scene_polyhedron_item::clone() const { bool Scene_polyhedron_item::load(std::istream& in) { + + in >> *poly; if ( in && !isEmpty() ) @@ -672,15 +710,20 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { - glBindVertexArray(vao); //Binds the buffer used for the flat and gouraud rendering glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glEnableVertexAttribArray(0); + // glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); + // glEnableVertexAttribArray(1); //Binds the buffer used for normals glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glEnableVertexAttribArray(3); + // glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + //glEnableVertexAttribArray(4); // tells the GPU to use the program just created glUseProgram(rendering_program); @@ -695,19 +738,23 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { // Clean-up glUseProgram(0); + // glDisableVertexAttribArray(4); + glDisableVertexAttribArray(3); glDisableVertexAttribArray(2); - glDisableVertexAttribArray(1); + // glDisableVertexAttribArray(1); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - //gl_render_facets(*poly,colors_); + } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glBindVertexArray(vao); + //glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + //glEnableVertexAttribArray(0); //Binds the buffer used for the wireframe rendering glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); glEnableVertexAttribArray(1); @@ -715,6 +762,12 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); glEnableVertexAttribArray(2); + + //glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + // glEnableVertexAttribArray(3); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glEnableVertexAttribArray(4); // tells the GPU to use the program just created glUseProgram(rendering_program); @@ -724,10 +777,17 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glDrawArrays(GL_LINES, 0, positions_lines.size()/4); // Clean-up glUseProgram(0); + glDisableVertexAttribArray(4); + // glDisableVertexAttribArray(3); glDisableVertexAttribArray(2); glDisableVertexAttribArray(1); + //glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); + + + + } /*void Scene_polyhedron_item::direct_draw_edges(Viewer_interface* viewer) const { @@ -763,13 +823,29 @@ void Scene_polyhedron_item:: changed() { - std::cout<<"changed"< positions_lines; std::vector positions_facets; std::vector normals; + std::vector color_lines; + std::vector color_facets; GLuint rendering_program; - GLint location[9]; + GLint location[8]; GLuint vertex_shader; GLuint fragment_shader; GLuint program; GLuint vao; - GLuint buffer[3]; - void initialize_buffers(); // a mettre a jour - GLuint compile_shaders(void); //a mettre a jour + GLuint buffer[5]; + void initialize_buffers(); + GLuint compile_shaders(void); void compute_normals_and_vertices(void); - void uniform_attrib(Viewer_interface*) const;//fini + void uniform_attrib(Viewer_interface*) const; }; // end class Scene_polyhedron_item #endif // SCENE_POLYHEDRON_ITEM_H From 4ca98368fb855de5695973a6d3df209780b28c5e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 24 Feb 2015 15:53:59 +0100 Subject: [PATCH 26/62] Cleaning of the code cleaned-up some VBO binding that was useless and corrected a sizeof error. --- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 96 ++++++------------- 1 file changed, 30 insertions(+), 66 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 3c3bb1ece01..462c0bac389 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -84,7 +84,7 @@ Scene_polyhedron_item::initialize_buffers() glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glBufferData(GL_ARRAY_BUFFER, - (positions_facets.size())*sizeof(positions_facets.data()), + (positions_facets.size())*sizeof(float), positions_facets.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, //number of the buffer @@ -94,10 +94,11 @@ Scene_polyhedron_item::initialize_buffers() 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_lines.size())*sizeof(positions_lines.data()), + (positions_lines.size())*sizeof(float), positions_lines.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, //number of the buffer @@ -107,10 +108,11 @@ Scene_polyhedron_item::initialize_buffers() 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.size())*sizeof(normals.data()), + (normals.size())*sizeof(float), normals.data(), GL_STATIC_DRAW); glVertexAttribPointer(2, 3, @@ -119,9 +121,11 @@ Scene_polyhedron_item::initialize_buffers() 0, NULL ); + glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); glBufferData(GL_ARRAY_BUFFER, - (color_facets.size())*sizeof(color_facets.data()), + (color_facets.size())*sizeof(float), color_facets.data(), GL_STATIC_DRAW); glVertexAttribPointer(3, 3, @@ -130,9 +134,11 @@ Scene_polyhedron_item::initialize_buffers() 0, NULL ); + glEnableVertexAttribArray(3); + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); glBufferData(GL_ARRAY_BUFFER, - (color_lines.size())*sizeof(color_lines.data()), + (color_lines.size())*sizeof(float), color_lines.data(), GL_STATIC_DRAW); glVertexAttribPointer(4, 3, @@ -141,9 +147,9 @@ Scene_polyhedron_item::initialize_buffers() 0, NULL ); + glEnableVertexAttribArray(4); // Clean-up - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } @@ -304,9 +310,8 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const //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]); @@ -322,8 +327,9 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const //position glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); - //ligne ne servant a rien mais si on l'enleve plus rien ne marche... - std::cout<camera()->position().x<<" "<camera()->position().y<<" "<camera()->position().z<<" "<camera()->position(); + //ambient glGetLightfv(GL_LIGHT0, GL_AMBIENT, light.ambient); @@ -352,6 +358,8 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const void Scene_polyhedron_item::compute_normals_and_vertices(void) { + GLfloat colors[3]; + positions_facets.clear(); positions_lines.clear(); normals.clear(); @@ -372,7 +380,11 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) // int patch_id = -1; - Facet_iterator f; + Facet_iterator f = poly->facets_begin(); + colors[0]=colors_[f->patch_id()].redF(); + colors[1]=colors_[f->patch_id()].greenF(); + colors[2]=colors_[f->patch_id()].blueF(); + for(f = poly->facets_begin(); f != poly->facets_end(); f++) @@ -427,8 +439,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) //Lines typedef Kernel::Point_3 Point; typedef Polyhedron::Edge_iterator Edge_iterator; - //GLfloat colors[4]; - //glGetFloatv(GL_CURRENT_COLOR, colors); + Edge_iterator he; if(!show_only_feature_edges_m) { for(he = poly->edges_begin(); @@ -448,13 +459,13 @@ 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);//colors[0]); - color_lines.push_back(0.0);//colors[1]); - color_lines.push_back(0.0);//colors[2]); + color_lines.push_back(colors[0]); + color_lines.push_back(colors[1]); + color_lines.push_back(colors[2]); - color_lines.push_back(1.0);//colors[0]); - color_lines.push_back(0.0);//colors[1]); - color_lines.push_back(0.0);//colors[2]); + color_lines.push_back(colors[0]); + color_lines.push_back(colors[1]); + color_lines.push_back(colors[2]); } } @@ -712,19 +723,6 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { glBindVertexArray(vao); - //Binds the buffer used for the flat and gouraud rendering - glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - glEnableVertexAttribArray(0); - // glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - // glEnableVertexAttribArray(1); - //Binds the buffer used for normals - glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); - glEnableVertexAttribArray(2); - glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); - glEnableVertexAttribArray(3); - // glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); - //glEnableVertexAttribArray(4); - // tells the GPU to use the program just created glUseProgram(rendering_program); uniform_attrib(viewer); @@ -734,16 +732,7 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); - //Tells OpenGL not to use the program anymore - - // Clean-up glUseProgram(0); - // glDisableVertexAttribArray(4); - glDisableVertexAttribArray(3); - glDisableVertexAttribArray(2); - // glDisableVertexAttribArray(1); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); @@ -753,21 +742,6 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glBindVertexArray(vao); - //glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); - //glEnableVertexAttribArray(0); - //Binds the buffer used for the wireframe rendering - glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); - glEnableVertexAttribArray(1); - - glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); - glEnableVertexAttribArray(2); - - - //glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); - // glEnableVertexAttribArray(3); - - glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); - glEnableVertexAttribArray(4); // tells the GPU to use the program just created glUseProgram(rendering_program); @@ -777,12 +751,6 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glDrawArrays(GL_LINES, 0, positions_lines.size()/4); // Clean-up glUseProgram(0); - glDisableVertexAttribArray(4); - // glDisableVertexAttribArray(3); - glDisableVertexAttribArray(2); - glDisableVertexAttribArray(1); - //glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); @@ -790,10 +758,6 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { } -/*void Scene_polyhedron_item::direct_draw_edges(Viewer_interface* viewer) const { - - direct_draw_edges(); -}*/ Polyhedron* Scene_polyhedron_item::polyhedron() { return poly; } From 585e3adb76622bb0ca336ea9c44ca915507ed069 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Feb 2015 11:33:37 +0100 Subject: [PATCH 27/62] Fix bugs, clean code and implement color I changed a few details in polygon_soup_item, like the sizeof(float) or the size of the location array. Fixed the bug that deformed an item in polyhedron_item, caused by glGet(GL_POLYGON_MODE) that takes an array of 2 int and not a single int. Implemented the color changes in polyhedron_item depending of the selection. --- Polyhedron/demo/Polyhedron/Scene.cpp | 1184 +++++++++-------- Polyhedron/demo/Polyhedron/Scene_item.cpp | 4 + Polyhedron/demo/Polyhedron/Scene_item.h | 2 + .../Polyhedron/Scene_polygon_soup_item.cpp | 8 +- .../demo/Polyhedron/Scene_polygon_soup_item.h | 2 +- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 156 ++- .../demo/Polyhedron/Scene_polyhedron_item.h | 3 + 7 files changed, 743 insertions(+), 616 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 85778f72330..0b355bbc5d8 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -24,10 +24,10 @@ namespace { - void CGALglcolor(QColor c) - { +void CGALglcolor(QColor c) +{ ::glColor4d(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); - } +} } #ifdef CGAL_GLEW_ENABLED @@ -35,157 +35,157 @@ GlSplat::SplatRenderer* Scene::ms_splatting = 0; int Scene::ms_splattingCounter = 0; GlSplat::SplatRenderer* Scene::splatting() { - assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); - return ms_splatting; + assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); + return ms_splatting; } #endif Scene::Scene(QObject* parent) - : QAbstractListModel(parent), - selected_item(-1), - item_A(-1), - item_B(-1) + : QAbstractListModel(parent), + selected_item(-1), + item_A(-1), + item_B(-1) { - connect(this, SIGNAL(selectionRay(double, double, double, - double, double, double)), - this, SLOT(setSelectionRay(double, double, double, - double, double, double))); + connect(this, SIGNAL(selectionRay(double, double, double, + double, double, double)), + this, SLOT(setSelectionRay(double, double, double, + double, double, double))); #ifdef CGAL_GLEW_ENABLED - if(ms_splatting==0) - ms_splatting = new GlSplat::SplatRenderer(); - ms_splattingCounter++; + if(ms_splatting==0) + ms_splatting = new GlSplat::SplatRenderer(); + ms_splattingCounter++; #endif } Scene::Item_id Scene::addItem(Scene_item* item) { - Bbox bbox_before = bbox(); - m_entries.push_back(item); - connect(item, SIGNAL(itemChanged()), - this, SLOT(itemChanged())); - if(bbox_before + item->bbox() != bbox_before) - { emit updated_bbox(); } - emit updated(); - QAbstractListModel::reset(); - Item_id id = m_entries.size() - 1; - emit newItem(id); - return id; + Bbox bbox_before = bbox(); + m_entries.push_back(item); + connect(item, SIGNAL(itemChanged()), + this, SLOT(itemChanged())); + if(bbox_before + item->bbox() != bbox_before) + { emit updated_bbox(); } + emit updated(); + QAbstractListModel::reset(); + Item_id id = m_entries.size() - 1; + emit newItem(id); + return id; } Scene_item* Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_to_be_destroyed) { - if(index < 0 || index >= m_entries.size()) - return 0; + if(index < 0 || index >= m_entries.size()) + return 0; - if(emit_item_about_to_be_destroyed) { - emit itemAboutToBeDestroyed(m_entries[index]); - } + if(emit_item_about_to_be_destroyed) { + emit itemAboutToBeDestroyed(m_entries[index]); + } - connect(item, SIGNAL(itemChanged()), - this, SLOT(itemChanged())); - std::swap(m_entries[index], item); + connect(item, SIGNAL(itemChanged()), + this, SLOT(itemChanged())); + std::swap(m_entries[index], item); - if ( item->isFinite() && !item->isEmpty() && - m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && - item->bbox()!=m_entries[index]->bbox() ) - { - emit updated_bbox(); - } - emit updated(); - itemChanged(index); - // QAbstractListModel::reset(); - return item; + if ( item->isFinite() && !item->isEmpty() && + m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && + item->bbox()!=m_entries[index]->bbox() ) + { + emit updated_bbox(); + } + emit updated(); + itemChanged(index); + // QAbstractListModel::reset(); + return item; } int Scene::erase(int index) { - if(index < 0 || index >= m_entries.size()) + if(index < 0 || index >= m_entries.size()) + return -1; + + Scene_item* item = m_entries[index]; + emit itemAboutToBeDestroyed(item); + delete item; + m_entries.removeAt(index); + + selected_item = -1; + emit updated(); + QAbstractListModel::reset(); + + if(--index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; return -1; - - Scene_item* item = m_entries[index]; - emit itemAboutToBeDestroyed(item); - delete item; - m_entries.removeAt(index); - - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); - - if(--index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; - return -1; } int Scene::erase(QList indices) { - QList to_be_removed; + QList to_be_removed; - int max_index = -1; - Q_FOREACH(int index, indices) { - if(index < 0 || index >= m_entries.size()) - continue; - max_index = (std::max)(max_index, index); - Scene_item* item = m_entries[index]; - to_be_removed.push_back(item); - emit itemAboutToBeDestroyed(item); - delete item; - } + int max_index = -1; + Q_FOREACH(int index, indices) { + if(index < 0 || index >= m_entries.size()) + continue; + max_index = (std::max)(max_index, index); + Scene_item* item = m_entries[index]; + to_be_removed.push_back(item); + emit itemAboutToBeDestroyed(item); + delete item; + } - Q_FOREACH(Scene_item* item, to_be_removed) { - m_entries.removeAll(item); - } + Q_FOREACH(Scene_item* item, to_be_removed) { + m_entries.removeAll(item); + } - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); + selected_item = -1; + emit updated(); + QAbstractListModel::reset(); - int index = max_index + 1 - indices.size(); - if(index >= m_entries.size()) { - index = m_entries.size() - 1; - } - if(index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; - return -1; + int index = max_index + 1 - indices.size(); + if(index >= m_entries.size()) { + index = m_entries.size() - 1; + } + if(index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; + return -1; } Scene::~Scene() { - Q_FOREACH(Scene_item* item_ptr, m_entries) - { - delete item_ptr; - } - m_entries.clear(); + Q_FOREACH(Scene_item* item_ptr, m_entries) + { + delete item_ptr; + } + m_entries.clear(); #ifdef CGAL_GLEW_ENABLED - if((--ms_splattingCounter)==0) - delete ms_splatting; + if((--ms_splattingCounter)==0) + delete ms_splatting; #endif } Scene_item* Scene::item(Item_id index) const { - return m_entries.value(index); // QList::value checks bounds + return m_entries.value(index); // QList::value checks bounds } Scene::Item_id Scene::item_id(Scene_item* scene_item) const { - return m_entries.indexOf(scene_item); + return m_entries.indexOf(scene_item); } int Scene::numberOfEntries() const { - return m_entries.size(); + return m_entries.size(); } // Duplicate a scene item. @@ -193,40 +193,40 @@ Scene::numberOfEntries() const Scene::Item_id Scene::duplicate(Item_id index) { - if(index < 0 || index >= m_entries.size()) - return -1; + if(index < 0 || index >= m_entries.size()) + return -1; - const Scene_item* item = m_entries[index]; - Scene_item* new_item = item->clone(); - if(new_item) { - new_item->setName(tr("%1 (copy)").arg(item->name())); - new_item->setColor(item->color()); - new_item->setVisible(item->visible()); - addItem(new_item); - return m_entries.size() - 1; - } - else - return -1; + const Scene_item* item = m_entries[index]; + Scene_item* new_item = item->clone(); + if(new_item) { + new_item->setName(tr("%1 (copy)").arg(item->name())); + new_item->setColor(item->color()); + new_item->setVisible(item->visible()); + addItem(new_item); + return m_entries.size() - 1; + } + else + return -1; } void Scene::initializeGL() { #ifdef CGAL_GLEW_ENABLED - ms_splatting->init(); + ms_splatting->init(); - //Setting the light options + //Setting the light options - // Create light components - GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; - GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; - GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; + // Create light components + GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; + GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; - // Assign created components to GL_LIGHT0 - glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); - glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); - glLightfv(GL_LIGHT0, GL_POSITION, position); + // Assign created components to GL_LIGHT0 + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); + glLightfv(GL_LIGHT0, GL_POSITION, position); #endif } @@ -238,191 +238,203 @@ void Scene::initializeGL() bool Scene::keyPressEvent(QKeyEvent* e){ - bool res=false; - for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); - it!=endit;++it) - { - Scene_item* item=m_entries[*it]; - res |= item->keyPressEvent(e); - } - return res; + bool res=false; + for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); + it!=endit;++it) + { + Scene_item* item=m_entries[*it]; + res |= item->keyPressEvent(e); + } + return res; } void Scene::draw() { - draw_aux(false, 0); + draw_aux(false, 0); } void Scene::draw(Viewer_interface* viewer) { - draw_aux(false, viewer); + draw_aux(false, viewer); } void Scene::drawWithNames() { - draw_aux(true, 0); + draw_aux(true, 0); } void Scene::drawWithNames(Viewer_interface* viewer) { - draw_aux(true, viewer); + draw_aux(true, viewer); } void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { - // Flat/Gouraud OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *m_entries[index]; - if(item.visible()) + // Flat/Gouraud OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) { - if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - if(item.renderingMode() == Gouraud) - ::glShadeModel(GL_SMOOTH); - else - ::glShadeModel(GL_FLAT); - - item.shading_mode_changed(); - if(CGAL::check_gl_error(__FILE__, __LINE__)) { - std::cerr << "GL error was before the drawing of the item \"" - << qPrintable(item.name()) << "\"\n" - << " with_name = " << std::boolalpha << with_names - << std::endl; + if(with_names) { + ::glPushName(index); } - if(viewer) - item.draw(viewer); - else - item.draw(); - if(CGAL::check_gl_error(__FILE__, __LINE__)) { - std::cerr << "GL error was after the drawing of the item \"" - << qPrintable(item.name()) << "\"\n" - << " with_name = " << std::boolalpha << with_names - << std::endl; - } - } - } - if(with_names) { - ::glPopName(); - } - } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) + { + ::glEnable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + {item.selection_changed(true); + CGALglcolor(item.color().lighter(120)); + } + else - // Wireframe OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); + {item.selection_changed(false); + CGALglcolor(item.color()); + } + + if(item.renderingMode() == Gouraud) + ::glShadeModel(GL_SMOOTH); + else + ::glShadeModel(GL_FLAT); + + item.shading_mode_changed(); + if(CGAL::check_gl_error(__FILE__, __LINE__)) { + std::cerr << "GL error was before the drawing of the item \"" + << qPrintable(item.name()) << "\"\n" + << " with_name = " << std::boolalpha << with_names + << std::endl; + } + if(viewer) + item.draw(viewer); + else + item.draw(); + if(CGAL::check_gl_error(__FILE__, __LINE__)) { + std::cerr << "GL error was after the drawing of the item \"" + << qPrintable(item.name()) << "\"\n" + << " with_name = " << std::boolalpha << with_names + << std::endl; + } + } + } + if(with_names) { + ::glPopName(); + } } - Scene_item& item = *m_entries[index]; - if(item.visible()) + + // Wireframe OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) { - if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(Qt::black); - else - CGALglcolor(item.color().lighter(50)); - - - - if(viewer) - item.draw_edges(viewer); - else - item.draw_edges(); - } - else{ - if( item.renderingMode() == PointsPlusNormals ){ - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - if(viewer) - item.draw_edges(viewer); - else - item.draw_edges(); + if(with_names) { + ::glPushName(index); } - } - } - if(with_names) { - ::glPopName(); - } - } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) + { + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + CGALglcolor(Qt::black); + else + CGALglcolor(item.color().lighter(50)); - // Points OpenGL drawing - for(int index = 0; index < m_entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); + + + if(viewer) + item.draw_edges(viewer); + else + item.draw_edges(); + } + else{ + if( item.renderingMode() == PointsPlusNormals ){ + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + if(index == selected_item) + { + item.selection_changed(true); + CGALglcolor(item.color().lighter(120)); + } + else + { + item.selection_changed(false); + CGALglcolor(item.color()); + } + if(viewer) + item.draw_edges(viewer); + else + item.draw_edges(); + } + } + } + if(with_names) { + ::glPopName(); + } } - Scene_item& item = *m_entries[index]; - if(item.visible()) + + // Points OpenGL drawing + for(int index = 0; index < m_entries.size(); ++index) { - if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - CGALglcolor(item.color()); + if(with_names) { + ::glPushName(index); + } + Scene_item& item = *m_entries[index]; + if(item.visible()) + { + if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) + { + ::glDisable(GL_LIGHTING); + ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); + ::glPointSize(2.f); + ::glLineWidth(1.0f); + CGALglcolor(item.color()); - if(viewer) - item.draw_points(viewer); - else - item.draw_points(); - } + if(viewer) + item.draw_points(viewer); + else + item.draw_points(); + } + } + if(with_names) { + ::glPopName(); + } } - if(with_names) { - ::glPopName(); - } - } #ifdef CGAL_GLEW_ENABLED - // Splatting - if(!with_names && ms_splatting->isSupported()) - { - ms_splatting->beginVisibilityPass(); - for(int index = 0; index < m_entries.size(); ++index) + // Splatting + if(!with_names && ms_splatting->isSupported()) { - Scene_item& item = *m_entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - item.draw_splats(); - } + ms_splatting->beginVisibilityPass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + item.draw_splats(); + } + } + ms_splatting->beginAttributePass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + CGALglcolor(item.color()); + item.draw_splats(); + } + } + ms_splatting->finalize(); } - ms_splatting->beginAttributePass(); - for(int index = 0; index < m_entries.size(); ++index) - { - Scene_item& item = *m_entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - CGALglcolor(item.color()); - item.draw_splats(); - } - } - ms_splatting->finalize(); - } #endif } @@ -433,127 +445,127 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) int Scene::rowCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else - return m_entries.size(); + if (parent.isValid()) + return 0; + else + return m_entries.size(); } int Scene::columnCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else - return NumberOfColumns; + if (parent.isValid()) + return 0; + else + return NumberOfColumns; } QVariant Scene::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); - if(index.row() < 0 || index.row() >= m_entries.size()) - return QVariant(); + if(index.row() < 0 || index.row() >= m_entries.size()) + return QVariant(); - if(role == ::Qt::ToolTipRole) - { - return m_entries[index.row()]->toolTip(); - } - switch(index.column()) - { - case ColorColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->color(); - else if(role == ::Qt::DecorationRole) - return m_entries.value(index.row())->color(); - break; - case NameColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->name(); - if(role == ::Qt::FontRole) - return m_entries.value(index.row())->font(); - break; - case RenderingModeColumn: - if(role == ::Qt::DisplayRole) { - return m_entries.value(index.row())->renderingModeName(); + if(role == ::Qt::ToolTipRole) + { + return m_entries[index.row()]->toolTip(); } - else if(role == ::Qt::EditRole) { - return static_cast(m_entries.value(index.row())->renderingMode()); + switch(index.column()) + { + case ColorColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->color(); + else if(role == ::Qt::DecorationRole) + return m_entries.value(index.row())->color(); + break; + case NameColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->name(); + if(role == ::Qt::FontRole) + return m_entries.value(index.row())->font(); + break; + case RenderingModeColumn: + if(role == ::Qt::DisplayRole) { + return m_entries.value(index.row())->renderingModeName(); + } + else if(role == ::Qt::EditRole) { + return static_cast(m_entries.value(index.row())->renderingMode()); + } + else if(role == ::Qt::TextAlignmentRole) { + return ::Qt::AlignCenter; + } + break; + case ABColumn: + if(role == ::Qt::DisplayRole) { + if(index.row() == item_A) + return "A"; + if(index.row() == item_B) + return "B"; + } + else if(role == ::Qt::TextAlignmentRole) { + return ::Qt::AlignCenter; + } + break; + case VisibleColumn: + if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) + return m_entries.value(index.row())->visible(); + break; + default: + return QVariant(); } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case ABColumn: - if(role == ::Qt::DisplayRole) { - if(index.row() == item_A) - return "A"; - if(index.row() == item_B) - return "B"; - } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case VisibleColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->visible(); - break; - default: return QVariant(); - } - return QVariant(); } QVariant Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const { - if(orientation == ::Qt::Horizontal) { - if (role == ::Qt::DisplayRole) - { - switch(section) - { - case NameColumn: - return tr("Name"); - break; - case ColorColumn: - return tr("Color"); - break; - case RenderingModeColumn: - return tr("Mode"); - case ABColumn: - return tr("A/B"); - break; - case VisibleColumn: - return tr("View"); - break; - default: - return QVariant(); - } + if(orientation == ::Qt::Horizontal) { + if (role == ::Qt::DisplayRole) + { + switch(section) + { + case NameColumn: + return tr("Name"); + break; + case ColorColumn: + return tr("Color"); + break; + case RenderingModeColumn: + return tr("Mode"); + case ABColumn: + return tr("A/B"); + break; + case VisibleColumn: + return tr("View"); + break; + default: + return QVariant(); + } + } + else if(role == ::Qt::ToolTipRole) { + if(section == RenderingModeColumn) { + return tr("Rendering mode (points/wireframe/flat/flat+edges/Gouraud)"); + } + else if(section == ABColumn) { + return tr("Selection A/Selection B"); + } + } } - else if(role == ::Qt::ToolTipRole) { - if(section == RenderingModeColumn) { - return tr("Rendering mode (points/wireframe/flat/flat+edges/Gouraud)"); - } - else if(section == ABColumn) { - return tr("Selection A/Selection B"); - } - } - } - return QAbstractListModel::headerData(section, orientation, role); + return QAbstractListModel::headerData(section, orientation, role); } Qt::ItemFlags Scene::flags ( const QModelIndex & index ) const { - if (index.isValid() && index.column() == NameColumn) { - return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; - } - else { - return QAbstractListModel::flags(index); - } + if (index.isValid() && index.column() == NameColumn) { + return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; + } + else { + return QAbstractListModel::flags(index); + } } bool @@ -561,232 +573,232 @@ Scene::setData(const QModelIndex &index, const QVariant &value, int role) { - if( role != ::Qt::EditRole || !index.isValid() ) - return false; + if( role != ::Qt::EditRole || !index.isValid() ) + return false; - if(index.row() < 0 || index.row() >= m_entries.size()) - return false; + if(index.row() < 0 || index.row() >= m_entries.size()) + return false; - Scene_item* item = m_entries[index.row()]; - if(!item) return false; - switch(index.column()) - { - case NameColumn: - item->setName(value.toString()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case ColorColumn: - item->setColor(value.value()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case RenderingModeColumn: - { - RenderingMode rendering_mode = static_cast(value.toInt()); - // Find next supported rendering mode - while ( ! item->supportsRenderingMode(rendering_mode) -#ifdef CGAL_GLEW_ENABLED - || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) -#endif - ) + Scene_item* item = m_entries[index.row()]; + if(!item) return false; + switch(index.column()) { - rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); + case NameColumn: + item->setName(value.toString()); + item->changed(); + emit dataChanged(index, index); + return true; + break; + case ColorColumn: + item->setColor(value.value()); + item->changed(); + emit dataChanged(index, index); + return true; + break; + case RenderingModeColumn: + { + RenderingMode rendering_mode = static_cast(value.toInt()); + // Find next supported rendering mode + while ( ! item->supportsRenderingMode(rendering_mode) + #ifdef CGAL_GLEW_ENABLED + || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) + #endif + ) + { + rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); + } + item->setRenderingMode(rendering_mode); + item->changed(); + emit dataChanged(index, index); + return true; + break; + } + case VisibleColumn: + item->setVisible(value.toBool()); + item->changed(); + emit dataChanged(index, index); + return true; + default: + return false; } - item->setRenderingMode(rendering_mode); - item->changed(); - emit dataChanged(index, index); - return true; - break; - } - case VisibleColumn: - item->setVisible(value.toBool()); - item->changed(); - emit dataChanged(index, index); - return true; - default: return false; - } - return false; } Scene::Item_id Scene::mainSelectionIndex() const { - return selected_item; + return selected_item; } QList Scene::selectionIndices() const { - return selected_items_list; + return selected_items_list; } int Scene::selectionAindex() const { - return item_A; + return item_A; } int Scene::selectionBindex() const { - return item_B; + return item_B; } QItemSelection Scene::createSelection(int i) { - return QItemSelection(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + return QItemSelection(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } QItemSelection Scene::createSelectionAll() { - return QItemSelection(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1 , LastColumn)); + return QItemSelection(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1 , LastColumn)); } void Scene::itemChanged() { - Scene_item* item = qobject_cast(sender()); - if(item) - itemChanged(item); + Scene_item* item = qobject_cast(sender()); + if(item) + itemChanged(item); } void Scene::itemChanged(Item_id i) { - if(i < 0 || i >= m_entries.size()) - return; + if(i < 0 || i >= m_entries.size()) + return; - m_entries[i]->changed(); - emit dataChanged(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + m_entries[i]->changed(); + emit dataChanged(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } void Scene::itemChanged(Scene_item* item) { - item->changed(); - emit dataChanged(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1, LastColumn)); + item->changed(); + emit dataChanged(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1, LastColumn)); } bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { - QAbstractProxyModel* proxyModel = dynamic_cast(model); - Q_ASSERT(proxyModel); - Scene *scene = dynamic_cast(proxyModel->sourceModel()); - Q_ASSERT(scene); - switch(index.column()) { - case Scene::VisibleColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - int x = mouseEvent->pos().x() - option.rect.x(); - if(x >= (option.rect.width() - size)/2 && - x <= (option.rect.width() + size)/2) { - model->setData(index, ! model->data(index).toBool() ); + QAbstractProxyModel* proxyModel = dynamic_cast(model); + Q_ASSERT(proxyModel); + Scene *scene = dynamic_cast(proxyModel->sourceModel()); + Q_ASSERT(scene); + switch(index.column()) { + case Scene::VisibleColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + int x = mouseEvent->pos().x() - option.rect.x(); + if(x >= (option.rect.width() - size)/2 && + x <= (option.rect.width() + size)/2) { + model->setData(index, ! model->data(index).toBool() ); + } + } + return false; //so that the selection can change } - } - return false; //so that the selection can change - } - return true; - break; - case Scene::ColorColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - QColor color = - QColorDialog::getColor(model->data(index).value(), - 0/*, - tr("Select color"), - QColorDialog::ShowAlphaChannel*/); - if (color.isValid()) { - model->setData(index, color ); + return true; + break; + case Scene::ColorColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + QColor color = + QColorDialog::getColor(model->data(index).value(), + 0/*, + tr("Select color"), + QColorDialog::ShowAlphaChannel*/); + if (color.isValid()) { + model->setData(index, color ); + } + } } - } + else if(event->type() == QEvent::MouseButtonDblClick) { + return true; // block double-click + } + return false; + break; + case Scene::RenderingModeColumn: + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == ::Qt::LeftButton) { + // Switch rendering mode + /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); + rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; + model->setData(index, rendering_mode); + } + } + else if(event->type() == QEvent::MouseButtonDblClick) { + return true; // block double-click + } + return false; + break; + case Scene::ABColumn: + if (event->type() == QEvent::MouseButtonPress) { + if(index.row() == scene->item_B) { + scene->item_A = index.row(); + scene->item_B = -1; + } + else if(index.row() == scene->item_A) { + scene->item_B = index.row(); + scene->item_A = -1; + } + else if(scene->item_A == -1) { + scene->item_A = index.row(); + } + else { + scene->item_B = index.row(); + } + scene->dataChanged(scene->createIndex(0, Scene::ABColumn), + scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); + } + return false; + break; + default: + return QItemDelegate::editorEvent(event, model, option, index); } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::RenderingModeColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - // Switch rendering mode - /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); - rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; - model->setData(index, rendering_mode); - } - } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::ABColumn: - if (event->type() == QEvent::MouseButtonPress) { - if(index.row() == scene->item_B) { - scene->item_A = index.row(); - scene->item_B = -1; - } - else if(index.row() == scene->item_A) { - scene->item_B = index.row(); - scene->item_A = -1; - } - else if(scene->item_A == -1) { - scene->item_A = index.row(); - } - else { - scene->item_B = index.row(); - } - scene->dataChanged(scene->createIndex(0, Scene::ABColumn), - scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); - } - return false; - break; - default: - return QItemDelegate::editorEvent(event, model, option, index); - } } void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - if (index.column() != Scene::VisibleColumn) { - QItemDelegate::paint(painter, option, index); - } else { - const QAbstractItemModel *model = index.model(); - QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? - (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; + if (index.column() != Scene::VisibleColumn) { + QItemDelegate::paint(painter, option, index); + } else { + const QAbstractItemModel *model = index.model(); + QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? + (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; - if (option.state & QStyle::State_Selected) - painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); - bool checked = model->data(index, ::Qt::DisplayRole).toBool(); - int width = option.rect.width(); - int height = option.rect.height(); - size = (std::min)(width, height); - int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; - int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); - if(checked) { - painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); + bool checked = model->data(index, ::Qt::DisplayRole).toBool(); + int width = option.rect.width(); + int height = option.rect.height(); + size = (std::min)(width, height); + int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; + int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); + if(checked) { + painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } + else { + painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } + drawFocus(painter, option, option.rect); // since we draw the grid ourselves } - else { - painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - drawFocus(painter, option, option.rect); // since we draw the grid ourselves - } } void Scene::setItemVisible(int index, bool b) { - if( index < 0 || index >= m_entries.size() ) - return; - m_entries[index]->setVisible(b); - emit dataChanged(this->createIndex(index, VisibleColumn), - this->createIndex(index, VisibleColumn)); + if( index < 0 || index >= m_entries.size() ) + return; + m_entries[index]->setVisible(b); + emit dataChanged(this->createIndex(index, VisibleColumn), + this->createIndex(index, VisibleColumn)); } void Scene::setSelectionRay(double orig_x, @@ -796,58 +808,58 @@ void Scene::setSelectionRay(double orig_x, double dir_y, double dir_z) { - Scene_item* item = this->item(selected_item); - if(item) item->select(orig_x, - orig_y, - orig_z, - dir_x, - dir_y, - dir_z); + Scene_item* item = this->item(selected_item); + if(item) item->select(orig_x, + orig_y, + orig_z, + dir_x, + dir_y, + dir_z); } void Scene::setItemA(int i) { - item_A = i; - if(item_A == item_B) - { - item_B = -1; - } - emit dataChanged(this->createIndex(0, ABColumn), - this->createIndex(m_entries.size()-1, ABColumn)); + item_A = i; + if(item_A == item_B) + { + item_B = -1; + } + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } void Scene::setItemB(int i) { - item_B = i; - if(item_A == item_B) - { - item_A = -1; - } - emit updated(); - emit dataChanged(this->createIndex(0, ABColumn), - this->createIndex(m_entries.size()-1, ABColumn)); + item_B = i; + if(item_A == item_B) + { + item_A = -1; + } + emit updated(); + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } Scene::Bbox Scene::bbox() const { - if(m_entries.empty()) - return Bbox(); + if(m_entries.empty()) + return Bbox(); - bool bbox_initialized = false; - Bbox bbox; - Q_FOREACH(Scene_item* item, m_entries) - { - if(item->isFinite() && !item->isEmpty()) { - if(bbox_initialized) { - bbox = bbox + item->bbox(); - } - else { - bbox = item->bbox(); - bbox_initialized = true; - } + bool bbox_initialized = false; + Bbox bbox; + Q_FOREACH(Scene_item* item, m_entries) + { + if(item->isFinite() && !item->isEmpty()) { + if(bbox_initialized) { + bbox = bbox + item->bbox(); + } + else { + bbox = item->bbox(); + bbox_initialized = true; + } + } } - } - return bbox; + return bbox; } #include "Scene_find_items.h" @@ -859,13 +871,13 @@ Scene_item* findItem(const Scene_interface* scene_interface, const QMetaObject& metaobj, QString name, Scene_item_name_fn_ptr fn) { - const Scene* scene = dynamic_cast(scene_interface); - if(!scene) return 0; - Q_FOREACH(Scene_item* item, scene->entries()) { - Scene_item* ptr = qobject_cast(metaobj.cast(item)); - if(ptr && ((ptr->*fn)() == name)) return ptr; - } - return 0; + const Scene* scene = dynamic_cast(scene_interface); + if(!scene) return 0; + Q_FOREACH(Scene_item* item, scene->entries()) { + Scene_item* ptr = qobject_cast(metaobj.cast(item)); + if(ptr && ((ptr->*fn)() == name)) return ptr; + } + return 0; } Q_DECL_EXPORT @@ -874,20 +886,20 @@ findItems(const Scene_interface* scene_interface, const QMetaObject&, QString name, Scene_item_name_fn_ptr fn) { - const Scene* scene = dynamic_cast(scene_interface); - QList list; - if(!scene) return list; + const Scene* scene = dynamic_cast(scene_interface); + QList list; + if(!scene) return list; - Q_FOREACH(Scene_item* item, scene->entries()) { - Scene_item* ptr = qobject_cast(item); - if(ptr && ((ptr->*fn)() == name)) { - list << ptr; + Q_FOREACH(Scene_item* item, scene->entries()) { + Scene_item* ptr = qobject_cast(item); + if(ptr && ((ptr->*fn)() == name)) { + list << ptr; + } } - } - return list; + return list; } } // end namespace details -} // end namespace scene + } // end namespace scene #include "Scene.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_item.cpp b/Polyhedron/demo/Polyhedron/Scene_item.cpp index 0942192fb73..ae7c2b23dd2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_item.cpp @@ -97,6 +97,10 @@ QMenu* Scene_item::contextMenu() void Scene_item::changed() { // emit itemChanged(); } + +void Scene_item::selection_changed(bool) { + // emit itemChanged(); +} void Scene_item::shading_mode_changed() { diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 3074d4662de..2ee71b01a55 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -52,6 +52,7 @@ public: // Splats OpenGL drawing virtual void draw_splats() const {} virtual void draw_splats(Viewer_interface*) const {draw_splats();} + virtual void selection_changed(bool); // Functions for displaying meta-data of the item virtual QString toolTip() const = 0; @@ -147,6 +148,7 @@ protected: QString name_; QColor color_; bool visible_; + bool is_selected; RenderingMode rendering_mode; QMenu* defaultContextMenu; diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 5e407ebc6a9..04933968e21 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -91,7 +91,7 @@ Scene_polygon_soup_item::initialize_buffers() glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glBufferData(GL_ARRAY_BUFFER, - (positions_poly.size())*sizeof(positions_poly.data()), + (positions_poly.size())*sizeof(float), positions_poly.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, //number of the buffer @@ -105,7 +105,7 @@ Scene_polygon_soup_item::initialize_buffers() glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); glBufferData(GL_ARRAY_BUFFER, - (normals.size())*sizeof(normals.data()), + (normals.size())*sizeof(float), normals.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 3, @@ -138,7 +138,7 @@ Scene_polygon_soup_item::compile_shaders(void) "uniform vec3 light_diff; \n" "uniform vec3 light_spec; \n" "uniform vec3 light_amb; \n" - "float spec_power = 0.0; \n" + "float spec_power = 128.0; \n" "out highp vec3 fColors; \n" " \n" @@ -300,7 +300,7 @@ Scene_polygon_soup_item::uniform_attrib(Viewer_interface* viewer) const glUniform3fv(location[3], 1, light.diffuse); glUniform3fv(location[4], 1, light.specular); glUniform3fv(location[5], 1, light.ambient); - glUniform1i(location[7], is_both_sides); + glUniform1i(location[6], is_both_sides); } void diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 173911379f3..8c77bd986cc 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -167,7 +167,7 @@ private: std::vector normals; GLuint rendering_program; - GLint location[8]; + GLint location[7]; GLuint vertex_shader; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 462c0bac389..f88acac6821 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -189,7 +189,7 @@ Scene_polyhedron_item::compile_shaders(void) "vec3 L; \n" "vec3 V; \n" "vec3 R; \n" - "if(is_wire !=6913){ \n" //number for the mode wireframe + "if(is_wire ==0){ \n" //number for the mode wireframe " P = mv_matrix * positions_facets; \n" " N = mat3(mv_matrix)* vNormals; \n" " L = light_pos - P.xyz; \n" @@ -299,6 +299,7 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const light_info light; GLint is_both_sides = 0; + GLint poly_mode[2]; GLint is_wire = 0; GLfloat mvp_mat[16]; GLfloat mv_mat[16]; @@ -318,7 +319,11 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); - glGetIntegerv(GL_POLYGON_MODE, &is_wire); + glGetIntegerv(GL_POLYGON_MODE, poly_mode); + if(poly_mode[1] == GL_LINE) + is_wire = 1; + else + is_wire = 0; //fills the arraw of colors with the current color @@ -327,9 +332,6 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const //position glGetLightfv(GL_LIGHT0, GL_POSITION, light.position); - //ligne ne servant a rien mais si on l'enleve plus rien ne marche... - viewer->camera()->position(); - //ambient glGetLightfv(GL_LIGHT0, GL_AMBIENT, light.ambient); @@ -358,13 +360,10 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer) const void Scene_polyhedron_item::compute_normals_and_vertices(void) { - GLfloat colors[3]; - positions_facets.clear(); positions_lines.clear(); normals.clear(); - color_lines.clear(); - color_facets.clear(); + //Facets @@ -381,9 +380,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) // int patch_id = -1; Facet_iterator f = poly->facets_begin(); - colors[0]=colors_[f->patch_id()].redF(); - colors[1]=colors_[f->patch_id()].greenF(); - colors[2]=colors_[f->patch_id()].blueF(); + for(f = poly->facets_begin(); f != poly->facets_end(); @@ -422,9 +419,9 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) //if(patch_id != this_patch_id) { //CGALglcolor(colors_[this_patch_id]); - color_facets.push_back(colors_[this_patch_id].redF()); + /* color_facets.push_back(colors_[this_patch_id].redF()); color_facets.push_back(colors_[this_patch_id].greenF()); - color_facets.push_back(colors_[this_patch_id].blueF()); + color_facets.push_back(colors_[this_patch_id].blueF());*/ // patch_id = this_patch_id; //} //position @@ -459,17 +456,16 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) positions_lines.push_back(b.z()); positions_lines.push_back(1.0); - color_lines.push_back(colors[0]); + /* color_lines.push_back(colors[0]); color_lines.push_back(colors[1]); color_lines.push_back(colors[2]); color_lines.push_back(colors[0]); color_lines.push_back(colors[1]); - color_lines.push_back(colors[2]); + color_lines.push_back(colors[2]);*/ } } - // ::glColor3d(1.0, 0.0, 0.0); //<<------ passe les edges en rouge for(he = poly->edges_begin(); he != poly->edges_end(); he++) @@ -488,15 +484,17 @@ 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(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); + color_lines.push_back(0.0);*/ } + //set the colors + compute_colors(); //Allocates a uniform location for the MVP and MV matrices location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program, "mv_matrix"); @@ -510,6 +508,99 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) location[7] = glGetUniformLocation(rendering_program, "is_wire"); } +void +Scene_polyhedron_item::compute_colors() +{ + std::cout<<"COMPUTE_COLOR"<facets_begin(); + QColor temp = colors_[f->patch_id()]; + if(is_selected) + { + colors[0]=0.0; + colors[1]=0.0; + colors[2]=0.0; + } + else + { + colors[0]=temp.lighter(50).redF(); + colors[1]=temp.lighter(50).greenF(); + colors[2]=temp.lighter(50).blueF(); + } + for(f = poly->facets_begin(); + f != poly->facets_end(); + f++) + { + HF_circulator he = f->facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + + const int this_patch_id = f->patch_id(); + if(is_selected) + { + color_facets.push_back(colors_[this_patch_id].lighter(120).redF()); + color_facets.push_back(colors_[this_patch_id].lighter(120).greenF()); + color_facets.push_back(colors_[this_patch_id].lighter(120).blueF()); + } + else + { + color_facets.push_back(colors_[this_patch_id].redF()); + color_facets.push_back(colors_[this_patch_id].greenF()); + color_facets.push_back(colors_[this_patch_id].blueF()); + } + } + } + //Lines + typedef Polyhedron::Edge_iterator Edge_iterator; + + Edge_iterator he; + if(!show_only_feature_edges_m) { + for(he = poly->edges_begin(); + he != poly->edges_end(); + he++) + { + if(he->is_feature_edge()) continue; + color_lines.push_back(colors[0]); + color_lines.push_back(colors[1]); + color_lines.push_back(colors[2]); + + color_lines.push_back(colors[0]); + color_lines.push_back(colors[1]); + color_lines.push_back(colors[2]); + + } + } + for(he = poly->edges_begin(); + he != poly->edges_end(); + he++) + { + if(!he->is_feature_edge()) continue; + 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); + } +} Scene_polyhedron_item::Scene_polyhedron_item() : Scene_item(), @@ -523,6 +614,7 @@ Scene_polyhedron_item::Scene_polyhedron_item() plugin_has_set_color_vector_m(false) { cur_shading=GL_FLAT; + is_selected = false; //init(); glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer @@ -543,6 +635,7 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) plugin_has_set_color_vector_m(false) { cur_shading=GL_FLAT; + is_selected = false; init(); glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer @@ -563,6 +656,7 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) plugin_has_set_color_vector_m(false) { cur_shading=GL_FLAT; + is_selected=false; init(); glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer @@ -613,7 +707,7 @@ init() } -Scene_polyhedron_item* +Scene_polyhedron_item* Scene_polyhedron_item::clone() const { return new Scene_polyhedron_item(*poly);} @@ -634,7 +728,7 @@ Scene_polyhedron_item::load(std::istream& in) } // Write polyhedron to .OFF file -bool +bool Scene_polyhedron_item::save(std::ostream& out) const { out.precision(13); @@ -642,7 +736,7 @@ Scene_polyhedron_item::save(std::ostream& out) const return (bool) out; } -QString +QString Scene_polyhedron_item::toolTip() const { if(!poly) @@ -759,9 +853,9 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { } -Polyhedron* +Polyhedron* Scene_polyhedron_item::polyhedron() { return poly; } -const Polyhedron* +const Polyhedron* Scene_polyhedron_item::polyhedron() const { return poly; } bool @@ -811,8 +905,19 @@ shading_mode_changed() changed(); } } +void +Scene_polyhedron_item::selection_changed(bool p_is_selected) +{ + if(p_is_selected != is_selected) + {is_selected = p_is_selected; + compute_colors(); + initialize_buffers(); + } + else + is_selected = p_is_selected; +} -void +void Scene_polyhedron_item::select(double orig_x, double orig_y, double orig_z, @@ -957,3 +1062,4 @@ void Scene_polyhedron_item::update_halfedge_indices() } #include "Scene_polyhedron_item.moc" + diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 02e5534ee48..12d1d2341dd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -60,6 +60,7 @@ virtual void draw_edges(Viewer_interface* viewer) const; public slots: virtual void changed(); virtual void shading_mode_changed(); + virtual void selection_changed(bool); void show_only_feature_edges(bool); void enable_facets_picking(bool); void set_erase_next_picked_facet(bool); @@ -120,6 +121,8 @@ private: GLuint compile_shaders(void); void compute_normals_and_vertices(void); void uniform_attrib(Viewer_interface*) const; + void compute_colors(); + }; // end class Scene_polyhedron_item #endif // SCENE_POLYHEDRON_ITEM_H From 140a6b408a3ef5fa5ab0d24fe36cb65663ca1de8 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Feb 2015 11:49:59 +0100 Subject: [PATCH 28/62] Implementation of draw_points just added the same function as polygon_soup_item and it works perfectly. --- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 16 ++ .../demo/Polyhedron/Scene_polyhedron_item.h | 168 +++++++++--------- 2 files changed, 100 insertions(+), 84 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index f88acac6821..a8c0ee729b4 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -852,6 +852,22 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { } +void +Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { + + glBindVertexArray(vao); + + // tells the GPU to use the program just created + glUseProgram(rendering_program); + + uniform_attrib(viewer); + + //draw the points + glDrawArrays(GL_POINTS, 0, positions_facets.size()/4); + + // Clean-up + glBindVertexArray(0); +} Polyhedron* Scene_polyhedron_item::polyhedron() { return poly; } diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 12d1d2341dd..3ca04971169 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -17,111 +17,111 @@ class QMenu; // This class represents a polyhedron in the OpenGL scene class SCENE_POLYHEDRON_ITEM_EXPORT Scene_polyhedron_item - : public Scene_item{ - Q_OBJECT + : public Scene_item{ + Q_OBJECT public: - Scene_polyhedron_item(); -// Scene_polyhedron_item(const Scene_polyhedron_item&); - Scene_polyhedron_item(const Polyhedron& p); - Scene_polyhedron_item(Polyhedron* const p); - ~Scene_polyhedron_item(); + Scene_polyhedron_item(); + // Scene_polyhedron_item(const Scene_polyhedron_item&); + Scene_polyhedron_item(const Polyhedron& p); + Scene_polyhedron_item(Polyhedron* const p); + ~Scene_polyhedron_item(); - Scene_polyhedron_item* clone() const; - - // IO - bool load(std::istream& in); - bool save(std::ostream& out) const; + Scene_polyhedron_item* clone() const; - // Function for displaying meta-data of the item - virtual QString toolTip() const; + // IO + bool load(std::istream& in); + bool save(std::ostream& out) const; - // Function to override the context menu - QMenu* contextMenu(); - - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } - // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list - void draw() const {} - virtual void draw(Viewer_interface*) const; - virtual void draw_edges() const {} -virtual void draw_edges(Viewer_interface* viewer) const; + // Function for displaying meta-data of the item + virtual QString toolTip() const; - // Get wrapped polyhedron - Polyhedron* polyhedron(); - const Polyhedron* polyhedron() const; + // Function to override the context menu + QMenu* contextMenu(); + + // Indicate if rendering mode is supported + virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } + // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list + void draw() const {} + virtual void draw(Viewer_interface*) const; + virtual void draw_edges() const {} + virtual void draw_edges(Viewer_interface* viewer) const; + void draw_points(Viewer_interface*) const; + // Get wrapped polyhedron + Polyhedron* polyhedron(); + const Polyhedron* polyhedron() const; + + // Get dimensions + bool isFinite() const { return true; } + bool isEmpty() const; + Bbox bbox() const; + std::vector& color_vector() {return colors_;} + void set_color_vector_read_only(bool on_off) {plugin_has_set_color_vector_m=on_off;} - // Get dimensions - bool isFinite() const { return true; } - bool isEmpty() const; - Bbox bbox() const; - std::vector& color_vector() {return colors_;} - void set_color_vector_read_only(bool on_off) {plugin_has_set_color_vector_m=on_off;} - public slots: - virtual void changed(); - virtual void shading_mode_changed(); - virtual void selection_changed(bool); - void show_only_feature_edges(bool); - void enable_facets_picking(bool); - void set_erase_next_picked_facet(bool); + virtual void changed(); + virtual void shading_mode_changed(); + virtual void selection_changed(bool); + void show_only_feature_edges(bool); + void enable_facets_picking(bool); + void set_erase_next_picked_facet(bool); - void select(double orig_x, - double orig_y, - double orig_z, - double dir_x, - double dir_y, - double dir_z); + void select(double orig_x, + double orig_y, + double orig_z, + double dir_x, + double dir_y, + double dir_z); - void update_vertex_indices(); - void update_facet_indices(); - void update_halfedge_indices(); + void update_vertex_indices(); + void update_facet_indices(); + void update_halfedge_indices(); signals: - void selected_vertex(void*); - void selected_facet(void*); - void selected_edge(void*); - void selected_halfedge(void*); - void item_is_about_to_be_changed(); // emitted in changed() + void selected_vertex(void*); + void selected_facet(void*); + void selected_edge(void*); + void selected_halfedge(void*); + void item_is_about_to_be_changed(); // emitted in changed() private: - // Initialization - void init(); - -private: - Polyhedron* poly; + // Initialization + void init(); private: - typedef Scene_item Base; - typedef std::vector Color_vector; + Polyhedron* poly; + +private: + typedef Scene_item Base; + typedef std::vector Color_vector; - Color_vector colors_; + Color_vector colors_; - bool show_only_feature_edges_m; - bool facet_picking_m; - bool erase_next_picked_facet_m; - //the following variable is used to indicate if the color vector must not be automatically updated. - bool plugin_has_set_color_vector_m; + bool show_only_feature_edges_m; + bool facet_picking_m; + bool erase_next_picked_facet_m; + //the following variable is used to indicate if the color vector must not be automatically updated. + bool plugin_has_set_color_vector_m; - std::vector positions_lines; - std::vector positions_facets; - std::vector normals; - std::vector color_lines; - std::vector color_facets; + std::vector positions_lines; + std::vector positions_facets; + std::vector normals; + std::vector color_lines; + std::vector color_facets; - GLuint rendering_program; - GLint location[8]; + GLuint rendering_program; + GLint location[8]; - GLuint vertex_shader; - GLuint fragment_shader; - GLuint program; - GLuint vao; - GLuint buffer[5]; - void initialize_buffers(); - GLuint compile_shaders(void); - void compute_normals_and_vertices(void); - void uniform_attrib(Viewer_interface*) const; - void compute_colors(); + GLuint vertex_shader; + GLuint fragment_shader; + GLuint program; + GLuint vao; + GLuint buffer[5]; + void initialize_buffers(); + GLuint compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*) const; + void compute_colors(); }; // end class Scene_polyhedron_item From 671c350f2cee6552257779da40e91845c85ac689 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Feb 2015 16:03:40 +0100 Subject: [PATCH 29/62] Split the rendering in two programs Facets and Edges have now each their own program. I had to change attrib_uniform to get a parameter which precise which program we are using. GlUseProgram is now done in attrib_uniform. --- Polyhedron/demo/Polyhedron/Scene.cpp | 2 - .../demo/Polyhedron/Scene_polyhedron_item.cpp | 209 +++++++++++------- .../demo/Polyhedron/Scene_polyhedron_item.h | 14 +- 3 files changed, 135 insertions(+), 90 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 0b355bbc5d8..a910d6adfc3 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -409,7 +409,6 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) ::glPopName(); } } - #ifdef CGAL_GLEW_ENABLED // Splatting if(!with_names && ms_splatting->isSupported()) @@ -436,7 +435,6 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) ms_splatting->finalize(); } #endif - } // workaround for Qt-4.2 (see above) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index a8c0ee729b4..bb61b992f41 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -72,14 +72,11 @@ struct light_info //specular GLfloat specular[4]; - GLfloat spec_power; - }; void Scene_polyhedron_item::initialize_buffers() { - glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); @@ -154,7 +151,7 @@ Scene_polyhedron_item::initialize_buffers() } -GLuint +void Scene_polyhedron_item::compile_shaders(void) { //fill the vertex shader @@ -163,16 +160,13 @@ Scene_polyhedron_item::compile_shaders(void) "#version 300 es \n" " \n" "layout (location = 0) in vec4 positions_facets; \n" - "layout (location = 1) in vec4 positions_lines; \n" "layout (location = 2) in vec3 vNormals; \n" "layout (location = 3) in vec3 color_facets; \n" - "layout (location = 4) in vec3 color_lines; \n" "uniform mat4 mvp_matrix; \n" "uniform mat4 mv_matrix; \n" "uniform int is_two_side; \n" - "uniform int is_wire; \n" "uniform vec3 light_pos; \n" "uniform vec3 light_diff; \n" "uniform vec3 light_spec; \n" @@ -184,22 +178,16 @@ Scene_polyhedron_item::compile_shaders(void) "void main(void) \n" "{ \n" - "vec4 P; \n" - "vec3 N; \n" - "vec3 L; \n" - "vec3 V; \n" - "vec3 R; \n" - "if(is_wire ==0){ \n" //number for the mode wireframe - " P = mv_matrix * positions_facets; \n" - " N = mat3(mv_matrix)* vNormals; \n" - " L = light_pos - P.xyz; \n" - " V = -P.xyz; \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" - " R = reflect(-L, 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_facets; \n" @@ -211,11 +199,6 @@ Scene_polyhedron_item::compile_shaders(void) " gl_Position = mvp_matrix *positions_facets; \n" "} \n" - "else{ \n" - " fColors = color_lines; \n" - " gl_Position = mvp_matrix * positions_lines; \n" - "} \n" - "} \n" }; //fill the fragment shader static const GLchar* fragment_shader_source[]= @@ -234,7 +217,7 @@ Scene_polyhedron_item::compile_shaders(void) }; //creates and compiles the vertex shader - vertex_shader = glCreateShader(GL_VERTEX_SHADER); + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader); @@ -250,7 +233,85 @@ Scene_polyhedron_item::compile_shaders(void) glGetShaderInfoLog(vertex_shader,maxLength,&length,log); std::cout<<"link error : Length = "<displayMessage(tr("TEST"),5000); glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); - glUseProgram(0); glBindVertexArray(0); - } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list @@ -837,19 +891,15 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glBindVertexArray(vao); // tells the GPU to use the program just created - glUseProgram(rendering_program); + // glUseProgram(rendering_program_lines); - uniform_attrib(viewer); + uniform_attrib(viewer,1); //draw the edges glDrawArrays(GL_LINES, 0, positions_lines.size()/4); // Clean-up glUseProgram(0); glBindVertexArray(0); - - - - } void @@ -858,9 +908,9 @@ Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { glBindVertexArray(vao); // tells the GPU to use the program just created - glUseProgram(rendering_program); + //glUseProgram(rendering_program_lines); - uniform_attrib(viewer); + uniform_attrib(viewer,1); //draw the points glDrawArrays(GL_POINTS, 0, positions_facets.size()/4); @@ -909,7 +959,6 @@ void Scene_polyhedron_item:: shading_mode_changed() { - GLint new_shading; glGetIntegerv(GL_SHADE_MODEL, &new_shading); prev_shading = cur_shading; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 3ca04971169..9d2b2894754 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -45,7 +45,8 @@ public: virtual void draw(Viewer_interface*) const; virtual void draw_edges() const {} virtual void draw_edges(Viewer_interface* viewer) const; - void draw_points(Viewer_interface*) const; + virtual void draw_points(Viewer_interface*) const; + // Get wrapped polyhedron Polyhedron* polyhedron(); const Polyhedron* polyhedron() const; @@ -108,19 +109,16 @@ private: std::vector color_lines; std::vector color_facets; - GLuint rendering_program; + GLuint rendering_program_facets; + GLuint rendering_program_lines; GLint location[8]; - - GLuint vertex_shader; - GLuint fragment_shader; - GLuint program; GLuint vao; GLuint buffer[5]; void initialize_buffers(); - GLuint compile_shaders(void); + void compile_shaders(void); void compute_normals_and_vertices(void); - void uniform_attrib(Viewer_interface*) const; + void uniform_attrib(Viewer_interface*, int) const; void compute_colors(); }; // end class Scene_polyhedron_item From b5c8876071de6368db708e722a2aa657c17e0812 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 2 Mar 2015 11:12:14 +0100 Subject: [PATCH 30/62] Not triangle facets implementation The polyhedron item is now able to draw plygons with not-triangle facets, but can no longer have a Gouraud Shading model. --- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 299 +++++++++++++++--- .../demo/Polyhedron/Scene_polyhedron_item.h | 10 +- 2 files changed, 263 insertions(+), 46 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index bb61b992f41..ed0a0e91066 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -1,21 +1,30 @@ #include #include "Scene_polyhedron_item.h" #include "Kernel_type.h" -#include "Polyhedron_type.h" #include #include #include #include + + +#include +#include +#include +#include +#include + +#include + #include #include +#include #include typedef CGAL::AABB_face_graph_triangle_primitive Primitive; typedef CGAL::AABB_traits AABB_traits; typedef CGAL::AABB_tree Input_facets_AABB_tree; - const char* aabb_property_name = "Scene_polyhedron_item aabb tree"; Input_facets_AABB_tree* get_aabb_tree(Scene_polyhedron_item* item) @@ -54,6 +63,218 @@ void delete_aabb_tree(Scene_polyhedron_item* item) } } +typedef typename Polyhedron::Traits Traits; +typedef typename Polyhedron::Facet Facet; +typedef CGAL::Triangulation_2_filtered_projection_traits_3 P_traits; +typedef typename Polyhedron::Halfedge_handle Halfedge_handle; +struct Face_info { + typename Polyhedron::Halfedge_handle e[3]; + bool is_external; +}; +typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; +typedef CGAL::Triangulation_face_base_with_info_2 Fb1; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::No_intersection_tag Itag; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDTbase; +typedef CGAL::Constrained_triangulation_plus_2 CDT; + +//Make sure all the facets are triangles +void +Scene_polyhedron_item::triangulate_facet(Facet_iterator fit) +{ + //Computes the normal of the facet + typename Traits::Vector_3 normal = + compute_facet_normal(*fit); + + P_traits cdt_traits(normal); + CDT cdt(cdt_traits); + + typename Facet::Halfedge_around_facet_circulator + he_circ = fit->facet_begin(), + he_circ_end(he_circ); + + // Iterates on the vector of facet handles + typename CDT::Vertex_handle previous, first; + do { + typename CDT::Vertex_handle vh = cdt.insert(he_circ->vertex()->point()); + if(first == 0) { + first = vh; + } + vh->info() = he_circ; + if(previous != 0 && previous != vh) { + cdt.insert_constraint(previous, vh); + } + previous = vh; + } while( ++he_circ != he_circ_end ); + cdt.insert_constraint(previous, first); + + // sets mark is_external + for(typename CDT::All_faces_iterator + fit = cdt.all_faces_begin(), + end = cdt.all_faces_end(); + fit != end; ++fit) + { + fit->info().is_external = false; + } + //check if the facet is external or internal + std::queue face_queue; + face_queue.push(cdt.infinite_vertex()->face()); + while(! face_queue.empty() ) { + typename CDT::Face_handle fh = face_queue.front(); + face_queue.pop(); + if(fh->info().is_external) continue; + fh->info().is_external = true; + for(int i = 0; i <3; ++i) { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + face_queue.push(fh->neighbor(i)); + } + } + } + + //iterates on the internal faces to add the vertices to the positions + //and the normals to the appropriate vectors + for(typename CDT::Finite_faces_iterator + ffit = cdt.finite_faces_begin(), + end = cdt.finite_faces_end(); + ffit != end; ++ffit) + { + if(ffit->info().is_external) + continue; + + positions_facets.push_back(ffit->vertex(0)->point().x()); + positions_facets.push_back(ffit->vertex(0)->point().y()); + positions_facets.push_back(ffit->vertex(0)->point().z()); + positions_facets.push_back(1.0); + + positions_facets.push_back(ffit->vertex(1)->point().x()); + positions_facets.push_back(ffit->vertex(1)->point().y()); + positions_facets.push_back(ffit->vertex(1)->point().z()); + positions_facets.push_back(1.0); + + positions_facets.push_back(ffit->vertex(2)->point().x()); + positions_facets.push_back(ffit->vertex(2)->point().y()); + positions_facets.push_back(ffit->vertex(2)->point().z()); + positions_facets.push_back(1.0); + + if (cur_shading == GL_FLAT || cur_shading == GL_SMOOTH) + { + + typedef typename Kernel::Vector_3 Vector; + Vector n = compute_facet_normal(*fit); + 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()); + } + + + + + } +} + +void +Scene_polyhedron_item::triangulate_facet_color(Facet_iterator fit) +{ + typename Traits::Vector_3 normal = + compute_facet_normal(*fit); + + P_traits cdt_traits(normal); + CDT cdt(cdt_traits); + + typename Facet::Halfedge_around_facet_circulator + he_circ = fit->facet_begin(), + he_circ_end(he_circ); + + // Iterates on the vector of facet handles + typename CDT::Vertex_handle previous, first; + do { + typename CDT::Vertex_handle vh = cdt.insert(he_circ->vertex()->point()); + if(first == 0) { + first = vh; + } + vh->info() = he_circ; + if(previous != 0 && previous != vh) { + cdt.insert_constraint(previous, vh); + } + previous = vh; + } while( ++he_circ != he_circ_end ); + cdt.insert_constraint(previous, first); + + // sets mark is_external + for(typename CDT::All_faces_iterator + fit = cdt.all_faces_begin(), + end = cdt.all_faces_end(); + fit != end; ++fit) + { + fit->info().is_external = false; + } + //check if the facet is external or internal + std::queue face_queue; + face_queue.push(cdt.infinite_vertex()->face()); + while(! face_queue.empty() ) { + typename CDT::Face_handle fh = face_queue.front(); + face_queue.pop(); + if(fh->info().is_external) continue; + fh->info().is_external = true; + for(int i = 0; i <3; ++i) { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + face_queue.push(fh->neighbor(i)); + } + } + } + + //iterates on the internal faces to add the vertices to the positions vector + for(typename CDT::Finite_faces_iterator + ffit = cdt.finite_faces_begin(), + end = cdt.finite_faces_end(); + ffit != end; ++ffit) + { + if(ffit->info().is_external) + continue; + //Add Colors + for(int i = 0; i<3; ++i) + { + const int this_patch_id = fit->patch_id(); + if(is_selected) + { + color_facets.push_back(colors_[this_patch_id].lighter(120).redF()); + color_facets.push_back(colors_[this_patch_id].lighter(120).greenF()); + color_facets.push_back(colors_[this_patch_id].lighter(120).blueF()); + + color_facets.push_back(colors_[this_patch_id].lighter(120).redF()); + color_facets.push_back(colors_[this_patch_id].lighter(120).greenF()); + color_facets.push_back(colors_[this_patch_id].lighter(120).blueF()); + } + else + { + color_facets.push_back(colors_[this_patch_id].redF()); + color_facets.push_back(colors_[this_patch_id].greenF()); + color_facets.push_back(colors_[this_patch_id].blueF()); + + color_facets.push_back(colors_[this_patch_id].redF()); + color_facets.push_back(colors_[this_patch_id].greenF()); + color_facets.push_back(colors_[this_patch_id].blueF()); + + } + } + } +} + #include #include #include @@ -77,7 +298,7 @@ struct light_info void Scene_polyhedron_item::initialize_buffers() { - glBindVertexArray(vao); + glBindVertexArray(vao[0]); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glBufferData(GL_ARRAY_BUFFER, @@ -211,7 +432,6 @@ Scene_polyhedron_item::compile_shaders(void) " \n" "void main(void) \n" "{ \n" - "/* Lighting gestion */ \n" " color = fColors; \n" //polygons de couleur rouge "} \n" }; @@ -221,7 +441,7 @@ Scene_polyhedron_item::compile_shaders(void) glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader); - GLint result; + /* GLint result; glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); if(result == GL_TRUE){ std::cout<<"Vertex compilation OK"<displayMessage(tr("TEST"),5000); glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); glUseProgram(0); glBindVertexArray(0); @@ -888,7 +1101,7 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { - glBindVertexArray(vao); + glBindVertexArray(vao[0]); // tells the GPU to use the program just created // glUseProgram(rendering_program_lines); @@ -905,7 +1118,7 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { void Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { - glBindVertexArray(vao); + glBindVertexArray(vao[0]); // tells the GPU to use the program just created //glUseProgram(rendering_program_lines); @@ -913,7 +1126,7 @@ Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { uniform_attrib(viewer,1); //draw the points - glDrawArrays(GL_POINTS, 0, positions_facets.size()/4); + glDrawArrays(GL_POINTS, 0, positions_facets.size()); // Clean-up glBindVertexArray(0); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 9d2b2894754..6682889640e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -5,6 +5,7 @@ #include "Scene_polyhedron_item_config.h" #include "Scene_item.h" //<- modif ? #include "Polyhedron_type_fwd.h" +#include "Polyhedron_type.h" #include "Viewer.h" #include @@ -94,6 +95,7 @@ private: private: typedef Scene_item Base; typedef std::vector Color_vector; + typedef typename Polyhedron::Facet_iterator Facet_iterator; Color_vector colors_; @@ -111,15 +113,17 @@ private: GLuint rendering_program_facets; GLuint rendering_program_lines; - GLint location[8]; + GLint location[9]; - GLuint vao; - GLuint buffer[5]; + GLuint vao[1]; + GLuint buffer[6]; void initialize_buffers(); void compile_shaders(void); void compute_normals_and_vertices(void); void uniform_attrib(Viewer_interface*, int) const; void compute_colors(); + void triangulate_facet(Facet_iterator ); + void triangulate_facet_color(Facet_iterator ); }; // end class Scene_polyhedron_item From 1f22ca4ca2bc3e53f3aed5d0c024ffa3c3afe903 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 2 Mar 2015 12:06:47 +0100 Subject: [PATCH 31/62] Triangulation test updates The test to know if a polygon is triangulated is now done once per changed() call, and it iterates the faces until it finds one that is not a triangle. --- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 144 +++++++++++------- .../demo/Polyhedron/Scene_polyhedron_item.h | 2 + 2 files changed, 92 insertions(+), 54 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index ed0a0e91066..2056dc5891f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -85,6 +85,30 @@ typedef CGAL::Constrained_triangulation_plus_2 CDT; //Make sure all the facets are triangles void +Scene_polyhedron_item::is_Triangulated() +{ + typedef typename Polyhedron::Halfedge_around_facet_circulator HF_circulator; + Facet_iterator f = poly->facets_begin(); + int nb_points_per_facet =0; + + for(f = poly->facets_begin(); + f != poly->facets_end(); + f++) + { + HF_circulator he = f->facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + nb_points_per_facet++; + } + + if(nb_points_per_facet !=3) + is_Triangle = false; + break; + nb_points_per_facet = 0; + } +} +void Scene_polyhedron_item::triangulate_facet(Facet_iterator fit) { //Computes the normal of the facet @@ -654,51 +678,55 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) Facet_iterator f = poly->facets_begin(); - for(f = poly->facets_begin(); f != poly->facets_end(); f++) { - triangulate_facet(f); - /* HF_circulator he = f->facet_begin(); - HF_circulator end = he; - CGAL_For_all(he,end) + + if(!is_Triangle) + triangulate_facet(f); + else { - - // If Flat shading:1 normal per polygon added once per vertex - if (cur_shading == GL_FLAT) + // std::cout<<"Triangles"<facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) { - Vector n = compute_facet_normal(*f); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + // If Flat shading:1 normal per polygon added once per vertex + if (cur_shading == GL_FLAT) + { + + Vector n = compute_facet_normal(*f); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + } + + + // revolve around current face to get vertices + + + // If Gouraud shading: 1 normal per vertex + else if (cur_shading == GL_SMOOTH) + { + + Vector n = compute_vertex_normal(*he->vertex()); + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + } + const int this_patch_id = f->patch_id(); + + //position + const Point& p = he->vertex()->point(); + positions_facets.push_back(p.x()); + positions_facets.push_back(p.y()); + positions_facets.push_back(p.z()); + positions_facets.push_back(1.0); } - - - // revolve around current face to get vertices - - - // If Gouraud shading: 1 normal per vertex - else if (cur_shading == GL_SMOOTH) - { - - Vector n = compute_vertex_normal(*he->vertex()); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); - } - const int this_patch_id = f->patch_id(); - - //position - const Point& p = he->vertex()->point(); - positions_facets.push_back(p.x()); - positions_facets.push_back(p.y()); - positions_facets.push_back(p.z()); - positions_facets.push_back(1.0); } - */ - std::cout<<"Nombre de vertices = "< #include +#include +#include +#include +#include +#include +#include @@ -92,8 +99,8 @@ Scene_polygon_soup_item::initialize_buffers() glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glBufferData(GL_ARRAY_BUFFER, (positions_poly.size())*sizeof(float), - positions_poly.data(), - GL_STATIC_DRAW); + positions_poly.data(), + GL_STATIC_DRAW); glVertexAttribPointer(0, //number of the buffer 4, //number of floats to be taken GL_FLOAT, // type of data @@ -105,22 +112,36 @@ Scene_polygon_soup_item::initialize_buffers() glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); glBufferData(GL_ARRAY_BUFFER, - (normals.size())*sizeof(float), - normals.data(), GL_STATIC_DRAW); - glVertexAttribPointer(1, - 3, - GL_FLOAT, - GL_FALSE, - 0, - NULL - ); + (positions_lines.size())*sizeof(float), + positions_lines.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.size())*sizeof(float), + normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(2); + // Clean-up - glBindVertexArray(0); + glBindVertexArray(0); } -GLuint +void Scene_polygon_soup_item::compile_shaders(void) { //fill the vertex shader @@ -129,7 +150,7 @@ Scene_polygon_soup_item::compile_shaders(void) "#version 300 es \n" " \n" "layout (location = 0) in vec4 positions_poly; \n" - "layout (location = 1) in vec3 vNormals; \n" + "layout (location = 2) in vec3 vNormals; \n" "uniform mat4 mvp_matrix; \n" "uniform mat4 mv_matrix; \n" @@ -188,7 +209,7 @@ Scene_polygon_soup_item::compile_shaders(void) glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader); - GLint result; + /*GLint result; glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); if(result == GL_TRUE){ std::cout<<"Vertex compilation OK"<points, soup->polygons); emit changed(); + return result; } @@ -552,9 +784,9 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { glBindVertexArray(vao); // tells the GPU to use the program just created - glUseProgram(rendering_program); + glUseProgram(rendering_program_poly); - uniform_attrib(viewer); + uniform_attrib(viewer,0); //draw the polygons // the third argument is the number of vec4 that will be entered @@ -573,9 +805,9 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { glBindVertexArray(vao); // tells the GPU to use the program just created - glUseProgram(rendering_program); + glUseProgram(rendering_program_poly); - uniform_attrib(viewer); + uniform_attrib(viewer,0); //draw the points glDrawArrays(GL_POINTS, 0, positions_poly.size()/4); @@ -584,6 +816,24 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { glBindVertexArray(0); } +void +Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { + if(soup == 0) return; + + glBindVertexArray(vao); + + // tells the GPU to use the program just created + glUseProgram(rendering_program_lines); + + uniform_attrib(viewer,1); + //draw the edges + glDrawArrays(GL_LINES, 0, positions_lines.size()/4); + // Clean-up + glUseProgram(0); + glBindVertexArray(0); + +} + bool Scene_polygon_soup_item::isEmpty() const { diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 8c77bd986cc..fcca2e0b611 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -14,171 +14,179 @@ struct Polygon_soup { - typedef Kernel::Point_3 Point_3; - typedef std::vector Points; - typedef std::vector Polygon_3; - typedef std::map, std::set > Edges_map; - typedef boost::array Edge; - typedef std::vector Polygons; - typedef std::set Edges; - typedef Polygons::size_type size_type; - Points points; - Polygons polygons; - Edges_map edges; - Edges non_manifold_edges; - bool display_non_manifold_edges; + typedef Kernel::Point_3 Point_3; + typedef std::vector Points; + typedef std::vector Polygon_3; + typedef std::map, std::set > Edges_map; + typedef boost::array Edge; + typedef std::vector Polygons; + typedef std::set Edges; + typedef Polygons::size_type size_type; + Points points; + Polygons polygons; + Edges_map edges; + Edges non_manifold_edges; + bool display_non_manifold_edges; - Polygon_soup(): - display_non_manifold_edges(false){} + Polygon_soup(): + display_non_manifold_edges(false){} - Polygon_soup* clone() const { - Polygon_soup* result = new Polygon_soup(); - result->points = points; - result->polygons = polygons; - result->edges = edges; - result->non_manifold_edges = non_manifold_edges; - result->display_non_manifold_edges = display_non_manifold_edges; - return result; - } - - void clear() { - points.clear(); - polygons.clear(); - edges.clear(); - non_manifold_edges.clear(); - } - - void fill_edges() { - // Fill edges - edges.clear(); - for(size_type i = 0; i < polygons.size(); ++i) - { - const size_type size = polygons[i].size(); - for(size_type j = 0; j < size; ++j) { - const std::size_t& i0 = polygons[i][j]; - const std::size_t& i1 = polygons[i][ j+1 < size ? j+1: 0]; - edges[std::make_pair(i0, i1)].insert(i); -// qDebug() << tr("edges[std::make_pair(%1, %2)].insert(%3). Size=%4") -// .arg(i0).arg(i1).arg(i).arg(edges[std::make_pair(i0, i1)].size()); - } + Polygon_soup* clone() const { + Polygon_soup* result = new Polygon_soup(); + result->points = points; + result->polygons = polygons; + result->edges = edges; + result->non_manifold_edges = non_manifold_edges; + result->display_non_manifold_edges = display_non_manifold_edges; + return result; } - // Fill non-manifold edges - non_manifold_edges.clear(); - for(size_type i = 0; i < polygons.size(); ++i) - { - const size_type size = polygons[i].size(); - for(size_type j = 0; j < size; ++j) { - const std::size_t& i0 = polygons[i][j]; - const std::size_t& i1 = polygons[i][ j+1 < size ? j+1: 0]; - if( (i0 < i1) && - (edges[std::make_pair(i0, i1)].size() + - edges[std::make_pair(i1, i0)].size() > 2) ) + void clear() { + points.clear(); + polygons.clear(); + edges.clear(); + non_manifold_edges.clear(); + } + + void fill_edges() { + // Fill edges + std::cout<<"FILL_EDGES"< i1) std::swap(edge[0], edge[1]); - non_manifold_edges.insert(edge); + const size_type size = polygons[i].size(); + for(size_type j = 0; j < size; ++j) { + const std::size_t& i0 = polygons[i][j]; + const std::size_t& i1 = polygons[i][ j+1 < size ? j+1: 0]; + edges[std::make_pair(i0, i1)].insert(i); + // qDebug() << tr("edges[std::make_pair(%1, %2)].insert(%3). Size=%4") + // .arg(i0).arg(i1).arg(i).arg(edges[std::make_pair(i0, i1)].size()); + } } - } - } - } - void inverse_orientation(const std::size_t index) { - std::reverse(polygons[index].begin(), polygons[index].end()); - } + // Fill non-manifold edges + non_manifold_edges.clear(); + for(size_type i = 0; i < polygons.size(); ++i) + { + const size_type size = polygons[i].size(); + for(size_type j = 0; j < size; ++j) { + const std::size_t& i0 = polygons[i][j]; + const std::size_t& i1 = polygons[i][ j+1 < size ? j+1: 0]; + + if( (i0 < i1) && + (edges[std::make_pair(i0, i1)].size() + + edges[std::make_pair(i1, i0)].size() > 2) ) + { + Edge edge; + edge[0] = i0; + edge[1] = i1; + if(i0 > i1) std::swap(edge[0], edge[1]); + non_manifold_edges.insert(edge); + + } + } + } + } + + void inverse_orientation(const std::size_t index) { + std::reverse(polygons[index].begin(), polygons[index].end()); + } }; class Scene_polyhedron_item; class SCENE_POLYGON_SOUP_ITEM_EXPORT Scene_polygon_soup_item - : public Scene_item + : public Scene_item { - typedef Kernel::Point_3 Point_3; + typedef Kernel::Point_3 Point_3; - Q_OBJECT + Q_OBJECT public: - Scene_polygon_soup_item(); - ~Scene_polygon_soup_item(); + Scene_polygon_soup_item(); + ~Scene_polygon_soup_item(); - Scene_polygon_soup_item* clone() const; - bool load(std::istream& in); - void load(Scene_polyhedron_item*); + Scene_polygon_soup_item* clone() const; + bool load(std::istream& in); + void load(Scene_polyhedron_item*); - template - inline void load(const std::vector& points, const std::vector& polygons) - { - if(!soup) - soup = new Polygon_soup; - soup->clear(); + template + inline void load(const std::vector& points, const std::vector& polygons) + { + if(!soup) + soup = new Polygon_soup; + soup->clear(); - /// add points - soup->points.reserve(points.size()); - BOOST_FOREACH(const Point& p, points) - soup->points.push_back( Point_3(p[0], p[1], p[2]) ); + /// add points + soup->points.reserve(points.size()); + BOOST_FOREACH(const Point& p, points) + soup->points.push_back( Point_3(p[0], p[1], p[2]) ); - /// add polygons - std::size_t nb_polygons=polygons.size(); - soup->polygons.resize(nb_polygons); - for(std::size_t i=0; ipolygons[i].assign(polygons[i].begin(), polygons[i].end()); + /// add polygons + std::size_t nb_polygons=polygons.size(); + soup->polygons.resize(nb_polygons); + for(std::size_t i=0; ipolygons[i].assign(polygons[i].begin(), polygons[i].end()); - /// fill non-manifold edges container - soup->fill_edges(); - oriented = false; - } + /// fill non-manifold edges container + soup->fill_edges(); + oriented = false; + } - bool save(std::ostream& out) const; + bool save(std::ostream& out) const; - QString toolTip() const; + QString toolTip() const; - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! - // OpenGL drawing in a display list - void draw() const {} - void draw(Viewer_interface*) const; - void draw_points(Viewer_interface*) const; - void changed(); - bool isFinite() const { return true; } - bool isEmpty() const; - Bbox bbox() const; + // Indicate if rendering mode is supported + virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! + // OpenGL drawing in a display list + virtual void draw() const {} + virtual void draw(Viewer_interface*) const; + virtual void draw_points(Viewer_interface*) const; + virtual void draw_edges(Viewer_interface* viewer) const; + void changed(); + bool isFinite() const { return true; } + bool isEmpty() const; + Bbox bbox() const; - void new_vertex(const double&, const double&, const double&); - void new_triangle(const std::size_t, const std::size_t, const std::size_t); + void new_vertex(const double&, const double&, const double&); + void new_triangle(const std::size_t, const std::size_t, const std::size_t); - void init_polygon_soup(std::size_t nb_pts, std::size_t nb_polygons); - void finalize_polygon_soup(); + void init_polygon_soup(std::size_t nb_pts, std::size_t nb_polygons); + void finalize_polygon_soup(); public slots: - void shuffle_orientations(); - bool orient(); - bool exportAsPolyhedron(Polyhedron*); - void inside_out(); + void shuffle_orientations(); + bool orient(); + bool exportAsPolyhedron(Polyhedron*); + void inside_out(); - void setDisplayNonManifoldEdges(const bool); - bool displayNonManifoldEdges() const; + void setDisplayNonManifoldEdges(const bool); + bool displayNonManifoldEdges() const; private: - Polygon_soup* soup; - bool oriented; - std::vector positions_poly; - std::vector normals; + typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; + Polygon_soup* soup; + bool oriented; + std::vector positions_poly; + std::vector positions_lines; + std::vector normals; - GLuint rendering_program; - GLint location[7]; + GLuint rendering_program_poly; + GLuint rendering_program_lines; + GLint location[9]; - GLuint vertex_shader; - GLuint fragment_shader; - GLuint program; - GLuint vao; - GLuint buffer[2]; - void initialize_buffers(); - GLuint compile_shaders(void); - void compute_normals_and_vertices(void); - void uniform_attrib(Viewer_interface*) const; + GLuint vertex_shader; + GLuint fragment_shader; + GLuint vao; + GLuint buffer[3]; + void initialize_buffers(); + void compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*, int) const; + //void is_Triangulated(); + void triangulate_polygon(Polygons_iterator ); }; // end class Scene_polygon_soup_item diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 2056dc5891f..1e842c4c236 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -14,7 +14,6 @@ #include #include #include - #include #include @@ -665,8 +664,6 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) //Facets - - typedef typename Polyhedron::Traits Kernel; typedef typename Kernel::Point_3 Point; typedef typename Kernel::Vector_3 Vector; @@ -1139,7 +1136,7 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glBindVertexArray(vao[0]); // tells the GPU to use the program just created - // glUseProgram(rendering_program_lines); + glUseProgram(rendering_program_lines); uniform_attrib(viewer,1); From 3a945c9e009b9b3328b26008fa35f74c04dd63b9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 5 Mar 2015 14:06:40 +0100 Subject: [PATCH 33/62] textured polyhedron update The textured polyhedron now use shaders to display an abject and its textures. The draw function doesn't call the Textured_Polyhedron.h function anymore, only to compute the normals. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 6 +- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 10 +- .../Scene_textured_polyhedron_item.cpp | 671 ++++++++++++++++-- .../Scene_textured_polyhedron_item.h | 37 +- 4 files changed, 659 insertions(+), 65 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 1e13b3cb9ba..99e8233d021 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -200,7 +200,7 @@ Scene_polygon_soup_item::compile_shaders(void) "void main(void) \n" "{ \n" "/* Lighting gestion */ \n" - " color = fColors; \n" //polygons de couleur rouge + " color = fColors; \n" "} \n" }; @@ -598,7 +598,6 @@ Scene_polygon_soup_item::Scene_polygon_soup_item() glGenVertexArrays(1, &vao); //Generates an integer which will be used as ID for each buffer glGenBuffers(3, buffer); - compile_shaders(); } @@ -796,6 +795,9 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { // Clean-up glUseProgram(0); glBindVertexArray(0); + + + } void diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 1e842c4c236..663ddc295db 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -102,8 +102,12 @@ Scene_polyhedron_item::is_Triangulated() } if(nb_points_per_facet !=3) + { + std::cout<<"NOT TRIANGLE"< typedef EPIC_kernel::Point_3 Point; +struct light_info +{ + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; +}; + +void Scene_textured_polyhedron_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 + 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_lines.size())*sizeof(float), + positions_lines.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.size())*sizeof(float), + normals.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, + (textures_map_facets.size())*sizeof(float), + textures_map_facets.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 2, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glBufferData(GL_ARRAY_BUFFER, + (textures_map_lines.size())*sizeof(float), + textures_map_lines.data(), GL_STATIC_DRAW); + glVertexAttribPointer(4, + 2, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(4); + + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGB, + texture.GetWidth(), + texture.GetHeight(), + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + texture.GetData()); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + // Clean-up + glBindVertexArray(0); +} + +void Scene_textured_polyhedron_item::compile_shaders(void) +{ + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec4 positions_facets; \n" + "layout (location = 2) in vec3 vNormals; \n" + "layout (location = 3) in vec2 v_texCoord; \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" + "uniform vec3 color_facets; \n" + "uniform sampler2D s_texture; \n" + "float spec_power = 128.0; \n" + "vec3 temp_color; \n" + "out highp vec3 fColors; \n" + " \n" + "void main(void) \n" + "{ \n" + "temp_color = vec3(texture(s_texture, v_texCoord)); \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 * temp_color; \n" + " else \n" + " diffuse = max(dot(N,L), 0.0) * light_diff * temp_color; \n" + " vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" + " fColors =color_facets * (light_amb * temp_color + 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" + }; + + //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_facets = program; + GLint result; + glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); + if(result == GL_TRUE){ + std::cout<<"Vertex compilation OK"<facet_begin(); + Halfedge_around_facet_circulator end = he; + CGAL_For_all(he,end) + { + + // If Flat shading:1 normal per polygon added once per vertex + if (cur_shading == GL_FLAT) + { + + Vector n = compute_facet_normal(*f); + normals.push_back(n[0]); + normals.push_back(n[1]); + normals.push_back(n[2]); + } + + + // revolve around current face to get vertices + + + // If Gouraud shading: 1 normal per vertex + else if(cur_shading == GL_SMOOTH) + { + + const typename Facet::Normal_3& n = he->vertex()->normal(); + normals.push_back(n[0]); + normals.push_back(n[1]); + normals.push_back(n[2]); + } + + //position + const Point& p = he->vertex()->point(); + positions_facets.push_back(p.x()); + positions_facets.push_back(p.y()); + positions_facets.push_back(p.z()); + positions_facets.push_back(1.0); + + const double u = he->vertex()->u(); + const double v = he->vertex()->v(); + textures_map_facets.push_back(u); + textures_map_facets.push_back(v); + } + + + } + //Lines + typedef Kernel::Point_3 Point; + typedef Base::Edge_iterator Edge_iterator; + + Edge_iterator he; + + for(he = poly->edges_begin(); + he != poly->edges_end(); + he++) + { + + const Point& a = he->vertex()->point(); + const Point& b = he->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(1.0); + + const double u = he->vertex()->u(); + const double v = he->vertex()->v(); + textures_map_lines.push_back(u); + textures_map_lines.push_back(v); + + positions_lines.push_back(b.x()); + positions_lines.push_back(b.y()); + positions_lines.push_back(b.z()); + positions_lines.push_back(1.0); + + const double ou = he->opposite()->vertex()->u(); + const double ov = he->opposite()->vertex()->v(); + textures_map_lines.push_back(ou); + textures_map_lines.push_back(ov); + + } + + + //Allocates a uniform location for the MVP and MV matrices + location[0] = glGetUniformLocation(rendering_program_facets, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_facets, "mv_matrix"); + + //Allocates a uniform location for the light values + 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"); + sampler_location = glGetUniformLocation(rendering_program_facets, "s_texture"); + location[7] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[8] = glGetUniformLocation(rendering_program_facets, "color_facets"); + location[9] = glGetUniformLocation(rendering_program_lines, "color_lines"); + +} Scene_textured_polyhedron_item::Scene_textured_polyhedron_item() - : Scene_item_with_display_list(), - poly(new Textured_polyhedron) + : Scene_item(),positions_lines(0),positions_facets(0),normals(0),textures_map_facets(0), + textures_map_lines(0),poly(new Textured_polyhedron) { - texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); + texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); + cur_shading=GL_FLAT; + is_selected=false; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(5, buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &textureId); + + compile_shaders(); + changed(); } Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(Textured_polyhedron* const p) - : Scene_item_with_display_list(), - poly(p) + : Scene_item(),smooth_shading(true),positions_lines(0),positions_facets(0),textures_map_facets(0), + textures_map_lines(0), poly(p) { - texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); + cur_shading=GL_FLAT; + is_selected=false; + texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(5, buffer); + + compile_shaders(); + changed(); } Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Textured_polyhedron& p) - : Scene_item_with_display_list(), - poly(new Textured_polyhedron(p)) + : Scene_item(),smooth_shading(true),positions_lines(0),positions_facets(0),textures_map_facets(0), + textures_map_lines(0), poly(new Textured_polyhedron(p)) { - texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); + texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); + cur_shading=GL_FLAT; + is_selected=false; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(5, buffer); + + compile_shaders(); + changed(); } // Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Scene_textured_polyhedron_item& item) @@ -36,68 +535,98 @@ Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Textured_po Scene_textured_polyhedron_item::~Scene_textured_polyhedron_item() { - delete poly; + delete poly; } Scene_textured_polyhedron_item* Scene_textured_polyhedron_item::clone() const { - return new Scene_textured_polyhedron_item(*poly); + return new Scene_textured_polyhedron_item(*poly); } // Load textured_polyhedron from .OFF file bool Scene_textured_polyhedron_item::load(std::istream& in) { - in >> *poly; - return in && !isEmpty(); + std::cout<<"LOAD"<> *poly; + changed(); + return in && !isEmpty(); } // Write textured_polyhedron to .OFF file bool Scene_textured_polyhedron_item::save(std::ostream& out) const { - out << *poly; - return (bool) out; + out << *poly; + return (bool) out; } QString Scene_textured_polyhedron_item::toolTip() const { - if(!poly) - return QString(); + if(!poly) + return QString(); - return QObject::tr("

Textured polyhedron %1 (mode: %5, color: %6)

" - "

Number of vertices: %2
" - "Number of edges: %3
" - "Number of facets: %4

") - .arg(this->name()) - .arg(poly->size_of_vertices()) - .arg(poly->size_of_halfedges()/2) - .arg(poly->size_of_facets()) - .arg(this->renderingModeName()) - .arg(this->color().name()); + return QObject::tr("

Textured polyhedron %1 (mode: %5, color: %6)

" + "

Number of vertices: %2
" + "Number of edges: %3
" + "Number of facets: %4

") + .arg(this->name()) + .arg(poly->size_of_vertices()) + .arg(poly->size_of_halfedges()/2) + .arg(poly->size_of_facets()) + .arg(this->renderingModeName()) + .arg(this->color().name()); } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list -void Scene_textured_polyhedron_item::direct_draw() const { - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGB, - texture.GetWidth(), - texture.GetHeight(), - 0, - GL_RGB, - GL_UNSIGNED_BYTE, - texture.GetData()); - glEnable(GL_TEXTURE_2D); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +void Scene_textured_polyhedron_item::draw(Viewer_interface* viewer) const { - poly->gl_draw_textured_triangles(true, true, 1.0); - glDisable(GL_TEXTURE_2D); + glBindVertexArray(vao[0]); + + // tells the GPU to use the program just created + glUseProgram(rendering_program_facets); + uniform_attrib(viewer,0); + //draw the polygons + // the third argument is the number of vec4 that will be entered + glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); + glUseProgram(0); + glBindVertexArray(0); + + + /* glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGB, + texture.GetWidth(), + texture.GetHeight(), + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + texture.GetData()); + glEnable(GL_TEXTURE_2D); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + poly->gl_draw_textured_triangles(true, true, 1.0); + glDisable(GL_TEXTURE_2D);*/ + + +} +void Scene_textured_polyhedron_item::draw_edges(Viewer_interface* viewer) const { + glBindVertexArray(vao[0]); + + // tells the GPU to use the program just created + glUseProgram(rendering_program_lines); + + uniform_attrib(viewer,1); + + //draw the edges + glDrawArrays(GL_LINES, 0, positions_lines.size()/4); + // Clean-up + glUseProgram(0); + glBindVertexArray(0); } Textured_polyhedron* @@ -107,20 +636,50 @@ Scene_textured_polyhedron_item::textured_polyhedron() const { return poly; } bool Scene_textured_polyhedron_item::isEmpty() const { - return (poly == 0) || poly->empty(); + return (poly == 0) || poly->empty(); } Scene_textured_polyhedron_item::Bbox Scene_textured_polyhedron_item::bbox() const { - const Point& p = *(poly->points_begin()); - CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); - for(Textured_polyhedron::Point_iterator it = poly->points_begin(); - it != poly->points_end(); - ++it) { - bbox = bbox + it->bbox(); - } - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + const Point& p = *(poly->points_begin()); + CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); + for(Textured_polyhedron::Point_iterator it = poly->points_begin(); + it != poly->points_end(); + ++it) { + bbox = bbox + it->bbox(); + } + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); +} +void +Scene_textured_polyhedron_item::changed() +{ + compute_normals_and_vertices(); + initialize_buffers(); +} +void +Scene_textured_polyhedron_item:: +shading_mode_changed() +{ + GLint new_shading; + glGetIntegerv(GL_SHADE_MODEL, &new_shading); + prev_shading = cur_shading; + cur_shading = new_shading; + if(prev_shading != cur_shading) + { + //Change the normals + changed(); + } +} +void +Scene_textured_polyhedron_item::selection_changed(bool p_is_selected) +{ + if(p_is_selected != is_selected) + { + is_selected = p_is_selected; + initialize_buffers(); + } + else + is_selected = p_is_selected; } - #include "Scene_textured_polyhedron_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h index f2c9355dbde..371d2c80745 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h @@ -1,15 +1,16 @@ #ifndef SCENE_TEXTURED_POLYHEDRON_ITEM_H #define SCENE_TEXTURED_POLYHEDRON_ITEM_H - +#include #include "Scene_textured_polyhedron_item_config.h" -#include "Scene_item_with_display_list.h" +#include "Scene_item.h" +#include "Viewer_interface.h" #include "Textured_polyhedron_type_fwd.h" #include #include "texture.h" // This class represents a textured polyhedron in the OpenGL scene class SCENE_TEXTURED_POLYHEDRON_ITEM_EXPORT Scene_textured_polyhedron_item - : public Scene_item_with_display_list { + : public Scene_item { Q_OBJECT public: Scene_textured_polyhedron_item(); @@ -30,7 +31,10 @@ public: // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const { return m != Splatting; } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list - virtual void direct_draw() const; + void draw() const {} + virtual void draw(Viewer_interface*) const; + virtual void draw_edges() const {} + virtual void draw_edges(Viewer_interface* viewer) const; // Get wrapped textured_polyhedron Textured_polyhedron* textured_polyhedron(); @@ -41,9 +45,34 @@ public: bool isEmpty() const; Bbox bbox() const; + virtual void changed(); + virtual void shading_mode_changed(); + virtual void selection_changed(bool); + private: Textured_polyhedron* poly; Texture texture; + std::vector positions_lines; + std::vector positions_facets; + std::vector normals; + std::vector textures_map_facets; + std::vector textures_map_lines; + + + GLuint rendering_program_facets; + GLuint rendering_program_lines; + GLuint textureId; + GLint location[10]; + GLint sampler_location; + + GLuint vao[1]; + GLuint buffer[5]; + bool smooth_shading; + void initialize_buffers(); + void compile_shaders(void); + void uniform_attrib(Viewer_interface*, int) const; + void compute_normals_and_vertices(void); + }; // end class Scene_textured_polyhedron_item From 4a48cfb524e174fa11d5ec77cfee8835dfb8d14b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 9 Mar 2015 16:13:38 +0100 Subject: [PATCH 34/62] 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 From 6d2e24c4fc757aa2695cfab949843bcb3f826ede Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 9 Mar 2015 17:06:51 +0100 Subject: [PATCH 35/62] Wired Spheres as Quads. The spheres appears with quads in the wiremode. It was just an implementation of the conversion code from triangles to lines when filling the positions_wire_spheres vector. --- .../demo/Polyhedron/Scene_polylines_item.cpp | 86 ++++++++++++++++--- 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index b1b7fa97ecb..152aea022bf 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -98,6 +98,7 @@ void Scene_polylines_item::create_Sphere(double R) for (int p=rings; p<180-rings; p+=rings) for(int t=0; t<360; t+=sectors) { + //A P = p*M_PI/180.0; T = t*M_PI/180.0; x[0] = sin(P) * cos(T) ; @@ -113,7 +114,7 @@ void Scene_polylines_item::create_Sphere(double R) normals_spheres.push_back(y[0]); normals_spheres.push_back(z[0]); - + //B P = (p+rings)*M_PI/180.0; T = t*M_PI/180.0; x[1] = sin(P) * cos(T) ; @@ -128,7 +129,7 @@ void Scene_polylines_item::create_Sphere(double R) normals_spheres.push_back(y[1]); normals_spheres.push_back(z[1]); - + //C P = p*M_PI/180.0; T = (t+sectors)*M_PI/180.0; x[2] = sin(P) * cos(T) ; @@ -142,7 +143,7 @@ void Scene_polylines_item::create_Sphere(double R) normals_spheres.push_back(x[2]); normals_spheres.push_back(y[2]); normals_spheres.push_back(z[2]); - + //D P = (p+rings)*M_PI/180.0; T = (t+sectors)*M_PI/180.0; x[3] = sin(P) * cos(T) ; @@ -723,25 +724,82 @@ Scene_polylines_item::compute_elements() //Convert the ttriangle coordinates to lines coordinates for the //Wiremode in the spheres - for(int i=0; i< positions_spheres.size(); i+=12) + for(int i=0; i< positions_spheres.size(); i=i) { - //AB - for(int j=i; j Date: Tue, 10 Mar 2015 08:49:18 +0100 Subject: [PATCH 36/62] Some clean-up Erased some comments. --- .../Polyhedron/Scene_polygon_soup_item.cpp | 95 ++----------- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 129 ++---------------- .../demo/Polyhedron/Scene_polylines_item.cpp | 123 +++-------------- .../demo/Polyhedron/Scene_polylines_item.h | 4 + .../Scene_textured_polyhedron_item.cpp | 99 ++------------ 5 files changed, 62 insertions(+), 388 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 086c5106b15..876cacc160d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -204,62 +204,23 @@ Scene_polygon_soup_item::compile_shaders(void) "} \n" }; - //creates and compiles the vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader); - /*GLint result; - glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); - if(result == GL_TRUE){ - std::cout<<"Vertex compilation OK"<facet_begin(); HF_circulator end = he; CGAL_For_all(he,end) @@ -704,10 +619,6 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) normals.push_back(n.z()); } - - // revolve around current face to get vertices - - // If Gouraud shading: 1 normal per vertex else if (cur_shading == GL_SMOOTH) { @@ -727,7 +638,6 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) positions_facets.push_back(1.0); } } - // std::cout<<"Nombre de vertices = "<edges_begin(); @@ -786,11 +688,9 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) //set the colors compute_colors(); - //Allocates a uniform location for the MVP and MV matrices + location[0] = glGetUniformLocation(rendering_program_facets, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program_facets, "mv_matrix"); - - //Allocates a uniform location for the light values location[2] = glGetUniformLocation(rendering_program_facets, "light_pos"); location[3] = glGetUniformLocation(rendering_program_facets, "light_diff"); location[4] = glGetUniformLocation(rendering_program_facets, "light_spec"); @@ -807,9 +707,8 @@ Scene_polyhedron_item::compute_colors() GLfloat colors[4]; color_lines.clear(); color_facets.clear(); + //Facets - - typedef typename Polyhedron::Traits Kernel; typedef typename Kernel::Point_3 Point; typedef typename Kernel::Vector_3 Vector; @@ -1113,16 +1012,14 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) erase_next_picked_facet_m = b; } -// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list 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 - //viewer->displayMessage(tr("TEST"),5000); glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); glUseProgram(0); glBindVertexArray(0); @@ -1131,13 +1028,10 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { + glBindVertexArray(vao[0]); - - // tells the GPU to use the program just created glUseProgram(rendering_program_lines); - uniform_attrib(viewer,1); - //draw the edges glDrawArrays(GL_LINES, 0, positions_lines.size()/4); // Clean-up @@ -1149,15 +1043,10 @@ void Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { glBindVertexArray(vao[0]); - - // tells the GPU to use the program just created - //glUseProgram(rendering_program_lines); - uniform_attrib(viewer,1); - + glUseProgram(rendering_program_lines); //draw the points - glDrawArrays(GL_POINTS, 0, positions_facets.size()/4); - + glDrawArrays(GL_POINTS, 0, positions_lines.size()/4); // Clean-up glBindVertexArray(0); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index 152aea022bf..2fa8a001200 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -38,12 +38,11 @@ struct light_info }; typedef Scene_polylines_item::K K; typedef K::Point_3 Point_3; - +//Fill the VBO with coordinates of the vertices composing a sphere void Scene_polylines_item::create_Sphere(double R) { float T, P; - int rings(18), sectors(36); float x[4],y[4],z[4]; @@ -114,7 +113,7 @@ void Scene_polylines_item::create_Sphere(double R) normals_spheres.push_back(y[0]); normals_spheres.push_back(z[0]); - //B + //B P = (p+rings)*M_PI/180.0; T = t*M_PI/180.0; x[1] = sin(P) * cos(T) ; @@ -347,6 +346,7 @@ Scene_polylines_item::initialize_buffers() glVertexAttribDivisor(3, 1); glVertexAttribDivisor(4, 1); + // Clean-up glBindVertexArray(0); @@ -422,6 +422,7 @@ Scene_polylines_item::compile_shaders() glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader); + //creates and compiles the fragment shader GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); glCompileShader(fragment_shader); @@ -431,12 +432,13 @@ Scene_polylines_item::compile_shaders() 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 + //For the lines //fill the vertex shader static const GLchar* vertex_shader_source_lines[] = { @@ -457,7 +459,6 @@ Scene_polylines_item::compile_shaders() "} \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); @@ -465,17 +466,15 @@ Scene_polylines_item::compile_shaders() 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 + + //For the wired spheres static const GLchar* vertex_shader_source_wire_sphere[] = { "#version 300 es \n" @@ -497,7 +496,6 @@ Scene_polylines_item::compile_shaders() "} \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); @@ -505,13 +503,11 @@ Scene_polylines_item::compile_shaders() 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; @@ -530,22 +526,20 @@ void Scene_polylines_item::uniform_attrib(Viewer_interface* viewer, int mode) co GLdouble d_mat[16]; viewer->camera()->getModelViewProjectionMatrix(d_mat); - //Convert the GLdoubles matrix in GLfloats + //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]); + //Program for the Flat mode if(mode ==0) { + //Decides if the light is one or both sides glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); - //fills the arraw of colors with the current color - - //Gets lighting info : //position @@ -554,24 +548,22 @@ void Scene_polylines_item::uniform_attrib(Viewer_interface* viewer, int mode) co //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); } + //For the wiremode programs else if(mode ==1) { //Lines @@ -600,6 +592,7 @@ Scene_polylines_item::compute_elements() positions_center.clear(); nbSpheres = 0; + //Fills the VBO with the lines for(std::list >::const_iterator it = polylines.begin(); it != polylines.end(); ++it){ @@ -622,6 +615,7 @@ Scene_polylines_item::compute_elements() } } + //Fills the VBO with the spheres if(d->draw_extremities) { @@ -677,6 +671,7 @@ Scene_polylines_item::compute_elements() } // At this point, 'corner_polyline_nb' gives the multiplicity of all // corners. + //Finds the centers of the spheres and their color for(iterator p_it = corner_polyline_nb.begin(), end = corner_polyline_nb.end(); @@ -722,12 +717,12 @@ Scene_polylines_item::compute_elements() } create_Sphere(d->spheres_drawn_radius); - //Convert the ttriangle coordinates to lines coordinates for the + //Convert the triangle coordinates to lines coordinates for the //Wiremode in the spheres for(int i=0; i< positions_spheres.size(); i=i) { //draw triangles - if(i< 120) + if(i< (360/sectors)*12) { //AB for(int j=i; jdraw_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); @@ -940,93 +926,28 @@ void 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){ - 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]; - ::glVertex3d(a.x(), a.y(), a.z()); - ::glVertex3d(b.x(), b.y(), b.z()); - } - } - ::glEnd(); - if(d->draw_extremities) - { - d->draw_spheres(this); - }*/ } void 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) - { - 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(); - - ::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 + glUseProgram(rendering_program_lines); glDrawArrays(GL_POINTS, 0, positions_lines.size()/4); - // Clean-up + glUseProgram(0); glBindVertexArray(0); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h index 2674877f2ee..82e962b0bd2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h @@ -109,6 +109,10 @@ private: GLuint rendering_program_lines; GLuint rendering_program_WireSpheres; GLuint nbSpheres; + //The more small they are, the more precise the Sphere will be. + // Must be a multiple of 360 and 180. + int rings; + int sectors; typedef std::map Point_to_int_map; typedef Point_to_int_map::iterator iterator; void create_Sphere(double); diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp index 38833c399a9..f8b72088261 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp @@ -174,7 +174,6 @@ void Scene_textured_polyhedron_item::compile_shaders(void) "} \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); @@ -191,26 +190,12 @@ void Scene_textured_polyhedron_item::compile_shaders(void) glAttachShader(program, fragment_shader); glLinkProgram(program); - - //Delete the shaders which are now in the memory + //Clean-up glDeleteShader(vertex_shader); rendering_program_facets = program; - GLint result; - glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); - if(result == GL_TRUE){ - std::cout<<"Vertex compilation OK"<facet_begin(); Halfedge_around_facet_circulator end = he; CGAL_For_all(he,end) @@ -398,10 +362,6 @@ Scene_textured_polyhedron_item::compute_normals_and_vertices(void) normals.push_back(n[2]); } - - // revolve around current face to get vertices - - // If Gouraud shading: 1 normal per vertex else if(cur_shading == GL_SMOOTH) { @@ -463,19 +423,18 @@ Scene_textured_polyhedron_item::compute_normals_and_vertices(void) } - //Allocates a uniform location for the MVP and MV matrices location[0] = glGetUniformLocation(rendering_program_facets, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program_facets, "mv_matrix"); - - //Allocates a uniform location for the light values 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"); - sampler_location = glGetUniformLocation(rendering_program_facets, "s_texture"); - location[7] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); location[8] = glGetUniformLocation(rendering_program_facets, "color_facets"); + + sampler_location = glGetUniformLocation(rendering_program_facets, "s_texture"); + + location[7] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); location[9] = glGetUniformLocation(rendering_program_lines, "color_lines"); } @@ -583,46 +542,19 @@ Scene_textured_polyhedron_item::toolTip() const void Scene_textured_polyhedron_item::draw(Viewer_interface* viewer) const { glBindVertexArray(vao[0]); - - // tells the GPU to use the program just created glUseProgram(rendering_program_facets); uniform_attrib(viewer,0); - //draw the polygons - // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); + //Clean-up glUseProgram(0); glBindVertexArray(0); - - /* glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGB, - texture.GetWidth(), - texture.GetHeight(), - 0, - GL_RGB, - GL_UNSIGNED_BYTE, - texture.GetData()); - glEnable(GL_TEXTURE_2D); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - poly->gl_draw_textured_triangles(true, true, 1.0); - glDisable(GL_TEXTURE_2D);*/ - - } void Scene_textured_polyhedron_item::draw_edges(Viewer_interface* viewer) const { glBindVertexArray(vao[0]); - // tells the GPU to use the program just created glUseProgram(rendering_program_lines); - uniform_attrib(viewer,1); - - //draw the edges glDrawArrays(GL_LINES, 0, positions_lines.size()/4); // Clean-up glUseProgram(0); @@ -666,10 +598,9 @@ shading_mode_changed() prev_shading = cur_shading; cur_shading = new_shading; if(prev_shading != cur_shading) - { - //Change the normals - changed(); - } + { + changed(); + } } void Scene_textured_polyhedron_item::selection_changed(bool p_is_selected) From 8c6efa6aae4754e663a3fbc8f219f1f79c1b7ea8 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 10 Mar 2015 09:10:24 +0100 Subject: [PATCH 37/62] Add changed for polylines. --- .../Polyhedron_demo_corefinement_plugin.cpp | 3 +- .../Polyhedron_demo_intersection_plugin.cpp | 1 + .../Polyhedron_demo_jet_fitting_plugin.cpp | 3 +- ...lyhedron_demo_polyhedron_slicer_plugin.cpp | 1 + ...edron_demo_polyhedron_stitching_plugin.cpp | 1 + .../Polyhedron_demo_polylines_io_plugin.cpp | 1 + .../include/CGAL/textured_polyhedron.h | 354 +++++++++--------- 7 files changed, 185 insertions(+), 179 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp index 242d113d898..dd3ba7b610f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp @@ -166,7 +166,8 @@ void Polyhedron_demo_corefinement_plugin::corefinement() new_item->setName(tr("boundary intersection")); new_item->setColor(Qt::green); new_item->setRenderingMode(Wireframe); - scene->addItem(new_item); + scene->addItem(new_item); + new_item->changed(); std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp index 79c04e5259b..4849cb83f3a 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp @@ -209,6 +209,7 @@ void Polyhedron_demo_intersection_plugin::intersection() new_item->setColor(Qt::green); new_item->setRenderingMode(Wireframe); scene->addItem(new_item); + new_item->changed(); QApplication::restoreOverrideCursor(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp index 24dbe6bb254..822f7928731 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp @@ -56,7 +56,6 @@ void Polyhedron_demo_jet_fitting_plugin::on_actionEstimateCurvature_triggered() Scene_polylines_item* max_curv = new Scene_polylines_item; max_curv->setColor(Qt::red); max_curv->setName(tr("%1 (max curvatures)").arg(poly_item->name())); - Scene_polylines_item* min_curv = new Scene_polylines_item; min_curv->setColor(Qt::green); min_curv->setName(tr("%1 (min curvatures)").arg(poly_item->name())); @@ -121,6 +120,8 @@ void Polyhedron_demo_jet_fitting_plugin::on_actionEstimateCurvature_triggered() scene->addItem(max_curv); scene->addItem(min_curv); + max_curv->changed(); + min_curv->changed(); // default cursor QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp index 4a139ee8ef3..08605bf26ea 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp @@ -309,6 +309,7 @@ void Polyhedron_demo_polyhedron_slicer_plugin::on_Generate_button_clicked() new_polylines_item->setColor(Qt::green); new_polylines_item->setRenderingMode(Wireframe); scene->addItem(new_polylines_item); + new_polylines_item->changed(); } } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp index c6b90c21a39..b724ca03104 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp @@ -131,6 +131,7 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_trigger new_item->setName(tr("Boundary of %1").arg(item->name())); new_item->setColor(Qt::red); scene->addItem(new_item); + new_item->changed(); } } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp index f6e3e36c7e7..5ff244dfe15 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp @@ -74,6 +74,7 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { item->setColor(Qt::black); item->setProperty("polylines metadata", polylines_metadata); std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl; + item->changed(); return item; } diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/textured_polyhedron.h b/Polyhedron/demo/Polyhedron/include/CGAL/textured_polyhedron.h index e78b5d39856..18021a830f8 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/textured_polyhedron.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/textured_polyhedron.h @@ -14,143 +14,143 @@ namespace CGAL template class Textured_facet : public CGAL::HalfedgeDS_face_base { - // normal - Norm m_normal; + // normal + Norm m_normal; public: - // life cycle - // no constructors to repeat, since only - // default constructor mandatory + // life cycle + // no constructors to repeat, since only + // default constructor mandatory - Textured_facet() - { - } + Textured_facet() + { + } - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } + // normal + typedef Norm Normal_3; + Normal_3& normal() { return m_normal; } + const Normal_3& normal() const { return m_normal; } }; template class Textured_halfedge : public CGAL::HalfedgeDS_halfedge_base { public: - // life cycle - Textured_halfedge() - { - } + // life cycle + Textured_halfedge() + { + } }; template class Textured_vertex : public CGAL::HalfedgeDS_vertex_base { - // normal - Norm m_normal; - double m_u; - double m_v; + // normal + Norm m_normal; + double m_u; + double m_v; public: - // life cycle - Textured_vertex() {} + // life cycle + Textured_vertex() {} - // repeat mandatory constructors - Textured_vertex(const P& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - } + // repeat mandatory constructors + Textured_vertex(const P& pt) + : CGAL::HalfedgeDS_vertex_base(pt) + { + } - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } + // normal + typedef Norm Normal_3; + Normal_3& normal() { return m_normal; } + const Normal_3& normal() const { return m_normal; } - // u,v coordinates - double& u() { return m_u; } - const double& u() const { return m_u; } - double& v() { return m_v; } - const double& v() const { return m_v; } + // u,v coordinates + double& u() { return m_u; } + const double& u() const { return m_u; } + double& v() { return m_v; } + const double& v() const { return m_v; } }; struct Textured_items : public CGAL::Polyhedron_items_3 { - // wrap vertex - template struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Textured_vertex Vertex; - }; + // wrap vertex + template struct Vertex_wrapper + { + typedef typename Traits::Point_3 Point; + typedef typename Traits::Vector_3 Normal; + typedef Textured_vertex Vertex; + }; - // wrap face - template struct Face_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Textured_facet Face; - }; + // wrap face + template struct Face_wrapper + { + typedef typename Traits::Point_3 Point; + typedef typename Traits::Vector_3 Normal; + typedef Textured_facet Face; + }; - // wrap halfedge - template struct Halfedge_wrapper - { - typedef typename Traits::Vector_3 Normal; - typedef Textured_halfedge Halfedge; - }; + // wrap halfedge + template struct Halfedge_wrapper + { + typedef typename Traits::Vector_3 Normal; + typedef Textured_halfedge Halfedge; + }; }; // compute facet normal struct Facet_normal // (functor) { - template void operator()(Facet& f) - { - typename Facet::Normal_3 sum = CGAL::NULL_VECTOR; - typename Facet::Halfedge_around_facet_circulator h = f.facet_begin(); - do + template void operator()(Facet& f) { - typename Facet::Normal_3 normal = CGAL::cross_product(h->next()->vertex()->point() - h->vertex()->point(), h->next()->next()->vertex()->point() - h->next()->vertex()->point()); - double sqnorm = normal * normal; - if (sqnorm != 0) - normal = normal / (float)std::sqrt(sqnorm); - sum = sum + normal; - } while (++h != f.facet_begin()); - float sqnorm = sum * sum; - if (sqnorm != 0.0) - f.normal() = sum / std::sqrt(sqnorm); - else - f.normal() = CGAL::NULL_VECTOR; - } + typename Facet::Normal_3 sum = CGAL::NULL_VECTOR; + typename Facet::Halfedge_around_facet_circulator h = f.facet_begin(); + do + { + typename Facet::Normal_3 normal = CGAL::cross_product(h->next()->vertex()->point() - h->vertex()->point(), h->next()->next()->vertex()->point() - h->next()->vertex()->point()); + double sqnorm = normal * normal; + if (sqnorm != 0) + normal = normal / (float)std::sqrt(sqnorm); + sum = sum + normal; + } while (++h != f.facet_begin()); + float sqnorm = sum * sum; + if (sqnorm != 0.0) + f.normal() = sum / std::sqrt(sqnorm); + else + f.normal() = CGAL::NULL_VECTOR; + } }; // compute vertex normal struct Vertex_normal // (functor) { - template void operator()(Vertex& v) - { - typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR; - typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = - v.vertex_begin(); - typename Vertex::Halfedge_around_vertex_const_circulator begin = - pHalfedge; - CGAL_For_all(pHalfedge,begin) - if(!pHalfedge->is_border()) - normal = normal + pHalfedge->facet()->normal(); - float sqnorm = normal * normal; - if (sqnorm != 0.0f) - v.normal() = normal / (float)std::sqrt(sqnorm); - else - v.normal() = CGAL::NULL_VECTOR; - } + template void operator()(Vertex& v) + { + typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR; + typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = + v.vertex_begin(); + typename Vertex::Halfedge_around_vertex_const_circulator begin = + pHalfedge; + CGAL_For_all(pHalfedge,begin) + if(!pHalfedge->is_border()) + normal = normal + pHalfedge->facet()->normal(); + float sqnorm = normal * normal; + if (sqnorm != 0.0f) + v.normal() = normal / (float)std::sqrt(sqnorm); + else + v.normal() = CGAL::NULL_VECTOR; + } }; //********************************************************* @@ -158,93 +158,93 @@ template class Textured_polyhedron : public CGAL::Polyhedron_3 { public : - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - typedef typename CGAL::Polyhedron_3 Base; - typedef typename CGAL::Polyhedron_3 Basic_polyhedron; + typedef typename Kernel::FT FT; + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename CGAL::Polyhedron_3 Base; + typedef typename CGAL::Polyhedron_3 Basic_polyhedron; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Vertex_iterator Vertex_iterator; - typedef typename Base::Halfedge_handle Halfedge_handle; - typedef typename Base::Halfedge_iterator Halfedge_iterator; - typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; - typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Base::Edge_iterator Edge_iterator; - typedef typename Base::Facet Facet; - typedef typename Base::Facet_iterator Facet_iterator; - typedef typename Base::Facet_handle Facet_handle; + typedef typename Base::Vertex_handle Vertex_handle; + typedef typename Base::Vertex_iterator Vertex_iterator; + typedef typename Base::Halfedge_handle Halfedge_handle; + typedef typename Base::Halfedge_iterator Halfedge_iterator; + typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; + typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; + typedef typename Base::Edge_iterator Edge_iterator; + typedef typename Base::Facet Facet; + typedef typename Base::Facet_iterator Facet_iterator; + typedef typename Base::Facet_handle Facet_handle; public : - // life cycle - Textured_polyhedron() - { - } - - virtual ~Textured_polyhedron() - { - } - - // normals (per facet, then per vertex) - void compute_normals_per_facet() - { - std::for_each(this->facets_begin(),this->facets_end(),Facet_normal()); - } - void compute_normals_per_vertex() - { - std::for_each(this->vertices_begin(),this->vertices_end(),Vertex_normal()); - } - void compute_normals() - { - compute_normals_per_facet(); - compute_normals_per_vertex(); - } - - void gl_draw_textured_triangles(bool smooth_shading, - bool use_normals, - const double scaling_tex_coordinates) - { - ::glBegin(GL_TRIANGLES); - Facet_iterator f = this->facets_begin(); - for(;f!= this->facets_end();f++) - gl_draw_textured_facet(f,smooth_shading,use_normals,scaling_tex_coordinates); - ::glEnd(); - } - - void gl_draw_textured_facet(Facet_handle f, - bool smooth_shading, - bool use_normals, - const double scaling_tex_coordinates) - { - // one normal per face - if(use_normals && !smooth_shading) + // life cycle + Textured_polyhedron() { - const typename Facet::Normal_3& n = f->normal(); - ::glNormal3f(n[0],n[1],n[2]); } - // revolve around current face to get vertices - Halfedge_around_facet_circulator he = f->facet_begin(); - do + virtual ~Textured_polyhedron() { - // one normal per vertex - if(use_normals && smooth_shading) - { - const typename Facet::Normal_3& n = he->vertex()->normal(); - ::glNormal3d(n[0],n[1],n[2]); - } - - // polygon assembly is performed per vertex - const Point& p = he->vertex()->point(); - const double u = he->vertex()->u(); - const double v = he->vertex()->v(); - // std::cout << u << " " << v << std::endl; - ::glTexCoord2d(u * scaling_tex_coordinates, v * scaling_tex_coordinates); - ::glVertex3d(p[0],p[1],p[2]); } - while(++he != f->facet_begin()); - } + + // normals (per facet, then per vertex) + void compute_normals_per_facet() + { + std::for_each(this->facets_begin(),this->facets_end(),Facet_normal()); + } + void compute_normals_per_vertex() + { + std::for_each(this->vertices_begin(),this->vertices_end(),Vertex_normal()); + } + void compute_normals() + { + compute_normals_per_facet(); + compute_normals_per_vertex(); + } + + void gl_draw_textured_triangles(bool smooth_shading, + bool use_normals, + const double scaling_tex_coordinates) + { + ::glBegin(GL_TRIANGLES); + Facet_iterator f = this->facets_begin(); + for(;f!= this->facets_end();f++) + gl_draw_textured_facet(f,smooth_shading,use_normals,scaling_tex_coordinates); + ::glEnd(); + } + + void gl_draw_textured_facet(Facet_handle f, + bool smooth_shading, + bool use_normals, + const double scaling_tex_coordinates) + { + // one normal per face + if(use_normals && !smooth_shading) + { + const typename Facet::Normal_3& n = f->normal(); + ::glNormal3f(n[0],n[1],n[2]); + } + + // revolve around current face to get vertices + Halfedge_around_facet_circulator he = f->facet_begin(); + do + { + // one normal per vertex + if(use_normals && smooth_shading) + { + const typename Facet::Normal_3& n = he->vertex()->normal(); + ::glNormal3d(n[0],n[1],n[2]); + } + + // polygon assembly is performed per vertex + const Point& p = he->vertex()->point(); + const double u = he->vertex()->u(); + const double v = he->vertex()->v(); + // std::cout << u << " " << v << std::endl; + ::glTexCoord2d(u * scaling_tex_coordinates, v * scaling_tex_coordinates); + ::glVertex3d(p[0],p[1],p[2]); + } + while(++he != f->facet_begin()); + } }; // end class Textured_polyhedron } // end namespace CGAL From a09fda551ac7c95aa6c55881254f7c744f638939 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 10 Mar 2015 11:37:24 +0100 Subject: [PATCH 38/62] Forgot the destructor. --- Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp | 5 +++++ .../demo/Polyhedron/Scene_textured_polyhedron_item.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index 2fa8a001200..063a92dd52d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -831,6 +831,11 @@ Scene_polylines_item::Scene_polylines_item() Scene_polylines_item::~Scene_polylines_item() { delete d; + glDeleteBuffers(6, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_spheres); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_WireSpheres); } bool diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp index f8b72088261..a8aac2fd7c2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp @@ -494,6 +494,10 @@ Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Textured_po Scene_textured_polyhedron_item::~Scene_textured_polyhedron_item() { + glDeleteBuffers(5, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_facets); delete poly; } From 61ebf2f25a98fbb085a90513febcb31921c189a0 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 11 Mar 2015 16:59:31 +0100 Subject: [PATCH 39/62] Upgrade and use of a texture Upgraded to OGL ES 3 and draw the slice in a texture instead of drawing it directly. --- .../Scene_implicit_function_item.cpp | 1007 ++++++++++++++--- .../Polyhedron/Scene_implicit_function_item.h | 53 +- 2 files changed, 869 insertions(+), 191 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp index 83557e29feb..a7ce9a88388 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp @@ -3,7 +3,6 @@ #include #include #include - #include #include @@ -11,89 +10,677 @@ #include #include + inline bool is_nan(double d) { - return !CGAL::Is_valid()( d ); + return !CGAL::Is_valid()( d ); +} + +void Scene_implicit_function_item::initialize_buffers() +{ + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_tex_quad.size())*sizeof(float), + positions_tex_quad.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_cube.size())*sizeof(float), + positions_cube.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, + (texture_map.size())*sizeof(float), + texture_map.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 2, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glBufferData(GL_ARRAY_BUFFER, + (positions_grid.size())*sizeof(float), + positions_grid.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 4, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGB, + texture->getWidth(), + texture->getHeight(), + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + texture->getData()); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Clean-up + glBindVertexArray(0); +} + +void Scene_implicit_function_item::compile_shaders(void) +{ + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec4 positions_tex_quad; \n" + "layout (location = 2) in vec2 v_texCoord; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform mat4 m_matrix; \n" + + "out highp vec2 f_texCoord; \n" + " \n" + "void main(void) \n" + "{ \n" + " f_texCoord = v_texCoord; \n" + " gl_Position = mvp_matrix *m_matrix * positions_tex_quad; \n" + "} \n" + }; + //fill the fragment shader + static const GLchar* fragment_shader_source[]= + { + "#version 300 es \n" + " \n" + "in highp vec2 f_texCoord; \n" + "uniform sampler2D s_texture; \n" + "out highp vec4 color; \n" + " \n" + "void main(void) \n" + "{ \n" + " color = texture2D(s_texture, f_texCoord); \n" + "} \n" + }; + + 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); + GLint result; + glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); + if(result == GL_TRUE){ + std::cout<<"Vertex compilation OK"<camera()->getModelViewProjectionMatrix(d_mat); + //Convert the GLdoubles matrices in GLfloats + for (int i=0; i<16; ++i){ + mvp_mat[i] = GLfloat(d_mat[i]); + } + + for (int i=0; i<16; ++i){ + m_mat[i] = GLfloat(frame_->matrix()[i]); + } + if(mode ==0) + { + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[2], 1, GL_FALSE, m_mat); + glUniform1i(sampler_location, 0); + + } + else if(mode ==1) + { + + glUniformMatrix4fv(location[1], 1, GL_FALSE, mvp_mat); + + } + else if (mode ==2) + { + glUniformMatrix4fv(location[3], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[4], 1, GL_FALSE, m_mat); + } + +} +void Scene_implicit_function_item::compute_vertices_and_texmap(void) +{ + positions_tex_quad.clear(); + positions_cube.clear(); + positions_grid.clear(); + texture_map.clear(); + + const Bbox& b = bbox(); + float x,y,z; + z = 0; + x = (b.xmax-b.xmin)/10.0; + y = (b.ymax-b.ymin)/10.0; + // The Quad + { + + + //A + positions_tex_quad.push_back(b.xmin); + positions_tex_quad.push_back(b.ymin); + positions_tex_quad.push_back(z); + positions_tex_quad.push_back(1.0); + + //B + positions_tex_quad.push_back(b.xmin); + positions_tex_quad.push_back(b.ymax); + positions_tex_quad.push_back(z); + positions_tex_quad.push_back(1.0); + + //C + positions_tex_quad.push_back(b.xmax); + positions_tex_quad.push_back(b.ymin); + positions_tex_quad.push_back(z); + positions_tex_quad.push_back(1.0); + + + //C + positions_tex_quad.push_back(b.xmax); + positions_tex_quad.push_back(b.ymin); + positions_tex_quad.push_back(z); + positions_tex_quad.push_back(1.0); + + //B + positions_tex_quad.push_back(b.xmin); + positions_tex_quad.push_back(b.ymax); + positions_tex_quad.push_back(z); + positions_tex_quad.push_back(1.0); + + //D + positions_tex_quad.push_back(b.xmax); + positions_tex_quad.push_back(b.ymax); + positions_tex_quad.push_back(z); + positions_tex_quad.push_back(1.0); + + //UV Mapping x2 but I don't know why. + texture_map.push_back(0.0); + texture_map.push_back(1.0); + + texture_map.push_back(0.0); + texture_map.push_back(0.0); + + texture_map.push_back(1.0); + texture_map.push_back(1.0); + + texture_map.push_back(1.0); + texture_map.push_back(1.0); + + texture_map.push_back(0.0); + texture_map.push_back(0.0); + + texture_map.push_back(1.0); + texture_map.push_back(0.0); + + texture_map.push_back(0.0); + texture_map.push_back(1.0); + + texture_map.push_back(0.0); + texture_map.push_back(0.0); + + texture_map.push_back(1.0); + texture_map.push_back(1.0); + + texture_map.push_back(1.0); + texture_map.push_back(1.0); + + texture_map.push_back(0.0); + texture_map.push_back(0.0); + + texture_map.push_back(1.0); + texture_map.push_back(0.0); + } + //The grid + { + + for(int u = 0; u < 11; u++) + { + + positions_grid.push_back(b.xmin + x* u); + positions_grid.push_back(b.ymin); + positions_grid.push_back(z); + positions_grid.push_back(1.0); + + positions_grid.push_back(b.xmin + x* u); + positions_grid.push_back(b.ymax); + positions_grid.push_back(z); + positions_grid.push_back(1.0); + } + for(int v=0; v<11; v++) + { + + positions_grid.push_back(b.xmin); + positions_grid.push_back(b.ymin + v * y); + positions_grid.push_back(z); + positions_grid.push_back(1.0); + + positions_grid.push_back(b.xmax); + positions_grid.push_back(b.ymin + v * y); + positions_grid.push_back(z); + positions_grid.push_back(1.0); + } + + } + //the Box + { + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmin); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmin); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymax); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + + positions_cube.push_back(b.xmax); + positions_cube.push_back(b.ymin); + positions_cube.push_back(b.zmax); + positions_cube.push_back(1.0); + } + + //The texture + for( int i=0 ; i < texture->getWidth() ; i++ ) + { + for( int j=0 ; j < texture->getHeight() ; j++) + { + compute_texture(i,j); + } + } + + location[0] = glGetUniformLocation(rendering_program_tex_quad, "mvp_matrix"); + location[2] = glGetUniformLocation(rendering_program_tex_quad, "m_matrix"); + + sampler_location = glGetUniformLocation(rendering_program_tex_quad, "s_texture"); + + location[1] = glGetUniformLocation(rendering_program_cube, "mvp_matrix"); + location[3] = glGetUniformLocation(rendering_program_grid, "mvp_matrix"); + location[4] = glGetUniformLocation(rendering_program_grid, "m_matrix"); + } Scene_implicit_function_item:: Scene_implicit_function_item(Implicit_function_interface* f) - : function_(f) - , frame_(new ManipulatedFrame()) - , need_update_(true) - , grid_size_(SCENE_IMPLICIT_GRID_SIZE) - , max_value_(0.) - , min_value_(0.) - , blue_color_ramp_() - , red_color_ramp_() + : function_(f) + , frame_(new ManipulatedFrame()) + , need_update_(true) + , grid_size_(SCENE_IMPLICIT_GRID_SIZE) + , max_value_(0.) + , min_value_(0.) + , blue_color_ramp_() + , red_color_ramp_() + , positions_cube(0) + , positions_grid(0) + , positions_tex_quad(0) + , texture_map(0) + { - blue_color_ramp_.build_blue(); - red_color_ramp_.build_red(); - compute_min_max(); - compute_function_grid(); - double offset_x = (bbox().xmin + bbox().xmax) / 2; - double offset_y = (bbox().ymin + bbox().ymax) / 2; - double offset_z = (bbox().zmin + bbox().zmax) / 2; - frame_->setPosition(offset_x, offset_y, offset_z); - frame_->setOrientation(1., 0, 0, 0); - connect(frame_, SIGNAL(modified()), this, SLOT(plane_was_moved())); + texture = new Texture(grid_size_-1,grid_size_-1); + blue_color_ramp_.build_blue(); + red_color_ramp_.build_red(); + glGenVertexArrays(1, &vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(4, buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &textureId); + compile_shaders(); + compute_min_max(); + compute_function_grid(); + double offset_x = (bbox().xmin + bbox().xmax) / 2; + double offset_y = (bbox().ymin + bbox().ymax) / 2; + double offset_z = (bbox().zmin + bbox().zmax) / 2; + frame_->setPosition(offset_x, offset_y, offset_z); + frame_->setOrientation(1., 0, 0, 0); + connect(frame_, SIGNAL(modified()), this, SLOT(plane_was_moved())); + + changed(); } Scene_implicit_function_item::~Scene_implicit_function_item() { - delete frame_; + glDeleteBuffers(4, buffer); + glDeleteVertexArrays(1, &vao); + glDeleteProgram(rendering_program_tex_quad); + glDeleteProgram(rendering_program_cube); + glDeleteProgram(rendering_program_grid); + delete frame_; + } Scene_implicit_function_item::Bbox Scene_implicit_function_item::bbox() const { - return function_->bbox(); + return function_->bbox(); } void Scene_implicit_function_item::draw(Viewer_interface* viewer) const { - draw_aux(viewer, false); + + //draw_aux(viewer, false); + glBindVertexArray(vao); + glUseProgram(rendering_program_tex_quad); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureId); + uniform_attrib(viewer,0); + glDrawArrays(GL_TRIANGLES, 0, positions_tex_quad.size()/4); + + + + // Clean-up + glUseProgram(0); + glBindVertexArray(0); + } void Scene_implicit_function_item::draw_edges(Viewer_interface* viewer) const { - draw_aux(viewer, true); + // draw_aux(viewer, true); + glBindVertexArray(vao); + glUseProgram(rendering_program_cube); + uniform_attrib(viewer,1); + glDrawArrays(GL_LINES, 0, positions_cube.size()/4); + + glUseProgram(rendering_program_grid); + uniform_attrib(viewer,2); + glDrawArrays(GL_LINES, 0, positions_grid.size()/4); + + // Clean-up + glUseProgram(0); + glBindVertexArray(0); } void Scene_implicit_function_item::draw_aux(Viewer_interface* viewer, bool edges) const { - if(edges) { - draw_bbox(); - ::glPushMatrix(); - ::glMultMatrixd(frame_->matrix()); - QGLViewer::drawGrid((float)bbox().diagonal_length() * 0.3); - ::glPopMatrix(); - } + if(edges) { + draw_bbox(); + ::glPushMatrix(); + ::glMultMatrixd(frame_->matrix()); + QGLViewer::drawGrid((float)bbox().diagonal_length() * 0.3); + ::glPopMatrix(); + } - if(!frame_->isManipulated()) { - if(need_update_) { - compute_function_grid(); - need_update_ = false; + if(!frame_->isManipulated()) { + if(need_update_) { + compute_function_grid(); + need_update_ = false; + } + if(!viewer->inFastDrawing()) { + if(edges) + Scene_item_with_display_list::draw_edges(viewer); + else + Scene_item_with_display_list::draw(viewer); + } } - if(!viewer->inFastDrawing()) { - if(edges) - Scene_item_with_display_list::draw_edges(viewer); - else - Scene_item_with_display_list::draw(viewer); - } - } } void -Scene_implicit_function_item::direct_draw() const +Scene_implicit_function_item::direct_draw(Viewer_interface* viewer) const { - draw_function_grid(red_color_ramp_, blue_color_ramp_); + // draw_function_grid(red_color_ramp_, blue_color_ramp_); + } @@ -101,79 +688,102 @@ Scene_implicit_function_item::direct_draw() const QString Scene_implicit_function_item::toolTip() const { - return tr("

Function %1") - .arg(this->name()); + return tr("

Function %1") + .arg(this->name()); } bool Scene_implicit_function_item::supportsRenderingMode(RenderingMode m) const { - switch ( m ) - { + switch ( m ) + { case Splatting: case Gouraud: - return false; - + return false; + case Points: case Wireframe: case Flat: case FlatPlusEdges: - return true; - + return true; + default: - return false; - } - - return false; + return false; + } + + return false; } void Scene_implicit_function_item:: draw_bbox() const { - const Bbox& b = bbox(); + const Bbox& b = bbox(); - ::glDisable(GL_LIGHTING); - ::glColor3f(0.f,0.f,0.f); - ::glBegin(GL_LINES); - - ::glVertex3d(b.xmin,b.ymin,b.zmin); - ::glVertex3d(b.xmin,b.ymin,b.zmax); - - ::glVertex3d(b.xmin,b.ymin,b.zmin); - ::glVertex3d(b.xmin,b.ymax,b.zmin); - - ::glVertex3d(b.xmin,b.ymin,b.zmin); - ::glVertex3d(b.xmax,b.ymin,b.zmin); - - ::glVertex3d(b.xmax,b.ymin,b.zmin); - ::glVertex3d(b.xmax,b.ymax,b.zmin); - - ::glVertex3d(b.xmax,b.ymin,b.zmin); - ::glVertex3d(b.xmax,b.ymin,b.zmax); - - ::glVertex3d(b.xmin,b.ymax,b.zmin); - ::glVertex3d(b.xmin,b.ymax,b.zmax); - - ::glVertex3d(b.xmin,b.ymax,b.zmin); - ::glVertex3d(b.xmax,b.ymax,b.zmin); - - ::glVertex3d(b.xmax,b.ymax,b.zmin); - ::glVertex3d(b.xmax,b.ymax,b.zmax); - - ::glVertex3d(b.xmin,b.ymin,b.zmax); - ::glVertex3d(b.xmin,b.ymax,b.zmax); - - ::glVertex3d(b.xmin,b.ymin,b.zmax); - ::glVertex3d(b.xmax,b.ymin,b.zmax); - - ::glVertex3d(b.xmax,b.ymax,b.zmax); - ::glVertex3d(b.xmin,b.ymax,b.zmax); - - ::glVertex3d(b.xmax,b.ymax,b.zmax); - ::glVertex3d(b.xmax,b.ymin,b.zmax); - - ::glEnd(); + ::glDisable(GL_LIGHTING); + ::glColor3f(0.f,0.f,0.f); + ::glBegin(GL_LINES); + + ::glVertex3d(b.xmin,b.ymin,b.zmin); + ::glVertex3d(b.xmin,b.ymin,b.zmax); + + ::glVertex3d(b.xmin,b.ymin,b.zmin); + ::glVertex3d(b.xmin,b.ymax,b.zmin); + + ::glVertex3d(b.xmin,b.ymin,b.zmin); + ::glVertex3d(b.xmax,b.ymin,b.zmin); + + ::glVertex3d(b.xmax,b.ymin,b.zmin); + ::glVertex3d(b.xmax,b.ymax,b.zmin); + + ::glVertex3d(b.xmax,b.ymin,b.zmin); + ::glVertex3d(b.xmax,b.ymin,b.zmax); + + ::glVertex3d(b.xmin,b.ymax,b.zmin); + ::glVertex3d(b.xmin,b.ymax,b.zmax); + + ::glVertex3d(b.xmin,b.ymax,b.zmin); + ::glVertex3d(b.xmax,b.ymax,b.zmin); + + ::glVertex3d(b.xmax,b.ymax,b.zmin); + ::glVertex3d(b.xmax,b.ymax,b.zmax); + + ::glVertex3d(b.xmin,b.ymin,b.zmax); + ::glVertex3d(b.xmin,b.ymax,b.zmax); + + ::glVertex3d(b.xmin,b.ymin,b.zmax); + ::glVertex3d(b.xmax,b.ymin,b.zmax); + + ::glVertex3d(b.xmax,b.ymax,b.zmax); + ::glVertex3d(b.xmin,b.ymax,b.zmax); + + ::glVertex3d(b.xmax,b.ymax,b.zmax); + ::glVertex3d(b.xmax,b.ymin,b.zmax); + + ::glEnd(); +} + +void Scene_implicit_function_item::compute_texture(int i, int j) +{ + const Point& p = (implicit_grid_[i][j]).first; + double v = (implicit_grid_[i][j]).second; + + if(is_nan(v)) { + texture->setData(i,j,0.2,0.2,0.2); + } else + // determines grey level + if ( v > 0 ) + { + v = v/max_value_; + GLdouble r = red_color_ramp_.r(v), g = red_color_ramp_.g(v), b = red_color_ramp_.b(v); + texture->setData(i,j,255*r,255*g,255*b); + } + else + { + v = v/min_value_; + GLdouble r = blue_color_ramp_.r(v), g = blue_color_ramp_.g(v), b = blue_color_ramp_.b(v); + texture->setData(i,j,255*r,255*g,255*b); + } } void @@ -181,22 +791,22 @@ Scene_implicit_function_item:: draw_function_grid(const Color_ramp& ramp_pos, const Color_ramp& ramp_neg) const { - ::glDisable(GL_LIGHTING); - ::glShadeModel(GL_SMOOTH); - - ::glBegin(GL_QUADS); - const int nb_quads = grid_size_ - 1; - for( int i=0 ; i < nb_quads ; i++ ) - { - for( int j=0 ; j < nb_quads ; j++) + ::glDisable(GL_LIGHTING); + ::glShadeModel(GL_SMOOTH); + + ::glBegin(GL_QUADS); + const int nb_quads = grid_size_ - 1; + for( int i=0 ; i < nb_quads ; i++ ) { - draw_grid_vertex(implicit_grid_[i][j], ramp_pos, ramp_neg); - draw_grid_vertex(implicit_grid_[i][j+1], ramp_pos, ramp_neg); - draw_grid_vertex(implicit_grid_[i+1][j+1], ramp_pos, ramp_neg); - draw_grid_vertex(implicit_grid_[i+1][j], ramp_pos, ramp_neg); + for( int j=0 ; j < nb_quads ; j++) + { + draw_grid_vertex(implicit_grid_[i][j], ramp_pos, ramp_neg); + draw_grid_vertex(implicit_grid_[i][j+1], ramp_pos, ramp_neg); + draw_grid_vertex(implicit_grid_[i+1][j+1], ramp_pos, ramp_neg); + draw_grid_vertex(implicit_grid_[i+1][j], ramp_pos, ramp_neg); + } } - } - ::glEnd(); + ::glEnd(); } @@ -206,25 +816,27 @@ draw_grid_vertex(const Point_value& pv, const Color_ramp& ramp_positive, const Color_ramp& ramp_negative) const { - const Point& p = pv.first; - double v = pv.second; + const Point& p = pv.first; + double v = pv.second; + + if(is_nan(v)) { + ::glColor3f(0.2f, 0.2f, 0.2f); + } else + // determines grey level + if ( v > 0 ) + { + v = v/max_value_; + ::glColor3d(ramp_positive.r(v),ramp_positive.g(v),ramp_positive.b(v)); + } + else + { + v = v/min_value_; + ::glColor3d(ramp_negative.r(v),ramp_negative.g(v),ramp_negative.b(v)); + } + + ::glVertex3d(p.x,p.y,p.z); + - if(is_nan(v)) { - ::glColor3f(0.2f, 0.2f, 0.2f); - } else - // determines grey level - if ( v > 0 ) - { - v = v/max_value_; - ::glColor3d(ramp_positive.r(v),ramp_positive.g(v),ramp_positive.b(v)); - } - else - { - v = v/min_value_; - ::glColor3d(ramp_negative.r(v),ramp_negative.g(v),ramp_negative.b(v)); - } - - ::glVertex3d(p.x,p.y,p.z); } @@ -232,78 +844,97 @@ void Scene_implicit_function_item:: compute_function_grid() const { - typedef CGAL::Simple_cartesian K; - typedef K::Aff_transformation_3 Aff_transformation; - typedef K::Point_3 Point_3; - - // Get transformation - const ::GLdouble* m = frame_->matrix(); - - // OpenGL matrices are row-major matrices - Aff_transformation t (m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14]); - - double diag = bbox().diagonal_length() * .6; - - const double dx = diag; - const double dy = diag; - const double z (0); + typedef CGAL::Simple_cartesian K; + typedef K::Aff_transformation_3 Aff_transformation; + typedef K::Point_3 Point_3; - int nb_quad = grid_size_ - 1; - - for(int i=0 ; imatrix(); + + // OpenGL matrices are row-major matrices + Aff_transformation t (m[0], m[4], m[8], m[12], + m[1], m[5], m[9], m[13], + m[2], m[6], m[10], m[14]); + + double diag = bbox().diagonal_length() * .6; + + const double dx = diag; + const double dy = diag; + const double z (0); + + int nb_quad = grid_size_ - 1; + + for(int i=0 ; ioperator()(query.x(), query.y(), query.z()); - - implicit_grid_[i][j] = Point_value(Point(query.x(),query.y(),query.z()),v); + double x = -diag/2. + double(i)/double(nb_quad) * dx; + + for(int j=0 ; joperator()(query.x(), query.y(), query.z()); + + implicit_grid_[i][j] = Point_value(Point(query.x(),query.y(),query.z()),v); + } } - } - - // Update display list - const_cast(this)->changed(); + + // Update display list + const_cast(this)->changed(); + } void Scene_implicit_function_item:: compute_min_max() { - if(function_->get_min_max(min_value_, max_value_)) - return; + if(function_->get_min_max(min_value_, max_value_)) + return; - double probes_nb = double(grid_size_) / 2; - - // Probe bounding box - const Bbox& b = bbox(); - - for ( int i = 0 ; i <= probes_nb ; ++i ) - { - double x = b.xmin + double(i) * (b.xmax - b.xmin) / probes_nb; - - for ( int j = 0 ; j <= probes_nb ; ++j ) + double probes_nb = double(grid_size_) / 2; + + // Probe bounding box + const Bbox& b = bbox(); + + for ( int i = 0 ; i <= probes_nb ; ++i ) { - double y = b.ymin + double(j) * (b.ymax - b.ymin) / probes_nb; - - for ( int k = 0 ; k <= probes_nb ; ++k ) - { - double z = b.zmin + double(k) * (b.zmax - b.zmin) / probes_nb; - - double v = (*function_)(x,y,z); - if(is_nan(v)) continue; - max_value_ = (std::max)(v,max_value_); - min_value_ = (std::min)(v,min_value_); - } + double x = b.xmin + double(i) * (b.xmax - b.xmin) / probes_nb; + + for ( int j = 0 ; j <= probes_nb ; ++j ) + { + double y = b.ymin + double(j) * (b.ymax - b.ymin) / probes_nb; + + for ( int k = 0 ; k <= probes_nb ; ++k ) + { + double z = b.zmin + double(k) * (b.zmax - b.zmin) / probes_nb; + + double v = (*function_)(x,y,z); + if(is_nan(v)) continue; + max_value_ = (std::max)(v,max_value_); + min_value_ = (std::min)(v,min_value_); + } + } } - } } +void +Scene_implicit_function_item::changed() +{ + Scene_item_with_display_list::changed(); + compute_vertices_and_texmap(); + initialize_buffers(); +} + +void Scene_implicit_function_item::shading_mode_changed() +{ + if(!frame_->isManipulated()) { + if(need_update_) { + compute_function_grid(); + compute_vertices_and_texmap(); + need_update_ = false; + } + } +} #include "Scene_implicit_function_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h index 2999d6f8a54..ea09295dd6b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h @@ -6,7 +6,6 @@ #include "Scene_implicit_function_item_config.h" #include "implicit_functions/Implicit_function_interface.h" #include "Color_ramp.h" - #include #include @@ -14,7 +13,30 @@ class Viewer_interface; +class Texture{ +private: + int Width; + int Height; + int size; + GLubyte *data; +public: + Texture(int w, int h) + { + Width = w; + Height = h; + size = 3*Height*Width; + data = new GLubyte[size]; + } + int getWidth() const {return Width;} + int getHeight() const {return Height;} + int getSize() const {return size;} + void setData(int i, int j, int r, int g, int b){ + data[j*Width*3 +i*3] = r; + data[j*Width*3 +i*3+1] = g; + data[j*Width*3 +i*3+2] = b;} + GLubyte* getData(){return data; } +}; class SCENE_IMPLICIT_FUNCTION_ITEM_EXPORT Scene_implicit_function_item : public Scene_item_with_display_list { @@ -40,13 +62,15 @@ public: virtual ManipulatedFrame* manipulatedFrame() { return frame_; } // draw (overload only direct_draw() to use display list of base class) - virtual void direct_draw() const; + virtual void direct_draw() const{} + virtual void direct_draw(Viewer_interface*) const; // actually draw() is also overloaded to detect when the cut plane is moved virtual void draw(Viewer_interface*) const; virtual void draw_edges(Viewer_interface*) const; virtual QString toolTip() const; - + virtual void shading_mode_changed(); + virtual void changed(); public slots: void plane_was_moved() { need_update_ = true; } void compute_function_grid() const; @@ -77,6 +101,29 @@ private: Color_ramp blue_color_ramp_; Color_ramp red_color_ramp_; + + std::vector positions_cube; + std::vector positions_grid; + std::vector positions_tex_quad; + std::vector texture_map; + Texture *texture; + + + GLuint rendering_program_tex_quad; + GLuint rendering_program_cube; + GLuint rendering_program_grid; + GLuint textureId; + GLint location[5]; + GLint sampler_location; + + + GLuint vao; + GLuint buffer[4]; + void initialize_buffers(); + void compile_shaders(void); + void uniform_attrib(Viewer_interface*, int) const; + void compute_vertices_and_texmap(void); + void compute_texture(int, int); }; #endif // SCENE_IMPLICIT_FUNCTION_ITEM From 0d5d776f536318f38865537c81c191ab7258b8bb Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 12 Mar 2015 10:10:31 +0100 Subject: [PATCH 40/62] Change of name I renamed shading_mode_changed to contextual_changed, as I use the function in implicit_function for a different test. --- Polyhedron/demo/Polyhedron/Scene.cpp | 2 +- Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp | 2 +- Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h | 2 +- Polyhedron/demo/Polyhedron/Scene_item.cpp | 3 --- Polyhedron/demo/Polyhedron/Scene_item.h | 2 +- Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h | 1 - Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp | 2 +- Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h | 2 +- Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp | 2 +- Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h | 2 +- 10 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 02477b847bc..39b5befcb1c 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -304,7 +304,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) else ::glShadeModel(GL_FLAT); - item.shading_mode_changed(); + item.contextual_changed(); if(CGAL::check_gl_error(__FILE__, __LINE__)) { std::cerr << "GL error was before the drawing of the item \"" << qPrintable(item.name()) << "\"\n" diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp index a7ce9a88388..a984f58fbc2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp @@ -925,7 +925,7 @@ Scene_implicit_function_item::changed() initialize_buffers(); } -void Scene_implicit_function_item::shading_mode_changed() +void Scene_implicit_function_item::contextual_changed() { if(!frame_->isManipulated()) { if(need_update_) { diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h index ea09295dd6b..f6a81d76671 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h @@ -69,7 +69,7 @@ public: virtual void draw_edges(Viewer_interface*) const; virtual QString toolTip() const; - virtual void shading_mode_changed(); + virtual void contextual_changed(); virtual void changed(); public slots: void plane_was_moved() { need_update_ = true; } diff --git a/Polyhedron/demo/Polyhedron/Scene_item.cpp b/Polyhedron/demo/Polyhedron/Scene_item.cpp index ae7c2b23dd2..6aba7cbc070 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_item.cpp @@ -101,10 +101,7 @@ void Scene_item::changed() { void Scene_item::selection_changed(bool) { // emit itemChanged(); } -void Scene_item::shading_mode_changed() -{ -} void Scene_item::select(double /*orig_x*/, double /*orig_y*/, diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 2ee71b01a55..5beb496ce2e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -85,7 +85,7 @@ public slots: // Call that once you have finished changing something in the item // (either the properties or internal data) virtual void changed(); - virtual void shading_mode_changed(); + virtual void contextual_changed(){} // Setters for the four basic properties virtual void setColor(QColor c) { color_ = c; } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index fcca2e0b611..146faa7abc0 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -50,7 +50,6 @@ struct Polygon_soup void fill_edges() { // Fill edges - std::cout<<"FILL_EDGES"< Date: Thu, 12 Mar 2015 10:31:55 +0100 Subject: [PATCH 41/62] Shader modifications I moved the texture drawing in the fragment shader, this way the drawing is done by pixel and not by primitive. Forgot about that before I code inimplicit_fuction where it was obvious. --- .../Scene_textured_polyhedron_item.cpp | 63 ++++++++++++++----- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp index 99cf6fc5c5e..14c193501ee 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp @@ -133,29 +133,24 @@ void Scene_textured_polyhedron_item::compile_shaders(void) "uniform vec3 light_spec; \n" "uniform vec3 light_amb; \n" "uniform vec3 color_facets; \n" - "uniform sampler2D s_texture; \n" "float spec_power = 128.0; \n" - "vec3 temp_color; \n" "out highp vec3 fColors; \n" + "out highp vec2 f_texCoord; \n" " \n" "void main(void) \n" "{ \n" - "temp_color = vec3(texture(s_texture, v_texCoord)); \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 * temp_color; \n" + " diffuse = abs(dot(N,L)) * light_diff; \n" " else \n" - " diffuse = max(dot(N,L), 0.0) * light_diff * temp_color; \n" - " vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - " fColors =color_facets * (light_amb * temp_color + diffuse + specular); \n" + " diffuse = max(dot(N,L), 0.0) * light_diff; \n" + " f_texCoord = v_texCoord; \n" + " fColors = color_facets * (light_amb + diffuse); \n" " gl_Position = mvp_matrix *positions_facets; \n" "} \n" }; @@ -165,12 +160,13 @@ void Scene_textured_polyhedron_item::compile_shaders(void) "#version 300 es \n" " \n" "in highp vec3 fColors; \n" - + "in highp vec2 f_texCoord; \n" + "uniform sampler2D s_texture; \n" "out highp vec3 color; \n" " \n" "void main(void) \n" "{ \n" - " color = fColors; \n" + " color = vec3(texture(s_texture, f_texCoord)) * fColors; \n" "} \n" }; @@ -194,7 +190,31 @@ void Scene_textured_polyhedron_item::compile_shaders(void) glDeleteShader(vertex_shader); rendering_program_facets = program; + GLint result; + glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&result); + if(result == GL_TRUE){ + std::cout<<"Vertex compilation OK"<point() ); + ROI_points.push_back(vd->point().x()); + ROI_points.push_back(vd->point().y()); + ROI_points.push_back(vd->point().z()); + ROI_color.push_back(0.0); + ROI_color.push_back(1.0); + ROI_color.push_back(0); + } + } + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) + { + if(hgb_data->frame == viewer->manipulatedFrame()) + { + // draw axis + + if(ui_widget->ActivatePivotingCheckBox->isChecked()) + { + // draw bbox + compute_bbox(hgb_data->bbox); + } + } + // draw control vertices + if(hgb_data == active_group) + { + //set color to red + control_color.push_back(1.0); + control_color.push_back(0.0); + control_color.push_back(0.0); + } + else + { + //set color to blue + control_color.push_back(0.0); + control_color.push_back(0.0); + control_color.push_back(1.0); + } + for(std::vector::const_iterator hb = hgb_data->ctrl_vertices_group.begin(); hb != hgb_data->ctrl_vertices_group.end(); ++hb) + { + control_points.push_back((*hb)->point().x()); + control_points.push_back((*hb)->point().y()); + control_points.push_back((*hb)->point().z()); + + } + } + + //The edges color + color_edges.resize(edges.size()); + for(int i =0; i< edges.size(); i++) + color_edges[i]=0.0; + + //The box color + color_bbox.resize(pos_bbox.size()); + for(int i =0; i< pos_bbox.size(); i++) + color_bbox[i]=0.0; + + for(int i =0; i< pos_bbox.size(); i+=3) + color_bbox[i]=1.0; + + //The axis + + pos_axis.resize(18); + for(int i =0; i< 18; i++) + pos_axis[i]=0.0; + pos_axis[3] = length_of_axis; pos_axis[10] = length_of_axis; pos_axis[17] = length_of_axis; + color_lines.resize(18); + for(int i =0; i< 18; i++) + color_lines[i]=0.0; + + color_lines[2] = 1.0; color_lines[5] = 1.0; + color_lines[6] = 1.0; color_lines[9] = 1.0; + color_lines[13] = 1.0; color_lines[16] = 1.0; + + 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[8] = glGetUniformLocation(rendering_program_facets, "u_color"); + + location[7] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[11] = glGetUniformLocation(rendering_program_lines, "rotations"); + location[13] = glGetUniformLocation(rendering_program_lines, "translation"); + location[14] = glGetUniformLocation(rendering_program_lines, "translation_2"); + + location[10] = glGetUniformLocation(rendering_program_points, "mvp_matrix"); + + + +} + +void Scene_edit_polyhedron_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 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); + + + //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); + + + if(mode ==0) + { + GLfloat color[3]; + color[0] = this->color().redF(); + color[1] = this->color().greenF(); + color[2] = this->color().blueF(); + + 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); + glUniform3fv(location[8], 1, color); + + } + else if(mode ==1) + { + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[7], 1, GL_FALSE, mvp_mat); + } + else if(mode ==2) + { + glUseProgram(rendering_program_points); + glUniformMatrix4fv(location[10], 1, GL_FALSE, mvp_mat); + } + +} + ///////////////////////////////////////////////////////// /////////// Most relevant functions lie here /////////// void Scene_edit_polyhedron_item::deform() { - if(!is_there_any_ctrl_vertices()) { return; } + if(!is_there_any_ctrl_vertices()) { return; } - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { it->set_target_positions(); } - deform_mesh.deform(); + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { it->set_target_positions(); } + deform_mesh.deform(); - poly_item->changed(); // now we need to call poly_item changed to delete AABB tree - emit itemChanged(); + poly_item->changed(); // now we need to call poly_item changed to delete AABB tree + emit itemChanged(); } void Scene_edit_polyhedron_item::timerEvent(QTimerEvent* /*event*/) { // just handle deformation - paint like selection is handled in eventFilter() - if(state.ctrl_pressing && (state.left_button_pressing || state.right_button_pressing)) { - if(!ui_widget->ActivatePivotingCheckBox->isChecked()) { - deform(); + if(state.ctrl_pressing && (state.left_button_pressing || state.right_button_pressing)) { + if(!ui_widget->ActivatePivotingCheckBox->isChecked()) { + deform(); + } + else { + emit itemChanged(); // for redraw while Pivoting (since we close signals of manipulatedFrames while pivoting, + // for now redraw with timer) + } } - else { - emit itemChanged(); // for redraw while Pivoting (since we close signals of manipulatedFrames while pivoting, - // for now redraw with timer) - } - } } bool Scene_edit_polyhedron_item::eventFilter(QObject* /*target*/, QEvent *event) { - // This filter is both filtering events from 'viewer' and 'main window' - Mouse_keyboard_state_deformation old_state = state; - ////////////////// TAKE EVENTS ///////////////////// - // key events - if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) - { - QKeyEvent *keyEvent = static_cast(event); - Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); + // This filter is both filtering events from 'viewer' and 'main window' + Mouse_keyboard_state_deformation old_state = state; + ////////////////// TAKE EVENTS ///////////////////// + // key events + if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) + { + QKeyEvent *keyEvent = static_cast(event); + Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); - state.ctrl_pressing = modifiers.testFlag(Qt::ControlModifier); - state.shift_pressing = modifiers.testFlag(Qt::ShiftModifier); - } - // mouse events - if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) - { - QMouseEvent* mouse_event = static_cast(event); - if(mouse_event->button() == Qt::LeftButton) { - state.left_button_pressing = event->type() == QEvent::MouseButtonPress; + state.ctrl_pressing = modifiers.testFlag(Qt::ControlModifier); + state.shift_pressing = modifiers.testFlag(Qt::ShiftModifier); } - if(mouse_event->button() == Qt::RightButton) { - state.right_button_pressing = event->type() == QEvent::MouseButtonPress; - } - } - ////////////////// //////////////// ///////////////////// + // mouse events + if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) + { + QMouseEvent* mouse_event = static_cast(event); + if(mouse_event->button() == Qt::LeftButton) { + state.left_button_pressing = event->type() == QEvent::MouseButtonPress; + } + if(mouse_event->button() == Qt::RightButton) { + state.right_button_pressing = event->type() == QEvent::MouseButtonPress; + } + } + ////////////////// //////////////// ///////////////////// - if(!poly_item->visible()) { return false; } // if not visible just update event state but don't do any action + if(!poly_item->visible()) { return false; } // if not visible just update event state but don't do any action - // check state changes between old and current state - bool ctrl_pressed_now = state.ctrl_pressing && !old_state.ctrl_pressing; - bool ctrl_released_now = !state.ctrl_pressing && old_state.ctrl_pressing; - if(ctrl_pressed_now || ctrl_released_now || event->type() == QEvent::HoverMove) - {// activate a handle manipulated frame - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); - bool need_repaint = activate_closest_manipulated_frame(p.x(), p.y()); + // check state changes between old and current state + bool ctrl_pressed_now = state.ctrl_pressing && !old_state.ctrl_pressing; + bool ctrl_released_now = !state.ctrl_pressing && old_state.ctrl_pressing; + if(ctrl_pressed_now || ctrl_released_now || event->type() == QEvent::HoverMove) + {// activate a handle manipulated frame + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); + bool need_repaint = activate_closest_manipulated_frame(p.x(), p.y()); - if(need_repaint) { emit itemChanged(); } - } + if(need_repaint) { emit itemChanged(); } + } - return false; + return false; } #include "opengl_tools.h" -void Scene_edit_polyhedron_item::draw_edges() const { +void Scene_edit_polyhedron_item::draw_edges(Viewer_interface* viewer) const { + GLfloat vec[3]; + for(int i=0; i< 3; i++) + vec[i]=0.0; + GLfloat f_matrix[16]; + for(int i=0; i<16; i++) + f_matrix[i]=0.0; + f_matrix[0]=1.0; f_matrix[5]=1.0; f_matrix[10]=1.0; f_matrix[15]=1.0; - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_DOUBLE, 0, positions.data()); - glDrawElements(GL_LINES, (GLsizei) edges.size(), GL_UNSIGNED_INT, edges.data()); - glDisableClientState(GL_VERTEX_ARRAY); + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + glUniform3fv(location[13],1,vec); + glUniform3fv(location[14],1,vec); + glUniformMatrix4fv(location[11], 1, GL_FALSE, f_matrix); + uniform_attrib(viewer,1); + glDrawElements(GL_LINES, (GLsizei) edges.size(), GL_UNSIGNED_INT, edges.data()); + glUseProgram(0); + glBindVertexArray(0); - if(rendering_mode == Wireframe) { - draw_ROI_and_control_vertices(); - } + if(rendering_mode == Wireframe) { + draw_ROI_and_control_vertices(viewer); + } } -void Scene_edit_polyhedron_item::draw() const { - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); +void Scene_edit_polyhedron_item::draw(Viewer_interface* viewer) const { - glVertexPointer(3, GL_DOUBLE, 0, positions.data()); - glNormalPointer(GL_DOUBLE, 0, normals.data()); - glDrawElements(GL_TRIANGLES, (GLsizei) tris.size(), GL_UNSIGNED_INT, tris.data()); + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_facets); + uniform_attrib(viewer,0); + glDrawElements(GL_TRIANGLES, (GLsizei) tris.size(), GL_UNSIGNED_INT, tris.data()); + glUseProgram(0); + glBindVertexArray(0); + draw_edges(viewer); + draw_ROI_and_control_vertices(viewer); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - CGAL::GL::Color color; - color.set_rgb_color(0, 0, 0); - draw_edges(); - - draw_ROI_and_control_vertices(); } -void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices() const { - GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); - glDisable(GL_LIGHTING); +void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* viewer) const { - CGAL::GL::Color color; - CGAL::GL::Point_size point_size; point_size.set_point_size(5); - color.set_rgb_color(0, 1.f, 0); - // draw ROI - if(ui_widget->ShowROICheckBox->isChecked()) { - BOOST_FOREACH(vertex_descriptor vd, deform_mesh.roi_vertices()) + GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); + (GL_LIGHTING); + + CGAL::GL::Color color; + CGAL::GL::Point_size point_size; point_size.set_point_size(5); + + color.set_rgb_color(0, 1.f, 0); + if(!ui_widget->ShowROICheckBox->isChecked()) { + + + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer,2); + glDrawArrays(GL_POINTS, 0, ROI_points.size()/3); + glUseProgram(0); + + glBindVertexArray(0); + } + + + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer,2); + glDrawArrays(GL_POINTS, 0, control_points.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + QGLViewer* viewerB = *QGLViewer::QGLViewerPool().begin(); + for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) { - if(!deform_mesh.is_control_vertex(vd)) - gl_draw_point( vd->point() ); - } - } - // draw control vertices related things - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + if(hgb_data->frame == viewerB->manipulatedFrame()) + { + //Draw the axis + GLfloat vec[3]; + for(int i=0; i< 3; i++) + vec[i]=0.0; + GLfloat f_matrix[16]; + for(int i =0; i<16; i++) + f_matrix[i] = hgb_data->frame->matrix()[i]; - for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) - { - if(hgb_data->frame == viewer->manipulatedFrame()) - { - // draw axis - ::glPushMatrix(); - ::glMultMatrixd(hgb_data->frame->matrix()); - QGLViewer::drawAxis(length_of_axis); - ::glPopMatrix(); - // draw bbox - if(!ui_widget->ActivatePivotingCheckBox->isChecked()) - { - color.set_rgb_color(1.0f, 0, 0); - ::glPushMatrix(); - ::glTranslated(hgb_data->frame->position().x, hgb_data->frame->position().y, hgb_data->frame->position().z); - ::glMultMatrixd(hgb_data->frame->orientation().matrix()); - ::glTranslated(-hgb_data->frame_initial_center.x, -hgb_data->frame_initial_center.y, -hgb_data->frame_initial_center.z); - draw_bbox(hgb_data->bbox); - ::glPopMatrix(); - } - } - // draw control vertices - if(hgb_data == active_group) { color.set_rgb_color(1.0f, 0, 0); } - else { color.set_rgb_color(0, 0, 1.0f); } - for(std::vector::const_iterator hb = hgb_data->ctrl_vertices_group.begin(); hb != hgb_data->ctrl_vertices_group.end(); ++hb) - { gl_draw_point( (*hb)->point() ); - } - } + glBindVertexArray(vao[2]); + glUseProgram(rendering_program_lines); + glUniform3fv(location[13], 1, vec); + glUniform3fv(location[14], 1, vec); + glUniformMatrix4fv(location[11], 1, GL_FALSE, f_matrix); + uniform_attrib(viewer,1); + glDrawArrays(GL_LINES, 0, pos_axis.size()/3); + glUseProgram(0); + glBindVertexArray(0); - if(enable_back_lighting) { glEnable(GL_LIGHTING); } + //QGLViewer::drawAxis(length_of_axis); + // draw bbox + if(!ui_widget->ActivatePivotingCheckBox->isChecked()) + { + GLfloat colors[3]; + GLfloat f_matrix[16]; + GLfloat trans[3]; + GLfloat trans2[3]; + colors[0]=1.0; + colors[1]=0.0; + colors[2]=0.0; + + trans[0] = hgb_data->frame->position().x; + trans[1] = hgb_data->frame->position().y; + trans[2] = hgb_data->frame->position().z; + + trans2[0] = -hgb_data->frame_initial_center.x; + trans2[1] = -hgb_data->frame_initial_center.y; + trans2[2] = -hgb_data->frame_initial_center.z; + + for(int i =0; i<16; i++) + f_matrix[i] = hgb_data->frame->orientation().matrix()[i]; + + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_lines); + glUniform3fv(location[13], 1, trans); + glUniform3fv(location[14], 1, trans2); + glUniformMatrix4fv(location[11], 1, GL_FALSE, f_matrix); + uniform_attrib(viewer,1); + glDrawArrays(GL_LINES, 0, pos_bbox.size()/3); + glUseProgram(0); + glBindVertexArray(0); + } + } + } + + /* // draw ROI + + if(ui_widget->ShowROICheckBox->isChecked()) { + BOOST_FOREACH(vertex_descriptor vd, deform_mesh.roi_vertices()) + { + if(!deform_mesh.is_control_vertex(vd)) + gl_draw_point( vd->point() ); + } + } + // draw control vertices related things + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + + for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) + { + if(hgb_data->frame == viewer->manipulatedFrame()) + { + // draw axis + ::glPushMatrix(); + ::glMultMatrixd(hgb_data->frame->matrix()); + QGLViewer::drawAxis(length_of_axis); + ::glPopMatrix(); + // draw bbox + if(!ui_widget->ActivatePivotingCheckBox->isChecked()) + { + color.set_rgb_color(1.0f, 0, 0); + ::glPushMatrix(); + ::glTranslated(hgb_data->frame->position().x, hgb_data->frame->position().y, hgb_data->frame->position().z); + ::glMultMatrixd(hgb_data->frame->orientation().matrix()); + ::glTranslated(-hgb_data->frame_initial_center.x, -hgb_data->frame_initial_center.y, -hgb_data->frame_initial_center.z); + draw_bbox(hgb_data->bbox); + ::glPopMatrix(); + } + } + // draw control vertices + if(hgb_data == active_group) { color.set_rgb_color(1.0f, 0, 0); } + else { color.set_rgb_color(0, 0, 1.0f); } + for(std::vector::const_iterator hb = hgb_data->ctrl_vertices_group.begin(); hb != hgb_data->ctrl_vertices_group.end(); ++hb) + { gl_draw_point( (*hb)->point() ); + } + } + + if(enable_back_lighting) { glEnable(GL_LIGHTING); }*/ } void Scene_edit_polyhedron_item::gl_draw_point(const Point& p) const { - if(!ui_widget->ShowAsSphereCheckBox->isChecked()) { - ::glBegin(GL_POINTS); - ::glVertex3d(p.x(), p.y(), p.z()); - ::glEnd(); - } - else { - GLint shading; - ::glGetIntegerv(GL_SHADE_MODEL, &shading); - ::glShadeModel(GL_SMOOTH); + if(!ui_widget->ShowAsSphereCheckBox->isChecked()) { + ::glBegin(GL_POINTS); + ::glVertex3d(p.x(), p.y(), p.z()); + ::glEnd(); + } + else { + GLint shading; + ::glGetIntegerv(GL_SHADE_MODEL, &shading); + ::glShadeModel(GL_SMOOTH); - ::glPushMatrix(); - ::glTranslated(p.x(), p.y(), p.z()); - ::gluSphere(quadric, length_of_axis/15, 8, 8); - ::glPopMatrix(); + ::glPushMatrix(); + ::glTranslated(p.x(), p.y(), p.z()); + ::gluSphere(quadric, length_of_axis/15, 8, 8); + ::glPopMatrix(); - ::glShadeModel(shading); - } + ::glShadeModel(shading); + } } ////////////////////////////////////////////////////////// /////////////// from trivial_plugin ////////////////////// -void Scene_edit_polyhedron_item::draw_bbox(const Scene_interface::Bbox& bb ) const { - ::glBegin(GL_LINES); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, - bb.xmax, bb.ymin, bb.zmin); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, - bb.xmin, bb.ymax, bb.zmin); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, - bb.xmin, bb.ymin, bb.zmax); - - gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, - bb.xmax, bb.ymax, bb.zmin); - gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, - bb.xmax, bb.ymin, bb.zmax); - - gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, - bb.xmax, bb.ymax, bb.zmin); - gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, - bb.xmin, bb.ymax, bb.zmax); - - gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, - bb.xmax, bb.ymin, bb.zmax); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, - bb.xmin, bb.ymax, bb.zmax); - - gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, - bb.xmin, bb.ymax, bb.zmax); - gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, - bb.xmax, bb.ymin, bb.zmax); - gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, - bb.xmax, bb.ymax, bb.zmin); - ::glEnd(); +void Scene_edit_polyhedron_item::draw_bbox(const Scene_interface::Bbox &bb)const{ + + ::glBegin(GL_LINES); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmax, bb.ymin, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmin, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmin, bb.ymin, bb.zmax); + + gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, + bb.xmax, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, + bb.xmax, bb.ymin, bb.zmax); + + gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, + bb.xmax, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, + bb.xmin, bb.ymax, bb.zmax); + + gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, + bb.xmax, bb.ymin, bb.zmax); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, + bb.xmin, bb.ymax, bb.zmax); + + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmin, bb.ymax, bb.zmax); + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmax, bb.ymin, bb.zmax); + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmax, bb.ymax, bb.zmin); + + + ::glEnd(); + } +void Scene_edit_polyhedron_item::compute_bbox(const Scene_interface::Bbox& bb){ + pos_bbox.resize(24*3); + + pos_bbox[0]=bb.xmin; pos_bbox[1]=bb.ymin; pos_bbox[2]=bb.zmin; + pos_bbox[3]=bb.xmax; pos_bbox[4]=bb.ymin; pos_bbox[5]=bb.zmin; + pos_bbox[6]=bb.xmin; pos_bbox[7]=bb.ymin; pos_bbox[8]=bb.zmin; + pos_bbox[9]=bb.xmin; pos_bbox[10]=bb.ymax; pos_bbox[11]=bb.zmin; + + pos_bbox[12]=bb.xmin; pos_bbox[13]=bb.ymin; pos_bbox[14]=bb.zmin; + pos_bbox[15]=bb.xmin; pos_bbox[16]=bb.ymin; pos_bbox[17]=bb.zmax; + pos_bbox[18]= bb.xmax; pos_bbox[19]=bb.ymin; pos_bbox[20]=bb.zmin; + pos_bbox[21]= bb.xmax; pos_bbox[22]=bb.ymax; pos_bbox[23]=bb.zmin; + + pos_bbox[24]= bb.xmax; pos_bbox[25]=bb.ymin; pos_bbox[26]=bb.zmin; + pos_bbox[27]= bb.xmax; pos_bbox[28]=bb.ymin; pos_bbox[29]=bb.zmax; + pos_bbox[30]=bb.xmin; pos_bbox[31]=bb.ymax; pos_bbox[32]=bb.zmin; + pos_bbox[33]=bb.xmax; pos_bbox[34]=bb.ymax; pos_bbox[35]=bb.zmin; + + pos_bbox[36]=bb.xmin; pos_bbox[37]=bb.ymax; pos_bbox[38]=bb.zmin; + pos_bbox[39]=bb.xmin; pos_bbox[40]=bb.ymax; pos_bbox[41]=bb.zmax; + pos_bbox[42]=bb.xmin; pos_bbox[43]=bb.ymin; pos_bbox[44]=bb.zmax; + pos_bbox[45]=bb.xmax; pos_bbox[46]=bb.ymin; pos_bbox[47]=bb.zmax; + + pos_bbox[48]=bb.xmin; pos_bbox[49]=bb.ymin; pos_bbox[50]=bb.zmax; + pos_bbox[51]=bb.xmin; pos_bbox[52]=bb.ymax; pos_bbox[53]=bb.zmax; + pos_bbox[54]=bb.xmax; pos_bbox[55]=bb.ymax; pos_bbox[56]=bb.zmax; + pos_bbox[57]=bb.xmin; pos_bbox[58]=bb.ymax; pos_bbox[59]=bb.zmax; + + pos_bbox[60]=bb.xmax; pos_bbox[61]=bb.ymax; pos_bbox[62]=bb.zmax; + pos_bbox[63]=bb.xmax; pos_bbox[64]=bb.ymin; pos_bbox[65]=bb.zmax; + pos_bbox[66]=bb.xmax; pos_bbox[67]=bb.ymax; pos_bbox[68]=bb.zmax; + pos_bbox[69]=bb.xmax; pos_bbox[70]=bb.ymax; pos_bbox[71]=bb.zmin; + +} + void Scene_edit_polyhedron_item::gl_draw_edge(double px, double py, double pz, - double qx, double qy, double qz) const + double qx, double qy, double qz) const { - ::glVertex3d(px,py,pz); - ::glVertex3d(qx,qy,qz); + ::glVertex3d(px,py,pz); + ::glVertex3d(qx,qy,qz); } ///////////////////////////////////////////////////////////// void Scene_edit_polyhedron_item::changed() -{ update_normals(); } - -Scene_polyhedron_item* Scene_edit_polyhedron_item::to_polyhedron_item() { - Scene_polyhedron_item* poly_item_tmp = poly_item; - poly_item->set_color_vector_read_only(false); - own_poly_item=false; - return poly_item_tmp; +{ + compute_normals_and_vertices(); + initialize_buffers(); + update_normals(); } -Polyhedron* Scene_edit_polyhedron_item::polyhedron() +Scene_polyhedron_item* Scene_edit_polyhedron_item::to_polyhedron_item() { + Scene_polyhedron_item* poly_item_tmp = poly_item; + poly_item->set_color_vector_read_only(false); + own_poly_item=false; + return poly_item_tmp; +} + +Polyhedron* Scene_edit_polyhedron_item::polyhedron() { return poly_item->polyhedron(); } -const Polyhedron* Scene_edit_polyhedron_item::polyhedron() const +const Polyhedron* Scene_edit_polyhedron_item::polyhedron() const { return poly_item->polyhedron(); } QString Scene_edit_polyhedron_item::toolTip() const { - if(!poly_item->polyhedron()) - return QString(); + if(!poly_item->polyhedron()) + return QString(); - return QObject::tr("

Polyhedron %1 (mode: %5, color: %6)

" - "

Number of vertices: %2
" - "Number of edges: %3
" - "Number of facets: %4

") - .arg(this->name()) - .arg(poly_item->polyhedron()->size_of_vertices()) - .arg(poly_item->polyhedron()->size_of_halfedges()/2) - .arg(poly_item->polyhedron()->size_of_facets()) - .arg(this->renderingModeName()) - .arg(this->color().name()); + return QObject::tr("

Polyhedron %1 (mode: %5, color: %6)

" + "

Number of vertices: %2
" + "Number of edges: %3
" + "Number of facets: %4

") + .arg(this->name()) + .arg(poly_item->polyhedron()->size_of_vertices()) + .arg(poly_item->polyhedron()->size_of_halfedges()/2) + .arg(poly_item->polyhedron()->size_of_facets()) + .arg(this->renderingModeName()) + .arg(this->color().name()); } bool Scene_edit_polyhedron_item::isEmpty() const { - return poly_item->isEmpty(); + return poly_item->isEmpty(); } Scene_edit_polyhedron_item::Bbox Scene_edit_polyhedron_item::bbox() const { - return poly_item->bbox(); + return poly_item->bbox(); } void Scene_edit_polyhedron_item::setVisible(bool b) { - poly_item->setVisible(b); - Scene_item::setVisible(b); - if(!b) { - (*QGLViewer::QGLViewerPool().begin())->setManipulatedFrame(NULL); - } + poly_item->setVisible(b); + Scene_item::setVisible(b); + if(!b) { + (*QGLViewer::QGLViewerPool().begin())->setManipulatedFrame(NULL); + } } void Scene_edit_polyhedron_item::setColor(QColor c) { - poly_item->setColor(c); - Scene_item::setColor(c); + poly_item->setColor(c); + Scene_item::setColor(c); } void Scene_edit_polyhedron_item::setName(QString n) { - Scene_item::setName(n); - n.replace(" (edit)", ""); - poly_item->setName(n); + Scene_item::setName(n); + n.replace(" (edit)", ""); + poly_item->setName(n); } void Scene_edit_polyhedron_item::setRenderingMode(RenderingMode m) { - poly_item->setRenderingMode(m); - Scene_item::setRenderingMode(m); + poly_item->setRenderingMode(m); + Scene_item::setRenderingMode(m); } Scene_edit_polyhedron_item* Scene_edit_polyhedron_item::clone() const { - return 0; + return 0; } void Scene_edit_polyhedron_item::select( - double orig_x, - double orig_y, - double orig_z, - double dir_x, - double dir_y, - double dir_z) + double orig_x, + double orig_y, + double orig_z, + double dir_x, + double dir_y, + double dir_z) { - Scene_item::select(orig_x, - orig_y, - orig_z, - dir_x, - dir_y, - dir_z); - poly_item->select(orig_x, + Scene_item::select(orig_x, orig_y, orig_z, dir_x, dir_y, dir_z); + poly_item->select(orig_x, + orig_y, + orig_z, + dir_x, + dir_y, + dir_z); } bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e) { - //setting/unsetting rotation constraints - if (e->key()==Qt::Key_R && !state.ctrl_pressing) - { - is_rot_free = !is_rot_free; - rot_constraint.setRotationConstraintType( is_rot_free? - qglviewer::AxisPlaneConstraint::FREE: - qglviewer::AxisPlaneConstraint::AXIS); - return true; - } - return false; + //setting/unsetting rotation constraints + if (e->key()==Qt::Key_R && !state.ctrl_pressing) + { + is_rot_free = !is_rot_free; + rot_constraint.setRotationConstraintType( is_rot_free? + qglviewer::AxisPlaneConstraint::FREE: + qglviewer::AxisPlaneConstraint::AXIS); + return true; + } + return false; } #include "Scene_edit_polyhedron_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index 4fdfc49ea4a..f00ce6900a4 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -21,6 +21,9 @@ #include "ui_Deform_mesh.h" #include #include +#include +#include +#include typedef Polyhedron::Vertex_handle Vertex_handle; @@ -195,9 +198,11 @@ public: return m == Gouraud; } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list - void draw() const; - void draw_edges() const; - void draw_bbox(const Scene_interface::Bbox& bb ) const; + void draw() const{} + void draw(Viewer_interface*) const; + void draw_edges() const{}; + void draw_edges(Viewer_interface*) const; + void draw_bbox(const Scene_interface::Bbox&) const; void gl_draw_edge(double px, double py, double pz, double qx, double qy, double qz) const; void gl_draw_point(const Point& p) const; @@ -225,7 +230,7 @@ public: protected: void timerEvent(QTimerEvent *event); - void draw_ROI_and_control_vertices() const; + void draw_ROI_and_control_vertices(Viewer_interface *viewer) const; public slots: void changed(); @@ -262,10 +267,35 @@ private: Ui::DeformMesh* ui_widget; Scene_polyhedron_item* poly_item; // For drawing - std::vector positions; + std::vector positions; std::vector tris; std::vector edges; - std::vector normals; + std::vector color_lines; + std::vector color_bbox; + std::vector color_edges; + std::vector ROI_points; + std::vector control_points; + std::vector ROI_color; + std::vector control_color; + std::vector normals; + std::vector pos_bbox; + std::vector pos_axis; + GLuint rendering_program_facets; + GLuint rendering_program_lines; + GLuint rendering_program_points; + GLint location[20]; + GLuint vao[3]; + GLuint buffer[20]; + + void initialize_buffers(); + void compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*, int) const; + void compute_bbox(const Scene_interface::Bbox&); + void drawSphere(float); + + + Deform_mesh deform_mesh; typedef std::list Ctrl_vertices_group_data_list; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 63c6c1f088c..e326e02264b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -453,9 +453,10 @@ Scene_polyhedron_item::compile_shaders(void) { "#version 300 es \n" " \n" - "in highp vec3 fColors; \n" + "precision mediump float; \n" + "in vec3 fColors; \n" - "out highp vec3 color; \n" + "out vec3 color; \n" " \n" "void main(void) \n" "{ \n" From 463c3e5b0e522bd74ef85739ad01f7af888151ed Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 16 Mar 2015 14:41:12 +0100 Subject: [PATCH 43/62] Finished The spheres are implemented, everything seems to work. --- .../Polyhedron/Scene_edit_polyhedron_item.cpp | 512 +++++++++++++++--- .../Polyhedron/Scene_edit_polyhedron_item.h | 14 +- 2 files changed, 457 insertions(+), 69 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp index d356e4c344b..fdbbd1cb169 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp @@ -32,6 +32,8 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item control_points(0), control_color(0), ROI_color(0), + pos_sphere(0), + normals_sphere(0), k_ring_selector(poly_item, mw, Scene_polyhedron_item_k_ring_selection::Active_handle::VERTEX, true), quadric(gluNewQuadric()) { @@ -90,8 +92,11 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item } glGenVertexArrays(3, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(20, buffer); + glGenBuffers(19, buffer); + compile_shaders(); + //the spheres : + create_Sphere(length_of_axis/15.0); changed(); } @@ -184,8 +189,67 @@ void Scene_edit_polyhedron_item::initialize_buffers() ); glEnableVertexAttribArray(4); + glBindBuffer(GL_ARRAY_BUFFER, buffer[11]); + glBufferData(GL_ARRAY_BUFFER, + (pos_sphere.size())*sizeof(double), + pos_sphere.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(5, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(5); + glBindBuffer(GL_ARRAY_BUFFER, buffer[13]); + glBufferData(GL_ARRAY_BUFFER, + (normals_sphere.size())*sizeof(double), + normals_sphere.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(6, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(6); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[15]); + glBufferData(GL_ARRAY_BUFFER, + (centers_ROI.size())*sizeof(double), + centers_ROI.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(7, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(7); + glVertexAttribDivisor(7, 1); + + + + glBindBuffer(GL_ARRAY_BUFFER, buffer[17]); + glBufferData(GL_ARRAY_BUFFER, + (color_sphere_ROI.size())*sizeof(double), + color_sphere_ROI.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(8, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(8); + glVertexAttribDivisor(8, 1); + // Clean-up glBindVertexArray(0); @@ -247,6 +311,64 @@ void Scene_edit_polyhedron_item::initialize_buffers() NULL ); glEnableVertexAttribArray(4); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[12]); + glBufferData(GL_ARRAY_BUFFER, + (pos_sphere.size())*sizeof(double), + pos_sphere.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(5, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(5); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[14]); + glBufferData(GL_ARRAY_BUFFER, + (normals_sphere.size())*sizeof(double), + normals_sphere.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(6, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(6); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[16]); + glBufferData(GL_ARRAY_BUFFER, + (centers_control.size())*sizeof(double), + centers_control.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(7, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(7); + glVertexAttribDivisor(7, 1); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[18]); + glBufferData(GL_ARRAY_BUFFER, + (color_sphere_control.size())*sizeof(double), + color_sphere_control.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(8, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(8); + glVertexAttribDivisor(8, 1); glBindVertexArray(0); @@ -280,11 +402,8 @@ void Scene_edit_polyhedron_item::initialize_buffers() NULL ); glEnableVertexAttribArray(4); + glBindVertexArray(0); - - - - } void Scene_edit_polyhedron_item::compile_shaders(void) @@ -405,6 +524,8 @@ void Scene_edit_polyhedron_item::compile_shaders(void) glDeleteShader(vertex_shader); rendering_program_lines = program; + + //For the points static const GLchar* vertex_shader_source_points[] = { @@ -436,11 +557,74 @@ void Scene_edit_polyhedron_item::compile_shaders(void) glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glLinkProgram(program); + //Clean-up glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); rendering_program_points = program; + //For the Spheres + static const GLchar* vertex_shader_source_sphere[] = + { + "#version 300 es \n" + " \n" + "layout (location = 5) in vec4 positions_spheres; \n" + "layout (location = 6) in vec3 vNormals; \n" + "layout (location = 8) in vec3 color_spheres; \n" + "layout (location = 7) 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" + }; + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source_sphere, 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); + //Clean-up + glDeleteShader(vertex_shader); + + glDeleteShader(fragment_shader); + rendering_program_spheres = program; + } void Scene_edit_polyhedron_item::compute_normals_and_vertices(void) @@ -454,11 +638,30 @@ void Scene_edit_polyhedron_item::compute_normals_and_vertices(void) ROI_points.push_back(vd->point().x()); ROI_points.push_back(vd->point().y()); ROI_points.push_back(vd->point().z()); - ROI_color.push_back(0.0); - ROI_color.push_back(1.0); - ROI_color.push_back(0); } } + centers_ROI.resize(ROI_points.size()); + ROI_color.resize(ROI_points.size()); + color_sphere_ROI.resize(ROI_points.size()); + for(int i=0; ipoint().z()); } + centers_control.resize(control_points.size()); + for(int i=0; iShowROICheckBox->isChecked()) { - - - glBindVertexArray(vao[0]); - glUseProgram(rendering_program_points); - uniform_attrib(viewer,2); - glDrawArrays(GL_POINTS, 0, ROI_points.size()/3); - glUseProgram(0); + if(ui_widget->ShowROICheckBox->isChecked()) { + if(!ui_widget->ShowAsSphereCheckBox->isChecked()) { + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer,2); + glDrawArrays(GL_POINTS, 0, ROI_points.size()/3); + glUseProgram(0); + } + else{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_spheres); + uniform_attrib(viewer,3); + glDrawArraysInstanced(GL_TRIANGLES, 0, pos_sphere.size()/3, ROI_points.size()/3); + glUseProgram(0); + } glBindVertexArray(0); } - - glBindVertexArray(vao[1]); - glUseProgram(rendering_program_points); - uniform_attrib(viewer,2); - glDrawArrays(GL_POINTS, 0, control_points.size()/3); + if(!ui_widget->ShowAsSphereCheckBox->isChecked()) { + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer,2); + glDrawArrays(GL_POINTS, 0, control_points.size()/3); + } + else{ + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_spheres); + uniform_attrib(viewer,3); + glDrawArraysInstanced(GL_TRIANGLES, 0, pos_sphere.size()/3, control_points.size()/3); + } glUseProgram(0); glBindVertexArray(0); @@ -813,48 +1059,6 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* } } - /* // draw ROI - - if(ui_widget->ShowROICheckBox->isChecked()) { - BOOST_FOREACH(vertex_descriptor vd, deform_mesh.roi_vertices()) - { - if(!deform_mesh.is_control_vertex(vd)) - gl_draw_point( vd->point() ); - } - } - // draw control vertices related things - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - - for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) - { - if(hgb_data->frame == viewer->manipulatedFrame()) - { - // draw axis - ::glPushMatrix(); - ::glMultMatrixd(hgb_data->frame->matrix()); - QGLViewer::drawAxis(length_of_axis); - ::glPopMatrix(); - // draw bbox - if(!ui_widget->ActivatePivotingCheckBox->isChecked()) - { - color.set_rgb_color(1.0f, 0, 0); - ::glPushMatrix(); - ::glTranslated(hgb_data->frame->position().x, hgb_data->frame->position().y, hgb_data->frame->position().z); - ::glMultMatrixd(hgb_data->frame->orientation().matrix()); - ::glTranslated(-hgb_data->frame_initial_center.x, -hgb_data->frame_initial_center.y, -hgb_data->frame_initial_center.z); - draw_bbox(hgb_data->bbox); - ::glPopMatrix(); - } - } - // draw control vertices - if(hgb_data == active_group) { color.set_rgb_color(1.0f, 0, 0); } - else { color.set_rgb_color(0, 0, 1.0f); } - for(std::vector::const_iterator hb = hgb_data->ctrl_vertices_group.begin(); hb != hgb_data->ctrl_vertices_group.end(); ++hb) - { gl_draw_point( (*hb)->point() ); - } - } - - if(enable_back_lighting) { glEnable(GL_LIGHTING); }*/ } void Scene_edit_polyhedron_item::gl_draw_point(const Point& p) const { @@ -1055,7 +1259,183 @@ bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e) qglviewer::AxisPlaneConstraint::AXIS); return true; } + return false; } +void Scene_edit_polyhedron_item::create_Sphere(double R) +{ + + float T, P; + float x[4],y[4],z[4]; + int rings = 22, sectors = 45; + + + //Top of the sphere + for(int t=0; t<360; t+=sectors) + { + + pos_sphere.push_back(0); + pos_sphere.push_back(0); + pos_sphere.push_back(R); + + + normals_sphere.push_back(0); + normals_sphere.push_back(0); + normals_sphere.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); + pos_sphere.push_back(R * x[1]); + pos_sphere.push_back(R * y[1]); + pos_sphere.push_back(R * z[1]); + + normals_sphere.push_back(x[1]); + normals_sphere.push_back(y[1]); + normals_sphere.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); + pos_sphere.push_back(R * x[2]); + pos_sphere.push_back(R * y[2]); + pos_sphere.push_back(R * z[2]); + + normals_sphere.push_back(x[2]); + normals_sphere.push_back(y[2]); + normals_sphere.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) + { + //A + 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); + + pos_sphere.push_back(R * x[0]); + pos_sphere.push_back(R * y[0]); + pos_sphere.push_back(R * z[0]); + + normals_sphere.push_back(x[0]); + normals_sphere.push_back(y[0]); + normals_sphere.push_back(z[0]); + + //B + 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); + pos_sphere.push_back(R * x[1]); + pos_sphere.push_back(R * y[1]); + pos_sphere.push_back(R * z[1]); + + normals_sphere.push_back(x[1]); + normals_sphere.push_back(y[1]); + normals_sphere.push_back(z[1]); + + //C + 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); + pos_sphere.push_back(R * x[2]); + pos_sphere.push_back(R * y[2]); + pos_sphere.push_back(R * z[2]); + + normals_sphere.push_back(x[2]); + normals_sphere.push_back(y[2]); + normals_sphere.push_back(z[2]); + //D + 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); + pos_sphere.push_back(R * x[3]); + pos_sphere.push_back(R * y[3]); + pos_sphere.push_back(R * z[3]); + + normals_sphere.push_back(x[3]); + normals_sphere.push_back(y[3]); + normals_sphere.push_back(z[3]); + + + + pos_sphere.push_back(R * x[1]); + pos_sphere.push_back(R * y[1]); + pos_sphere.push_back(R * z[1]); + + normals_sphere.push_back(x[1]); + normals_sphere.push_back(y[1]); + normals_sphere.push_back(z[1]); + + pos_sphere.push_back(R * x[2]); + pos_sphere.push_back(R * y[2]); + pos_sphere.push_back(R * z[2]); + + normals_sphere.push_back(x[2]); + normals_sphere.push_back(y[2]); + normals_sphere.push_back(z[2]); + + } + //Bottom of the sphere + for(int t=0; t<360; t+=sectors) + { + + + pos_sphere.push_back(0); + pos_sphere.push_back(0); + pos_sphere.push_back(-R); + + normals_sphere.push_back(0); + normals_sphere.push_back(0); + normals_sphere.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); + pos_sphere.push_back(R * x[1]); + pos_sphere.push_back(R * y[1]); + pos_sphere.push_back(R * z[1]); + + normals_sphere.push_back(x[1]); + normals_sphere.push_back(y[1]); + normals_sphere.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); + pos_sphere.push_back(R * x[2]); + pos_sphere.push_back(R * y[2]); + pos_sphere.push_back(R * z[2]); + + normals_sphere.push_back(x[2]); + normals_sphere.push_back(y[2]); + normals_sphere.push_back(z[2]); + + } +} + #include "Scene_edit_polyhedron_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index f00ce6900a4..b319eb450d9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -280,19 +280,26 @@ private: std::vector normals; std::vector pos_bbox; std::vector pos_axis; + std::vector pos_sphere; + std::vector normals_sphere; + std::vector centers_control; + std::vector centers_ROI; + std::vector color_sphere_ROI; + std::vector color_sphere_control; GLuint rendering_program_facets; GLuint rendering_program_lines; GLuint rendering_program_points; - GLint location[20]; + GLuint rendering_program_spheres; + GLint location[22]; GLuint vao[3]; - GLuint buffer[20]; + GLuint buffer[19]; void initialize_buffers(); void compile_shaders(void); void compute_normals_and_vertices(void); void uniform_attrib(Viewer_interface*, int) const; void compute_bbox(const Scene_interface::Bbox&); - void drawSphere(float); + void create_Sphere(double); @@ -692,6 +699,7 @@ protected: normals[id*3] = n.x(); normals[id*3+1] = n.y(); normals[id*3+2] = n.z(); + } } protected: From f06493726af9548cac25462d17230ee8e98541c9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Mar 2015 11:18:27 +0100 Subject: [PATCH 44/62] Upgraded to OpenGL ES 3.0 No more gluTessPolygon, which means the light does not reveal strange triangles in the surface, but the way nef_Polyhedron deals with the vertices from an OFF file makes a Triangulation mandatory for every polygon, even if it already is triangulated. --- .../Polyhedron/Scene_nef_polyhedron_item.cpp | 1029 ++++++++++++++--- .../Polyhedron/Scene_nef_polyhedron_item.h | 41 +- 2 files changed, 905 insertions(+), 165 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index 70a900c23f1..998de5be0a9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -12,25 +12,110 @@ #include "Scene_nef_rendering.h" #include -#include +#include +#include +#include +#include -Scene_nef_polyhedron_item::Scene_nef_polyhedron_item() - : Scene_item_with_display_list(), - nef_poly(new Nef_polyhedron) +typedef Nef_polyhedron::Traits Traits; +typedef Nef_polyhedron::Halffacet Facet; +typedef CGAL::Triangulation_2_filtered_projection_traits_3 P_traits; +typedef typename Nef_polyhedron::Halfedge_const_handle Halfedge_handle; +struct Face_info { + typename Nef_polyhedron::Halfedge_const_handle e[3]; + bool is_external; +}; +typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; +typedef CGAL::Triangulation_face_base_with_info_2 Fb1; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::No_intersection_tag Itag; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDTbase; +typedef CGAL::Constrained_triangulation_plus_2 CDT; + +struct light_info { + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; +}; +struct DPoint { + DPoint(GLdouble x, GLdouble y, GLdouble z) + { + coords[0] = x; + coords[1] = y; + coords[2] = z; + } + GLdouble coords[3]; +}; +Scene_nef_polyhedron_item::Scene_nef_polyhedron_item() + : Scene_item_with_display_list(), + positions_facets(0), + positions_lines(0), + color_lines(0), + color_facets(0), + color_points(0), + normals(0), + positions_points(0), + nef_poly(new Nef_polyhedron) +{ + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); + } Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(Nef_polyhedron* const p) - : Scene_item_with_display_list(), - nef_poly(p) + : Scene_item_with_display_list(), + positions_facets(0), + positions_lines(0), + color_lines(0), + color_facets(0), + color_points(0), + normals(0), + positions_points(0), + nef_poly(p) { + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); + } Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(const Nef_polyhedron& p) - : Scene_item_with_display_list(), - nef_poly(new Nef_polyhedron(p)) + : Scene_item_with_display_list(), + positions_facets(0), + positions_lines(0), + normals(0), + color_lines(0), + color_facets(0), + color_points(0), + positions_points(0), + nef_poly(new Nef_polyhedron(p)) { + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); + } // Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(const Scene_nef_polyhedron_item& item) @@ -41,251 +126,854 @@ Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(const Nef_polyhedron& p) Scene_nef_polyhedron_item::~Scene_nef_polyhedron_item() { - delete nef_poly; + glDeleteBuffers(6, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_facets); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_points); + delete nef_poly; +} + +void Scene_nef_polyhedron_item::initialize_buffers() +{ + glBindVertexArray(vao[0]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_facets.size())*sizeof(double), + positions_facets.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(0, //number of the buffer + 3, //number of floats to be taken + GL_DOUBLE, // 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_lines.size())*sizeof(double), + positions_lines.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(1, //number of the buffer + 3, //number of floats to be taken + GL_DOUBLE, // 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.size())*sizeof(double), + normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glBufferData(GL_ARRAY_BUFFER, + (color_facets.size())*sizeof(double), + color_facets.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glBufferData(GL_ARRAY_BUFFER, + (color_lines.size())*sizeof(double), + color_lines.data(), GL_STATIC_DRAW); + glVertexAttribPointer(4, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(4); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[5]); + glBufferData(GL_ARRAY_BUFFER, + (positions_points.size())*sizeof(double), + positions_points.data(), GL_STATIC_DRAW); + glVertexAttribPointer(5, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(5); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[6]); + glBufferData(GL_ARRAY_BUFFER, + (color_points.size())*sizeof(double), + color_points.data(), GL_STATIC_DRAW); + glVertexAttribPointer(6, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(6); + // Clean-up + glBindVertexArray(0); + + +} + +void Scene_nef_polyhedron_item::compile_shaders(void) +{ + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec3 positions; \n" + "layout (location = 2) in vec3 vNormals; \n" + "layout (location = 3) in vec3 color_facets; \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 * color_facets; \n" + " else \n" + " diffuse = max(dot(N,L), 0.0) * light_diff * color_facets; \n" + " vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" + + " fColors =light_amb*color_facets+ 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" + "precision mediump float; \n" + "in vec3 fColors; \n" + + "out 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, 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); + + //Clean-up + glDeleteShader(vertex_shader); + + rendering_program_facets = program; + + //For the edges + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 1) in vec3 positions; \n" + "layout (location = 4) in vec3 color_lines; \n" + + "uniform mat4 mvp_matrix; \n" + + "out highp vec3 fColors; \n" + "vec4 positions_lines = vec4(positions, 1.0); \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color_lines; \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); + //Clean-up + glDeleteShader(vertex_shader); + rendering_program_lines = program; + + //For the points + static const GLchar* vertex_shader_source_points[] = + { + "#version 300 es \n" + " \n" + "layout (location = 5) in vec3 positions; \n" + "layout (location = 6) in vec3 color; \n" + "uniform mat4 mvp_matrix; \n" + + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color; \n" + " gl_Position = mvp_matrix * vec4(positions, 1.0); \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); + //Clean-up + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + rendering_program_points = program; +} + +void Scene_nef_polyhedron_item::compute_normals_and_vertices(void) +{ + int count = 0; + positions_facets.clear(); + positions_points.clear(); + color_lines.clear(); + color_facets.clear(); + color_points.clear(); + normals.clear(); + //The Facets + { + for(Nef_polyhedron::Halffacet_const_iterator + f = nef_poly->halffacets_begin (), + end = nef_poly->halffacets_end(); + f != end; ++f) + { + if(f->is_twin()) continue; + count++; + Nef_polyhedron::Vector_3 v = f->plane().orthogonal_vector(); + P_traits cdt_traits(v); + CDT cdt(cdt_traits); + + for(Nef_polyhedron::Halffacet_cycle_const_iterator + fc = f->facet_cycles_begin(), + end = f->facet_cycles_end(); + fc != end; ++fc) + { + if ( fc.is_shalfedge() ) + { + + Nef_polyhedron::SHalfedge_const_handle h = fc; + Nef_polyhedron::SHalfedge_around_facet_const_circulator hc(h), he(hc); + + typename CDT::Vertex_handle previous, first; + + do { + Nef_polyhedron::SVertex_const_handle v = hc->source(); + const Nef_polyhedron::Point_3& point = v->source()->point(); + typename CDT::Vertex_handle vh = cdt.insert(point); + if(first == 0) { + first = vh; + } + vh->info() = hc->source(); + if(previous != 0 && previous != vh) { + cdt.insert_constraint(previous, vh); + } + previous = vh; + } while( ++hc != he ); + + cdt.insert_constraint(previous, first); + + // sets mark is_external + for(typename CDT::All_faces_iterator + fit = cdt.all_faces_begin(), + end = cdt.all_faces_end(); + fit != end; ++fit) + { + fit->info().is_external = false; + + } + //check if the facet is external or internal + std::queue face_queue; + face_queue.push(cdt.infinite_vertex()->face()); + + while(! face_queue.empty() ) { + typename CDT::Face_handle fh = face_queue.front(); + face_queue.pop(); + if(fh->info().is_external) continue; + fh->info().is_external = true; + for(int i = 0; i <3; ++i) { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + face_queue.push(fh->neighbor(i)); + } + } + + } + //iterates on the internal faces to add the vertices to the positions + //and the normals to the appropriate vectors + + for(typename CDT::Finite_faces_iterator + ffit = cdt.finite_faces_begin(), + end = cdt.finite_faces_end(); + ffit != end; ++ffit) + { + + + if(ffit->info().is_external){ continue;} + for(int i = 0; i<3; i++) + { + positions_facets.push_back(CGAL::to_double(ffit->vertex(i)->point().x())); + positions_facets.push_back(CGAL::to_double(ffit->vertex(i)->point().y())); + positions_facets.push_back(CGAL::to_double(ffit->vertex(i)->point().z())); + + } + + + + Nef_polyhedron::Vector_3 v = f->plane().orthogonal_vector(); + GLdouble normal[3]; + normal[0] = CGAL::to_double(v.x()); + normal[1] = CGAL::to_double(v.y()); + normal[2] = CGAL::to_double(v.z()); + GLdouble norm = normal[0]*normal[0] + + normal[1]*normal[1] + + normal[2]*normal[2]; + norm = CGAL::sqrt(norm); + normal[0] /= norm; + normal[1] /= norm; + normal[2] /= norm; + + normals.push_back(normal[0]); + normals.push_back(normal[1]); + normals.push_back(normal[2]); + + normals.push_back(normal[0]); + normals.push_back(normal[1]); + normals.push_back(normal[2]); + + normals.push_back(normal[0]); + normals.push_back(normal[1]); + normals.push_back(normal[2]); + + if(is_selected) + { + color_facets.push_back(this->color().lighter(120).redF()); + color_facets.push_back(this->color().lighter(120).greenF()); + color_facets.push_back(this->color().lighter(120).blueF()); + + color_facets.push_back(this->color().lighter(120).redF()); + color_facets.push_back(this->color().lighter(120).greenF()); + color_facets.push_back(this->color().lighter(120).blueF()); + + color_facets.push_back(this->color().lighter(120).redF()); + color_facets.push_back(this->color().lighter(120).greenF()); + color_facets.push_back(this->color().lighter(120).blueF()); + } + else + { + color_facets.push_back(this->color().redF()); + color_facets.push_back(this->color().greenF()); + color_facets.push_back(this->color().blueF()); + + color_facets.push_back(this->color().redF()); + color_facets.push_back(this->color().greenF()); + color_facets.push_back(this->color().blueF()); + + color_facets.push_back(this->color().redF()); + color_facets.push_back(this->color().greenF()); + color_facets.push_back(this->color().blueF()); + + } + + } + } + } + } + + } // end facets + + //The Lines + { + for(Nef_polyhedron::Halfedge_const_iterator + e = nef_poly->halfedges_begin(), + end = nef_poly->halfedges_end(); + e != end; ++e) + { + if (e->is_twin()) continue; + const Nef_polyhedron::Vertex_const_handle& s = e->source(); + const Nef_polyhedron::Vertex_const_handle& t = e->twin()->source(); + const Nef_polyhedron::Point_3& a = s->point(); + const Nef_polyhedron::Point_3& b = t->point(); + + positions_lines.push_back(CGAL::to_double(a.x())); + positions_lines.push_back(CGAL::to_double(a.y())); + positions_lines.push_back(CGAL::to_double(a.z())); + + positions_lines.push_back(CGAL::to_double(b.x())); + positions_lines.push_back(CGAL::to_double(b.y())); + positions_lines.push_back(CGAL::to_double(b.z())); + + if(is_selected) + { + color_lines.push_back(this->color().lighter(50).redF()); + color_lines.push_back(this->color().lighter(50).greenF()); + color_lines.push_back(this->color().lighter(50).blueF()); + + color_lines.push_back(this->color().lighter(50).redF()); + color_lines.push_back(this->color().lighter(50).greenF()); + color_lines.push_back(this->color().lighter(50).blueF()); + } + else + { + color_lines.push_back(0.0); + color_lines.push_back(0.0); + color_lines.push_back(0.0); + + color_lines.push_back(0.0); + color_lines.push_back(0.0); + color_lines.push_back(0.0); + } + } + } + //The points + { + for(Nef_polyhedron::Vertex_const_iterator + v = nef_poly->vertices_begin(), + end = nef_poly->vertices_end(); + v != end; ++v) + { + const Nef_polyhedron::Point_3& p = v->point(); + positions_points.push_back(CGAL::to_double(p.x())); + positions_points.push_back(CGAL::to_double(p.y())); + positions_points.push_back(CGAL::to_double(p.z())); + + color_points.push_back(this->color().lighter(50).redF()); + color_points.push_back(this->color().lighter(50).greenF()); + color_points.push_back(this->color().lighter(50).blueF()); + + color_points.push_back(this->color().lighter(50).redF()); + color_points.push_back(this->color().lighter(50).greenF()); + color_points.push_back(this->color().lighter(50).blueF()); + + } + + } //end points + + 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_points, "mvp_matrix"); + + +} + +void Scene_nef_polyhedron_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 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); + + + //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); + 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); + } + else if(mode ==1) + { + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[7], 1, GL_FALSE, mvp_mat); + } + else if(mode ==2) + { + glUseProgram(rendering_program_points); + glUniformMatrix4fv(location[8], 1, GL_FALSE, mvp_mat); + } } Scene_nef_polyhedron_item* Scene_nef_polyhedron_item::clone() const { - return new Scene_nef_polyhedron_item(*nef_poly); + return new Scene_nef_polyhedron_item(*nef_poly); } bool Scene_nef_polyhedron_item::load_from_off(std::istream& in) { -// const std::size_t discarded = CGAL::OFF_to_nef_3(in, *nef_poly); -// return discarded != 0; + // const std::size_t discarded = CGAL::OFF_to_nef_3(in, *nef_poly); + // return discarded != 0; - Exact_polyhedron exact_poly; - in >> exact_poly; - *nef_poly = Nef_polyhedron(exact_poly); + Exact_polyhedron exact_poly; + in >> exact_poly; + *nef_poly = Nef_polyhedron(exact_poly); -// Polyhedron poly; -// in >> poly; -// *nef_poly = Nef_polyhedron(poly); - return (bool) in; + // Polyhedron poly; + // in >> poly; + // *nef_poly = Nef_polyhedron(poly); + changed(); + return (bool) in; } QFont Scene_nef_polyhedron_item::font() const { - QFont font; - font.setItalic(!font.italic()); - return font; + QFont font; + font.setItalic(!font.italic()); + return font; } bool Scene_nef_polyhedron_item::load(std::istream& in) { - in >> *nef_poly; - return (bool) in; + in >> *nef_poly; + changed(); + return (bool) in; } bool Scene_nef_polyhedron_item::save(std::ostream& in) const { - in << *nef_poly; - return (bool) in; + in << *nef_poly; + return (bool) in; } QString Scene_nef_polyhedron_item::toolTip() const { - if(!nef_poly) - return QString(); + if(!nef_poly) + return QString(); - return QObject::tr("

%1 (mode: %5, color: %6)
" - "Nef_3 polyhedron

" - "

Number of vertices: %2
" - "Number of edges: %3
" - "Number of facets: %4
" - "number of volumes: %7

") - .arg(this->name()) - .arg(nef_poly->number_of_vertices()) - .arg(nef_poly->number_of_edges()) - .arg(nef_poly->number_of_facets()) - .arg(this->renderingModeName()) - .arg(this->color().name()) - .arg(nef_poly->number_of_volumes()); + return QObject::tr("

%1 (mode: %5, color: %6)
" + "Nef_3 polyhedron

" + "

Number of vertices: %2
" + "Number of edges: %3
" + "Number of facets: %4
" + "number of volumes: %7

") + .arg(this->name()) + .arg(nef_poly->number_of_vertices()) + .arg(nef_poly->number_of_edges()) + .arg(nef_poly->number_of_facets()) + .arg(this->renderingModeName()) + .arg(this->color().name()) + .arg(nef_poly->number_of_volumes()); } void Scene_nef_polyhedron_item::direct_draw() const { - gl_render_nef_facets(nef_poly); + gl_render_nef_facets(nef_poly); - GLboolean lighting; - glGetBooleanv(GL_LIGHTING, &lighting); - glDisable(GL_LIGHTING); + GLboolean lighting; + glGetBooleanv(GL_LIGHTING, &lighting); + glDisable(GL_LIGHTING); - GLfloat point_size; - glGetFloatv(GL_POINT_SIZE, &point_size); - glPointSize(10.f); + GLfloat point_size; + glGetFloatv(GL_POINT_SIZE, &point_size); + glPointSize(10.f); - gl_render_nef_vertices(nef_poly); + gl_render_nef_vertices(nef_poly); + + if(lighting) { + glEnable(GL_LIGHTING); + } + glPointSize(point_size); +} +void Scene_nef_polyhedron_item::draw(Viewer_interface* viewer) const +{ + glBindVertexArray(vao[0]); + + // tells the GPU to use the program just created + glUseProgram(rendering_program_facets); + uniform_attrib(viewer,0); + //draw the polygons + // the third argument is the number of vec4 that will be entered + glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/3); + + + GLfloat point_size; + glGetFloatv(GL_POINT_SIZE, &point_size); + glPointSize(10.f); + + draw_points(viewer); + glPointSize(point_size); + + glUseProgram(0); + glBindVertexArray(0); + +} +void Scene_nef_polyhedron_item::draw_edges(Viewer_interface* viewer) const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer ,1); + glDrawArrays(GL_LINES,0,positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); +} +void Scene_nef_polyhedron_item::draw_points(Viewer_interface* viewer) const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer ,2); + glDrawArrays(GL_POINTS,0,positions_points.size()/3); + glUseProgram(0); + glBindVertexArray(0); - if(lighting) { - glEnable(GL_LIGHTING); - } - glPointSize(point_size); } -void -Scene_nef_polyhedron_item::draw_edges() const { - gl_render_nef_edges(nef_poly); -} Nef_polyhedron* Scene_nef_polyhedron_item::nef_polyhedron() { - return nef_poly; + return nef_poly; } bool Scene_nef_polyhedron_item::isEmpty() const { - return (nef_poly == 0) || nef_poly->is_empty(); + return (nef_poly == 0) || nef_poly->is_empty(); } Scene_nef_polyhedron_item::Bbox Scene_nef_polyhedron_item::bbox() const { - if(isEmpty()) - return Bbox(); - CGAL::Bbox_3 bbox(nef_poly->vertices_begin()->point().bbox()); - for(Nef_polyhedron::Vertex_const_iterator it = nef_poly->vertices_begin(); - it != nef_poly->vertices_end(); - ++it) { - bbox = bbox + it->point().bbox(); - } - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + if(isEmpty()) + return Bbox(); + CGAL::Bbox_3 bbox(nef_poly->vertices_begin()->point().bbox()); + for(Nef_polyhedron::Vertex_const_iterator it = nef_poly->vertices_begin(); + it != nef_poly->vertices_end(); + ++it) { + bbox = bbox + it->point().bbox(); + } + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); } // quick hacks to convert polyhedra from exact to inexact and vice-versa template + class Polyhedron_output> struct Copy_polyhedron_to - : public CGAL::Modifier_base + : public CGAL::Modifier_base { - Copy_polyhedron_to(const Polyhedron_input& in_poly) - : in_poly(in_poly) {} + Copy_polyhedron_to(const Polyhedron_input& in_poly) + : in_poly(in_poly) {} - void operator()(typename Polyhedron_output::HalfedgeDS& out_hds) - { - typedef typename Polyhedron_output::HalfedgeDS Output_HDS; - - CGAL::Polyhedron_incremental_builder_3 builder(out_hds); - - typedef typename Polyhedron_input::Vertex_const_iterator Vertex_const_iterator; - typedef typename Polyhedron_input::Facet_const_iterator Facet_const_iterator; - typedef typename Polyhedron_input::Halfedge_around_facet_const_circulator HFCC; - - builder.begin_surface(in_poly.size_of_vertices(), - in_poly.size_of_facets(), - in_poly.size_of_halfedges()); - - for(Vertex_const_iterator - vi = in_poly.vertices_begin(), end = in_poly.vertices_end(); - vi != end ; ++vi) + void operator()(typename Polyhedron_output::HalfedgeDS& out_hds) { - typename Polyhedron_output::Point_3 p(::CGAL::to_double( vi->point().x()), - ::CGAL::to_double( vi->point().y()), - ::CGAL::to_double( vi->point().z())); - builder.add_vertex(p); - } + typedef typename Polyhedron_output::HalfedgeDS Output_HDS; - typedef CGAL::Inverse_index Index; - Index index( in_poly.vertices_begin(), in_poly.vertices_end()); + CGAL::Polyhedron_incremental_builder_3 builder(out_hds); - for(Facet_const_iterator - fi = in_poly.facets_begin(), end = in_poly.facets_end(); - fi != end; ++fi) - { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - // std::size_t n = circulator_size( hc); - // CGAL_assertion( n >= 3); - builder.begin_facet (); - do { - builder.add_vertex_to_facet(index[hc->vertex()]); - ++hc; - } while( hc != hc_end); - builder.end_facet(); - } - builder.end_surface(); - } // end operator()(..) + typedef typename Polyhedron_input::Vertex_const_iterator Vertex_const_iterator; + typedef typename Polyhedron_input::Facet_const_iterator Facet_const_iterator; + typedef typename Polyhedron_input::Halfedge_around_facet_const_circulator HFCC; + + builder.begin_surface(in_poly.size_of_vertices(), + in_poly.size_of_facets(), + in_poly.size_of_halfedges()); + + for(Vertex_const_iterator + vi = in_poly.vertices_begin(), end = in_poly.vertices_end(); + vi != end ; ++vi) + { + typename Polyhedron_output::Point_3 p(::CGAL::to_double( vi->point().x()), + ::CGAL::to_double( vi->point().y()), + ::CGAL::to_double( vi->point().z())); + builder.add_vertex(p); + } + + typedef CGAL::Inverse_index Index; + Index index( in_poly.vertices_begin(), in_poly.vertices_end()); + + for(Facet_const_iterator + fi = in_poly.facets_begin(), end = in_poly.facets_end(); + fi != end; ++fi) + { + HFCC hc = fi->facet_begin(); + HFCC hc_end = hc; + // std::size_t n = circulator_size( hc); + // CGAL_assertion( n >= 3); + builder.begin_facet (); + do { + builder.add_vertex_to_facet(index[hc->vertex()]); + ++hc; + } while( hc != hc_end); + builder.end_facet(); + } + builder.end_surface(); + } // end operator()(..) private: - const Polyhedron_input& in_poly; + const Polyhedron_input& in_poly; }; // end Copy_polyhedron_to<> template void copy_to(const Poly_A& poly_a, Poly_B& poly_b) { - Copy_polyhedron_to modifier(poly_a); - poly_b.delegate(modifier); + Copy_polyhedron_to modifier(poly_a); + poly_b.delegate(modifier); } void from_exact(Exact_polyhedron& in, - Polyhedron& out) + Polyhedron& out) { - copy_to(in, out); - CGAL_assertion(out.is_valid()); + copy_to(in, out); + CGAL_assertion(out.is_valid()); } void to_exact(Polyhedron& in, - Exact_polyhedron& out) + Exact_polyhedron& out) { - copy_to(in, out); - CGAL_assertion(out.is_valid()); + copy_to(in, out); + CGAL_assertion(out.is_valid()); } bool Scene_nef_polyhedron_item::is_simple() const { - return nef_poly->is_simple(); + return nef_poly->is_simple(); } // [static] Scene_nef_polyhedron_item* Scene_nef_polyhedron_item::from_polyhedron(Scene_polyhedron_item* item) { - Polyhedron* poly = item->polyhedron(); - if(!poly) return 0; + Polyhedron* poly = item->polyhedron(); + if(!poly) return 0; - Exact_polyhedron exact_poly; - to_exact(*poly, exact_poly); - Nef_polyhedron* nef_poly = new Nef_polyhedron(exact_poly); - exact_poly.clear(); + Exact_polyhedron exact_poly; + to_exact(*poly, exact_poly); + Nef_polyhedron* nef_poly = new Nef_polyhedron(exact_poly); + exact_poly.clear(); - return new Scene_nef_polyhedron_item(nef_poly); + return new Scene_nef_polyhedron_item(nef_poly); } Scene_polyhedron_item* Scene_nef_polyhedron_item::convert_to_polyhedron() const { - Exact_polyhedron exact_poly; - nef_poly->convert_to_Polyhedron(exact_poly); - Polyhedron* poly = new Polyhedron; - from_exact(exact_poly, *poly); - exact_poly.clear(); - return new Scene_polyhedron_item(poly); + Exact_polyhedron exact_poly; + nef_poly->convert_to_Polyhedron(exact_poly); + Polyhedron* poly = new Polyhedron; + from_exact(exact_poly, *poly); + exact_poly.clear(); + return new Scene_polyhedron_item(poly); } Scene_nef_polyhedron_item& Scene_nef_polyhedron_item:: operator+=(const Scene_nef_polyhedron_item& other) { - (*nef_poly) += (*other.nef_poly); - return *this; + (*nef_poly) += (*other.nef_poly); + return *this; } Scene_nef_polyhedron_item& Scene_nef_polyhedron_item:: operator*=(const Scene_nef_polyhedron_item& other) { - (*nef_poly) *= (*other.nef_poly); - return *this; + (*nef_poly) *= (*other.nef_poly); + return *this; } Scene_nef_polyhedron_item& Scene_nef_polyhedron_item:: operator-=(const Scene_nef_polyhedron_item& other) { - (*nef_poly) -= (*other.nef_poly); - return *this; + (*nef_poly) -= (*other.nef_poly); + return *this; } Scene_nef_polyhedron_item* @@ -293,31 +981,50 @@ Scene_nef_polyhedron_item:: sum(const Scene_nef_polyhedron_item& a, const Scene_nef_polyhedron_item& b) { - return new Scene_nef_polyhedron_item(CGAL::minkowski_sum_3(*a.nef_poly, - *b.nef_poly)); + return new Scene_nef_polyhedron_item(CGAL::minkowski_sum_3(*a.nef_poly, + *b.nef_poly)); } void Scene_nef_polyhedron_item:: convex_decomposition(std::list< Scene_polyhedron_item*>& convex_parts) { - // copy the Nef polyhedron, as markers are added - Nef_polyhedron N(*nef_poly); - CGAL::convex_decomposition_3(N); - - typedef Nef_polyhedron::Volume_const_iterator Volume_const_iterator; - - Volume_const_iterator ci = ++N.volumes_begin(); - for( ; ci != N.volumes_end(); ++ci) { - if(ci->mark()) { - Exact_polyhedron P; - N.convert_inner_shell_to_polyhedron(ci->shells_begin(), P); - Polyhedron* poly = new Polyhedron; - from_exact(P, *poly); - convex_parts.push_back(new Scene_polyhedron_item(poly)); + // copy the Nef polyhedron, as markers are added + Nef_polyhedron N(*nef_poly); + CGAL::convex_decomposition_3(N); + + typedef Nef_polyhedron::Volume_const_iterator Volume_const_iterator; + + Volume_const_iterator ci = ++N.volumes_begin(); + for( ; ci != N.volumes_end(); ++ci) { + if(ci->mark()) { + Exact_polyhedron P; + N.convert_inner_shell_to_polyhedron(ci->shells_begin(), P); + Polyhedron* poly = new Polyhedron; + from_exact(P, *poly); + convex_parts.push_back(new Scene_polyhedron_item(poly)); + } } - } } - +void +Scene_nef_polyhedron_item:: +changed() +{ + // init(); + Base::changed(); + compute_normals_and_vertices(); + initialize_buffers(); +} #include "Scene_nef_polyhedron_item.moc" +void +Scene_nef_polyhedron_item::selection_changed(bool p_is_selected) +{ + + if(p_is_selected != is_selected) + { + is_selected = p_is_selected; + changed(); + } + +} diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h index 8f37c43c85d..024eea69a0b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h @@ -5,14 +5,14 @@ #include "Scene_item_with_display_list.h" #include "Nef_type_fwd.h" #include - +#include class Scene_polyhedron_item; class SCENE_NEF_POLYHEDRON_ITEM_EXPORT Scene_nef_polyhedron_item : public Scene_item_with_display_list { Q_OBJECT -public: +public: Scene_nef_polyhedron_item(); // Scene_nef_polyhedron_item(const Scene_nef_polyhedron_item&); Scene_nef_polyhedron_item(const Nef_polyhedron& p); @@ -27,12 +27,18 @@ public: QFont font() const; QString toolTip() const; + virtual void changed(); + virtual void selection_changed(bool); // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud && m!=Splatting; } // CHECK THIS! // OpenGL drawing in a display list void direct_draw() const; + + virtual void draw(Viewer_interface*) const; + virtual void draw_edges() const {} + virtual void draw_edges(Viewer_interface* viewer) const; + virtual void draw_points(Viewer_interface*) const; // Wireframe OpenGL drawing - void draw_edges() const; bool isFinite() const { return true; } bool isEmpty() const; @@ -42,7 +48,7 @@ public: const Nef_polyhedron* nef_polyhedron() const; bool is_simple() const; - + bool is_Triangle; // conversion operations static Scene_nef_polyhedron_item* from_polyhedron(Scene_polyhedron_item*); Scene_polyhedron_item* convert_to_polyhedron() const; @@ -64,7 +70,34 @@ public: void convex_decomposition(std::list< Scene_polyhedron_item*>&); private: + typedef Scene_item Base; + typedef std::vector Color_vector; + Nef_polyhedron* nef_poly; + + + std::vector positions_lines; + std::vector positions_facets; + std::vector positions_points; + std::vector normals; + std::vector color_lines; + std::vector color_facets; + std::vector color_points; + + GLuint rendering_program_facets; + GLuint rendering_program_lines; + GLuint rendering_program_points; + GLint location[9]; + + GLuint vao[1]; + GLuint buffer[7]; + void initialize_buffers(); + void compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*, int) const; + void compute_colors(); + void triangulate_facet(); + void triangulate_facet_color(); }; // end class Scene_nef_polyhedron_item #endif // SCENE_NEF_POLYHEDRON_ITEM_H From 85e0de731a6251f3b5412ff83a3940c64e4f72a2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Mar 2015 11:35:56 +0100 Subject: [PATCH 45/62] Convex Decomposition fixed Just added a call to changed() in the function. --- Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index 998de5be0a9..909324826e2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -1002,8 +1002,11 @@ convex_decomposition(std::list< Scene_polyhedron_item*>& convex_parts) N.convert_inner_shell_to_polyhedron(ci->shells_begin(), P); Polyhedron* poly = new Polyhedron; from_exact(P, *poly); - convex_parts.push_back(new Scene_polyhedron_item(poly)); + Scene_polyhedron_item *spoly = new Scene_polyhedron_item(poly); + convex_parts.push_back(spoly); + spoly->changed(); } + } } From 20a5f19fe6eaac45b148abad46f9595e4b75e4b9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Mar 2015 11:50:06 +0100 Subject: [PATCH 46/62] Points+normals fixed I don't really understand why it is called points+normals as it never was the normals, but anyway. The problem is that the points are drawn twice, once with draw and once with draw_edges. --- Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index 909324826e2..f0a265067a8 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -805,6 +805,14 @@ void Scene_nef_polyhedron_item::draw_edges(Viewer_interface* viewer) const glUseProgram(rendering_program_lines); uniform_attrib(viewer ,1); glDrawArrays(GL_LINES,0,positions_lines.size()/3); + + GLfloat point_size; + glGetFloatv(GL_POINT_SIZE, &point_size); + glPointSize(10.f); + + draw_points(viewer); + glPointSize(point_size); + glUseProgram(0); glBindVertexArray(0); } From 0c1dca6fa6e809588922a0dbeefbef502442529b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Mar 2015 12:15:28 +0100 Subject: [PATCH 47/62] Double pointsdrawing fixed I just found out about renderingMode() == PointsPlusNormal, that solved the problem. --- Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index f0a265067a8..d211b0791cb 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -805,14 +805,15 @@ void Scene_nef_polyhedron_item::draw_edges(Viewer_interface* viewer) const glUseProgram(rendering_program_lines); uniform_attrib(viewer ,1); glDrawArrays(GL_LINES,0,positions_lines.size()/3); - +if(renderingMode() == PointsPlusNormals) +{ GLfloat point_size; glGetFloatv(GL_POINT_SIZE, &point_size); glPointSize(10.f); draw_points(viewer); glPointSize(point_size); - +} glUseProgram(0); glBindVertexArray(0); } From 3a7f25962b6cbdeaf7fffc352f4b078982e4c120 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 18 Mar 2015 15:50:21 +0100 Subject: [PATCH 48/62] points_with_normals upgrade Splat_draw is missing for now, and I had to add some calls to changed from different files manipulating scene items. --- Polyhedron/demo/Polyhedron/Color_ramp.cpp | 3 +- ...lyhedron_demo_normal_estimation_plugin.cpp | 1 + .../Polyhedron_demo_poisson_plugin.cpp | 1 + Polyhedron/demo/Polyhedron/Scene.cpp | 10 +- .../Scene_combinatorial_map_item.cpp | 676 ++++++++------- .../Polyhedron/Scene_combinatorial_map_item.h | 115 +-- .../Polyhedron/Scene_nef_polyhedron_item.cpp | 2 +- .../Polyhedron/Scene_nef_polyhedron_item.h | 2 +- .../Scene_points_with_normal_item.cpp | 777 ++++++++++++++---- 9 files changed, 1078 insertions(+), 509 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Color_ramp.cpp b/Polyhedron/demo/Polyhedron/Color_ramp.cpp index c8d74b8f0fd..40c55a9c2d9 100644 --- a/Polyhedron/demo/Polyhedron/Color_ramp.cpp +++ b/Polyhedron/demo/Polyhedron/Color_ramp.cpp @@ -35,10 +35,11 @@ interpolate(const double v) const { return prev->second; } - + const double& a = prev->first; const double& b = next->first; return (b-v)/(b-a) * prev->second + (v-a)/(b-a) * next->second; + } void diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp index dc5b2502fa6..3fced8ead16 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp @@ -98,6 +98,7 @@ void Polyhedron_demo_normal_estimation_plugin::on_actionNormalInversion_triggere for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ it->normal() = -1 * it->normal(); } + item->changed(); } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp index 9f0926a4b32..2383dc6ad18 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp @@ -115,6 +115,7 @@ void Polyhedron_demo_poisson_plugin::on_actionPoissonReconstruction_triggered() new_item->setColor(Qt::lightGray); scene->addItem(new_item); + // Hide point set point_set_item->setVisible(false); scene->itemChanged(index); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 39b5befcb1c..69bc66e05f5 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -56,12 +56,14 @@ Scene::Scene(QObject* parent) ms_splatting = new GlSplat::SplatRenderer(); ms_splattingCounter++; #endif + } Scene::Item_id Scene::addItem(Scene_item* item) { Bbox bbox_before = bbox(); + item->changed(); m_entries.push_back(item); connect(item, SIGNAL(itemChanged()), this, SLOT(itemChanged())); @@ -285,17 +287,19 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) { if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) { + item.selection_changed(false); ::glEnable(GL_LIGHTING); ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); ::glPointSize(2.f); ::glLineWidth(1.0f); if(index == selected_item) - {item.selection_changed(true); + { + item.selection_changed(true); CGALglcolor(item.color().lighter(120)); } else - {item.selection_changed(false); + { CGALglcolor(item.color()); } @@ -363,11 +367,13 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) ::glLineWidth(1.0f); if(index == selected_item) { + item.selection_changed(true); CGALglcolor(item.color().lighter(120)); } else { + item.selection_changed(false); CGALglcolor(item.color()); } diff --git a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp index b28fc6a42d9..9f7e04fd3d3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp @@ -6,8 +6,108 @@ #include #include #include - #include +#include #include +void Scene_combinatorial_map_item::initialize_buffers() +{ + glBindVertexArray(vao); + buffer[0] = QGLBuffer(QGLBuffer::VertexBuffer); + if(!(buffer[0].create())) + std::cout<<"ERROR lors de la creation"<compileSourceCode(vertex_shader_source)) + std::cout<log().toStdString()<compileSourceCode(fragment_shader_source)) + std::cout<log().toStdString()<addShader(vertex_shader)) + std::cout<log().toStdString()<addShader(fragment_shader)) + std::cout<log().toStdString()<link(); + +} + +void Scene_combinatorial_map_item::compute_normals_and_vertices(void) +{ + positions.push_back(-1.0); + positions.push_back(-1.0); + positions.push_back(0.0); + + positions.push_back(0.0); + positions.push_back(1.0); + positions.push_back(0.0); + + positions.push_back(1.0); + positions.push_back(-1.0); + positions.push_back(0.0); + +} + +void Scene_combinatorial_map_item::uniform_attrib(Viewer_interface*, int) const +{ + +} +void Scene_combinatorial_map_item::compute_colors() +{ + +} Scene_combinatorial_map_item::Scene_combinatorial_map_item(Scene_interface* scene,void* address):last_known_scene(scene),volume_to_display(0),exportSelectedVolume(NULL),address_of_A(address){m_combinatorial_map=NULL;} Scene_combinatorial_map_item::~Scene_combinatorial_map_item(){if (m_combinatorial_map!=NULL) delete m_combinatorial_map;} @@ -16,384 +116,384 @@ Scene_combinatorial_map_item* Scene_combinatorial_map_item::clone() const{return Kernel::Vector_3 Scene_combinatorial_map_item::compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const { - typedef Combinatorial_map_3::Dart_of_orbit_const_range<1> Dart_in_facet_range; - typedef Kernel::Vector_3 Vector_3; - Vector_3 normal = CGAL::NULL_VECTOR; - - Dart_in_facet_range vertices=combinatorial_map().darts_of_orbit<1>(adart); - Kernel::Point_3 points[3]; - int index=0; - Dart_in_facet_range::const_iterator pit=vertices.begin(); - for (;pit!=vertices.end() && index!=3;++pit,++index ){ - points[index]=pit->attribute<0>()->point(); - } - - if (index!=3) return normal; - - do{ - Vector_3 n = CGAL::cross_product(points[2]-points[1],points[0]-points[1]); - if (n != Vector_3(0,0,0) ) - normal = normal + (n / std::sqrt(n*n)); - points[0]=points[1]; - points[1]=points[2]; - if ( pit==vertices.end() ) break; - - points[2]=pit->attribute<0>()->point(); - ++pit; - }while(true); - - return normal == Vector_3(0,0,0)? normal : normal / std::sqrt(normal * normal); + typedef Combinatorial_map_3::Dart_of_orbit_const_range<1> Dart_in_facet_range; + typedef Kernel::Vector_3 Vector_3; + Vector_3 normal = CGAL::NULL_VECTOR; + + Dart_in_facet_range vertices=combinatorial_map().darts_of_orbit<1>(adart); + Kernel::Point_3 points[3]; + int index=0; + Dart_in_facet_range::const_iterator pit=vertices.begin(); + for (;pit!=vertices.end() && index!=3;++pit,++index ){ + points[index]=pit->attribute<0>()->point(); + } + + if (index!=3) return normal; + + do{ + Vector_3 n = CGAL::cross_product(points[2]-points[1],points[0]-points[1]); + if (n != Vector_3(0,0,0) ) + normal = normal + (n / std::sqrt(n*n)); + points[0]=points[1]; + points[1]=points[2]; + if ( pit==vertices.end() ) break; + + points[2]=pit->attribute<0>()->point(); + ++pit; + }while(true); + + return normal == Vector_3(0,0,0)? normal : normal / std::sqrt(normal * normal); } void Scene_combinatorial_map_item::set_next_volume(){ - ++volume_to_display; - volume_to_display=volume_to_display%(combinatorial_map().attributes<3>().size()+1); - emit itemChanged(); + ++volume_to_display; + volume_to_display=volume_to_display%(combinatorial_map().attributes<3>().size()+1); + emit itemChanged(); - if (exportSelectedVolume!=NULL && ( volume_to_display==1 || volume_to_display==0 ) ) - exportSelectedVolume->setEnabled(!exportSelectedVolume->isEnabled()); + if (exportSelectedVolume!=NULL && ( volume_to_display==1 || volume_to_display==0 ) ) + exportSelectedVolume->setEnabled(!exportSelectedVolume->isEnabled()); } template void Scene_combinatorial_map_item::export_as_polyhedron(Predicate pred,const QString& name) const { - typedef Combinatorial_map_3::Dart_const_handle Dart_handle; - typedef Combinatorial_map_3::One_dart_per_cell_const_range<3> One_dart_per_vol_range; - typedef CGAL::internal::Import_volume_as_polyhedron Volume_import_modifier; - - std::vector darts; - One_dart_per_vol_range cell_range=combinatorial_map().template one_dart_per_cell<3>(); + typedef Combinatorial_map_3::Dart_const_handle Dart_handle; + typedef Combinatorial_map_3::One_dart_per_cell_const_range<3> One_dart_per_vol_range; + typedef CGAL::internal::Import_volume_as_polyhedron Volume_import_modifier; - - for (One_dart_per_vol_range::const_iterator it = cell_range.begin();it!= cell_range.end() ; ++it ) - if ( pred(it) ){ - darts.push_back(it); - if (Predicate::only_one_run) break; + std::vector darts; + One_dart_per_vol_range cell_range=combinatorial_map().template one_dart_per_cell<3>(); + + + for (One_dart_per_vol_range::const_iterator it = cell_range.begin();it!= cell_range.end() ; ++it ) + if ( pred(it) ){ + darts.push_back(it); + if (Predicate::only_one_run) break; + } + + if (!darts.empty()) + { + Volume_import_modifier modifier=Predicate::swap_orientation? + Volume_import_modifier(combinatorial_map(),darts.begin(),darts.end(),Predicate::swap_orientation): + Volume_import_modifier(combinatorial_map(),darts.begin(),darts.end()); + + Polyhedron* new_poly=new Polyhedron(); + new_poly->delegate(modifier); + Scene_polyhedron_item* new_item = new Scene_polyhedron_item(new_poly); + new_item->setName(name); + last_known_scene->addItem(new_item); } - - if (!darts.empty()) - { - Volume_import_modifier modifier=Predicate::swap_orientation? - Volume_import_modifier(combinatorial_map(),darts.begin(),darts.end(),Predicate::swap_orientation): - Volume_import_modifier(combinatorial_map(),darts.begin(),darts.end()); - - Polyhedron* new_poly=new Polyhedron(); - new_poly->delegate(modifier); - Scene_polyhedron_item* new_item = new Scene_polyhedron_item(new_poly); - new_item->setName(name); - last_known_scene->addItem(new_item); - } } struct Select_volume{ - static const bool only_one_run=true; - static const bool swap_orientation=false; - Select_volume(std::size_t i):volume_to_select(i),index(0){} - template - bool operator() (Dart_handle){ - return ++index==volume_to_select; - } + static const bool only_one_run=true; + static const bool swap_orientation=false; + Select_volume(std::size_t i):volume_to_select(i),index(0){} + template + bool operator() (Dart_handle){ + return ++index==volume_to_select; + } private: - std::size_t volume_to_select; - std::size_t index; + std::size_t volume_to_select; + std::size_t index; }; void Scene_combinatorial_map_item::export_current_volume_as_polyhedron() const { - if (volume_to_display==0) return; //no volume selected - - Select_volume predicate(volume_to_display); - export_as_polyhedron(predicate,QString("%1_%2").arg(this->name()).arg(volume_to_display-1)); + if (volume_to_display==0) return; //no volume selected + + Select_volume predicate(volume_to_display); + export_as_polyhedron(predicate,QString("%1_%2").arg(this->name()).arg(volume_to_display-1)); } struct Select_union{ - static const bool only_one_run=false; - static const bool swap_orientation=true; - template - bool operator() (Dart_handle d){ return d->template attribute<3>()->info().outside.size()==2; } + static const bool only_one_run=false; + static const bool swap_orientation=true; + template + bool operator() (Dart_handle d){ return d->template attribute<3>()->info().outside.size()==2; } }; struct Select_inter{ - static const bool only_one_run=false; - static const bool swap_orientation=false; - template - bool operator() (Dart_handle d){ return d->template attribute<3>()->info().inside.size()==2; } + static const bool only_one_run=false; + static const bool swap_orientation=false; + template + bool operator() (Dart_handle d){ return d->template attribute<3>()->info().inside.size()==2; } }; struct Select_A_minus_B{ - static const bool only_one_run=false; - static const bool swap_orientation=false; - Select_A_minus_B(void* address):address_of_A(address){} - template - bool operator() (Dart_handle d){ - return d->template attribute<3>()->info().inside.size()==1 && - static_cast(*d->template attribute<3>()->info().inside.begin())==address_of_A; - } + static const bool only_one_run=false; + static const bool swap_orientation=false; + Select_A_minus_B(void* address):address_of_A(address){} + template + bool operator() (Dart_handle d){ + return d->template attribute<3>()->info().inside.size()==1 && + static_cast(*d->template attribute<3>()->info().inside.begin())==address_of_A; + } private: - void* address_of_A; + void* address_of_A; }; struct Select_B_minus_A{ - static const bool only_one_run=false; - static const bool swap_orientation=false; - Select_B_minus_A(void* address):address_of_A(address){} - template - bool operator() (Dart_handle d){ - return d->template attribute<3>()->info().inside.size()==1 && - static_cast(*d->template attribute<3>()->info().inside.begin())!=address_of_A; - } + static const bool only_one_run=false; + static const bool swap_orientation=false; + Select_B_minus_A(void* address):address_of_A(address){} + template + bool operator() (Dart_handle d){ + return d->template attribute<3>()->info().inside.size()==1 && + static_cast(*d->template attribute<3>()->info().inside.begin())!=address_of_A; + } private: - void* address_of_A; + void* address_of_A; }; void Scene_combinatorial_map_item::export_union_as_polyhedron() const { - export_as_polyhedron(Select_union(),QString("%1_union_%2").arg("A").arg("B")); + export_as_polyhedron(Select_union(),QString("%1_union_%2").arg("A").arg("B")); } void Scene_combinatorial_map_item::export_intersection_as_polyhedron() const{ - export_as_polyhedron(Select_inter(),QString("%1_inter_%2").arg("A").arg("B")); + export_as_polyhedron(Select_inter(),QString("%1_inter_%2").arg("A").arg("B")); } void Scene_combinatorial_map_item::export_A_minus_B_as_polyhedron() const{ - Select_A_minus_B predicate(address_of_A); - export_as_polyhedron(predicate,QString("%1_minus_%2").arg("A").arg("B")); + Select_A_minus_B predicate(address_of_A); + export_as_polyhedron(predicate,QString("%1_minus_%2").arg("A").arg("B")); } void Scene_combinatorial_map_item::export_B_minus_A_as_polyhedron() const{ - Select_B_minus_A predicate(address_of_A); - export_as_polyhedron(predicate,QString("%1_minus_%2").arg("B").arg("A")); + Select_B_minus_A predicate(address_of_A); + export_as_polyhedron(predicate,QString("%1_minus_%2").arg("B").arg("A")); } QMenu* Scene_combinatorial_map_item::contextMenu() { - const char* prop_name = "Menu modified by Scene_combinatorial_map_item."; + const char* prop_name = "Menu modified by Scene_combinatorial_map_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) { - QAction* actionSelectNextVolume = - menu->addAction(tr("Iterate over volumes")); - actionSelectNextVolume->setObjectName("actionSelectNextVolume"); - connect(actionSelectNextVolume, SIGNAL(triggered()),this, SLOT(set_next_volume())); + if(!menuChanged) { + QAction* actionSelectNextVolume = + menu->addAction(tr("Iterate over volumes")); + actionSelectNextVolume->setObjectName("actionSelectNextVolume"); + connect(actionSelectNextVolume, SIGNAL(triggered()),this, SLOT(set_next_volume())); - exportSelectedVolume = - menu->addAction(tr("Export current volume as polyhedron")); - exportSelectedVolume->setObjectName("exportSelectedVolume"); - connect(exportSelectedVolume, SIGNAL(triggered()),this, SLOT(export_current_volume_as_polyhedron())); - exportSelectedVolume->setEnabled(volume_to_display!=0); - menu->setProperty(prop_name, true); - - if(is_from_corefinement()){ - //Export union as polyhedron - QAction* exportUnion = - menu->addAction(tr("Export union as polyhedron")); - exportUnion->setObjectName("exportUnion"); - connect(exportUnion, SIGNAL(triggered()),this, SLOT(export_union_as_polyhedron())); + exportSelectedVolume = + menu->addAction(tr("Export current volume as polyhedron")); + exportSelectedVolume->setObjectName("exportSelectedVolume"); + connect(exportSelectedVolume, SIGNAL(triggered()),this, SLOT(export_current_volume_as_polyhedron())); + exportSelectedVolume->setEnabled(volume_to_display!=0); + menu->setProperty(prop_name, true); - //Export intersection as polyhedron - QAction* exportIntersection = - menu->addAction(tr("Export intersection as polyhedron")); - exportIntersection->setObjectName("exportIntersection"); - connect(exportIntersection, SIGNAL(triggered()),this, SLOT(export_intersection_as_polyhedron())); + if(is_from_corefinement()){ + //Export union as polyhedron + QAction* exportUnion = + menu->addAction(tr("Export union as polyhedron")); + exportUnion->setObjectName("exportUnion"); + connect(exportUnion, SIGNAL(triggered()),this, SLOT(export_union_as_polyhedron())); - //Export A minus B as polyhedron - QAction* exportAMinusB = - menu->addAction(tr("Export A minus B as polyhedron")); - exportAMinusB->setObjectName("exportAMinusB"); - connect(exportAMinusB, SIGNAL(triggered()),this, SLOT(export_A_minus_B_as_polyhedron())); + //Export intersection as polyhedron + QAction* exportIntersection = + menu->addAction(tr("Export intersection as polyhedron")); + exportIntersection->setObjectName("exportIntersection"); + connect(exportIntersection, SIGNAL(triggered()),this, SLOT(export_intersection_as_polyhedron())); - //Export B minus A as polyhedron - QAction* exportBMinusA = - menu->addAction(tr("Export B minus A as polyhedron")); - exportBMinusA->setObjectName("exportBMinusA"); - connect(exportBMinusA, SIGNAL(triggered()),this, SLOT(export_B_minus_A_as_polyhedron())); - + //Export A minus B as polyhedron + QAction* exportAMinusB = + menu->addAction(tr("Export A minus B as polyhedron")); + exportAMinusB->setObjectName("exportAMinusB"); + connect(exportAMinusB, SIGNAL(triggered()),this, SLOT(export_A_minus_B_as_polyhedron())); + + //Export B minus A as polyhedron + QAction* exportBMinusA = + menu->addAction(tr("Export B minus A as polyhedron")); + exportBMinusA->setObjectName("exportBMinusA"); + connect(exportBMinusA, SIGNAL(triggered()),this, SLOT(export_B_minus_A_as_polyhedron())); + + } } - } - return menu; + return menu; } bool Scene_combinatorial_map_item::keyPressEvent(QKeyEvent* e){ - if (e->key()==Qt::Key_N){ - set_next_volume(); - return true; - } - return false; + if (e->key()==Qt::Key_N){ + set_next_volume(); + return true; + } + return false; } void Scene_combinatorial_map_item::direct_draw() const { - #if 0 - typedef Combinatorial_map_3::One_dart_per_cell_const_range<3> Volume_dart_range; - typedef Combinatorial_map_3::One_dart_per_incident_cell_const_range<2,3> Facet_in_volume_drange; - typedef Combinatorial_map_3::Dart_of_orbit_const_range<1> Dart_in_facet_range; - Volume_dart_range dart_per_volume_range = combinatorial_map().one_dart_per_cell<3>(); - - std::size_t index = 0; - for (Volume_dart_range::const_iterator vit=dart_per_volume_range.begin();vit!=dart_per_volume_range.end();++vit) - { - if (++index!=volume_to_display && volume_to_display!=0) continue; - Facet_in_volume_drange facet_range=combinatorial_map().one_dart_per_incident_cell<2,3>(vit); - - for(Facet_in_volume_drange::const_iterator fit=facet_range.begin();fit!=facet_range.end();++fit){ - Dart_in_facet_range vertices=combinatorial_map().darts_of_orbit<1>(fit); - Kernel::Vector_3 normal = compute_face_normal(fit); - - ::glBegin(GL_POLYGON); - ::glNormal3d(normal.x(),normal.y(),normal.z()); - - for (Dart_in_facet_range::const_iterator pit=vertices.begin();pit!=vertices.end();++pit ){ - const Kernel::Point_3& p= pit->attribute<0>()->point(); - ::glVertex3d(p.x(),p.y(),p.z()); - } - ::glEnd(); - } - } - #else - std::size_t index = 0; - int voltreated = combinatorial_map().get_new_mark(); - int facetreated = combinatorial_map().get_new_mark(); - Combinatorial_map_3::Dart_const_range::const_iterator - darts_it=combinatorial_map().darts().begin(), darts_end=combinatorial_map().darts().end(); - for( ; darts_it!=darts_end; ++darts_it) - { - if ( !combinatorial_map().is_marked(darts_it,voltreated) ) +#if 0 + typedef Combinatorial_map_3::One_dart_per_cell_const_range<3> Volume_dart_range; + typedef Combinatorial_map_3::One_dart_per_incident_cell_const_range<2,3> Facet_in_volume_drange; + typedef Combinatorial_map_3::Dart_of_orbit_const_range<1> Dart_in_facet_range; + Volume_dart_range dart_per_volume_range = combinatorial_map().one_dart_per_cell<3>(); + std::cout<<"COUCOU"<::const_iterator - vol_it=combinatorial_map().darts_of_cell<3>(darts_it).begin(), - vol_end=combinatorial_map().darts_of_cell<3>(darts_it).end(); - if ( volume_to_display!=0 && index!=volume_to_display ) - { - //only mark darts if the volume is not the one to display - for ( ;vol_it!=vol_end; ++vol_it ) - { - combinatorial_map().mark(vol_it,facetreated); - combinatorial_map().mark(vol_it, voltreated); - } - } - else - { - for ( ;vol_it!=vol_end; ++vol_it ) - { - if ( !combinatorial_map().is_marked(vol_it,facetreated) ) - { - Kernel::Vector_3 normal = compute_face_normal(vol_it); + if (++index!=volume_to_display && volume_to_display!=0) continue; + Facet_in_volume_drange facet_range=combinatorial_map().one_dart_per_incident_cell<2,3>(vit); + + for(Facet_in_volume_drange::const_iterator fit=facet_range.begin();fit!=facet_range.end();++fit){ + Dart_in_facet_range vertices=combinatorial_map().darts_of_orbit<1>(fit); + Kernel::Vector_3 normal = compute_face_normal(fit); + ::glBegin(GL_POLYGON); ::glNormal3d(normal.x(),normal.y(),normal.z()); - //iterate over all darts of facets - for ( Combinatorial_map_3::Dart_of_orbit_const_range<1>::const_iterator - face_it=combinatorial_map().darts_of_orbit<1>(vol_it).begin(), - face_end=combinatorial_map().darts_of_orbit<1>(vol_it).end(); - face_it!=face_end; ++face_it) - { - const Kernel::Point_3& p= face_it->attribute<0>()->point(); - ::glVertex3d(p.x(),p.y(),p.z()); - combinatorial_map().mark(face_it,facetreated); - combinatorial_map().mark(face_it, voltreated); + for (Dart_in_facet_range::const_iterator pit=vertices.begin();pit!=vertices.end();++pit ){ + const Kernel::Point_3& p= pit->attribute<0>()->point(); + ::glVertex3d(p.x(),p.y(),p.z()); } ::glEnd(); - } } - } - if ( index==volume_to_display ) break; } - } - //mark remaining darts to have an O(1) free_mark - for( ; darts_it!=darts_end; ++darts_it) - { - combinatorial_map().mark(darts_it, facetreated); - combinatorial_map().mark(darts_it, voltreated); - } +#else + std::size_t index = 0; + int voltreated = combinatorial_map().get_new_mark(); + int facetreated = combinatorial_map().get_new_mark(); + Combinatorial_map_3::Dart_const_range::const_iterator + darts_it=combinatorial_map().darts().begin(), darts_end=combinatorial_map().darts().end(); + for( ; darts_it!=darts_end; ++darts_it) + { + if ( !combinatorial_map().is_marked(darts_it,voltreated) ) + { + ++index; + //iterate over all the darts of the volume + Combinatorial_map_3::Dart_of_cell_const_range<3>::const_iterator + vol_it=combinatorial_map().darts_of_cell<3>(darts_it).begin(), + vol_end=combinatorial_map().darts_of_cell<3>(darts_it).end(); + if ( volume_to_display!=0 && index!=volume_to_display ) + { + //only mark darts if the volume is not the one to display + for ( ;vol_it!=vol_end; ++vol_it ) + { + combinatorial_map().mark(vol_it,facetreated); + combinatorial_map().mark(vol_it, voltreated); + } + } + else + { + for ( ;vol_it!=vol_end; ++vol_it ) + { + if ( !combinatorial_map().is_marked(vol_it,facetreated) ) + { + Kernel::Vector_3 normal = compute_face_normal(vol_it); + ::glBegin(GL_POLYGON); + ::glNormal3d(normal.x(),normal.y(),normal.z()); - combinatorial_map().free_mark(facetreated); - combinatorial_map().free_mark(voltreated); - #endif + //iterate over all darts of facets + for ( Combinatorial_map_3::Dart_of_orbit_const_range<1>::const_iterator + face_it=combinatorial_map().darts_of_orbit<1>(vol_it).begin(), + face_end=combinatorial_map().darts_of_orbit<1>(vol_it).end(); + face_it!=face_end; ++face_it) + { + const Kernel::Point_3& p= face_it->attribute<0>()->point(); + ::glVertex3d(p.x(),p.y(),p.z()); + combinatorial_map().mark(face_it,facetreated); + combinatorial_map().mark(face_it, voltreated); + } + ::glEnd(); + } + } + } + if ( index==volume_to_display ) break; + } + } + //mark remaining darts to have an O(1) free_mark + for( ; darts_it!=darts_end; ++darts_it) + { + combinatorial_map().mark(darts_it, facetreated); + combinatorial_map().mark(darts_it, voltreated); + } + + combinatorial_map().free_mark(facetreated); + combinatorial_map().free_mark(voltreated); +#endif } void Scene_combinatorial_map_item::direct_draw_edges() const { - typedef Combinatorial_map_3::One_dart_per_cell_const_range<1> Edge_darts; - Edge_darts darts=combinatorial_map().one_dart_per_cell<1>(); - ::glBegin(GL_LINES); - for (Edge_darts::const_iterator dit=darts.begin();dit!=darts.end();++dit){ - CGAL_assertion(!dit->is_free(1)); - const Kernel::Point_3& a = dit->attribute<0>()->point(); - const Kernel::Point_3& b = dit->beta(1)->attribute<0>()->point(); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - } - ::glEnd(); + typedef Combinatorial_map_3::One_dart_per_cell_const_range<1> Edge_darts; + Edge_darts darts=combinatorial_map().one_dart_per_cell<1>(); + ::glBegin(GL_LINES); + for (Edge_darts::const_iterator dit=darts.begin();dit!=darts.end();++dit){ + CGAL_assertion(!dit->is_free(1)); + const Kernel::Point_3& a = dit->attribute<0>()->point(); + const Kernel::Point_3& b = dit->beta(1)->attribute<0>()->point(); + ::glVertex3d(a.x(),a.y(),a.z()); + ::glVertex3d(b.x(),b.y(),b.z()); + } + ::glEnd(); } void Scene_combinatorial_map_item::draw_points() const{ - typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range; - const Point_range& points=combinatorial_map().attributes<0>(); - ::glBegin(GL_POINTS); - for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit){ - const Kernel::Point_3& p=pit->point(); - ::glVertex3d(p.x(),p.y(),p.z()); - } - ::glEnd(); + typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range; + const Point_range& points=combinatorial_map().attributes<0>(); + ::glBegin(GL_POINTS); + for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit){ + const Kernel::Point_3& p=pit->point(); + ::glVertex3d(p.x(),p.y(),p.z()); + } + ::glEnd(); } bool Scene_combinatorial_map_item::isEmpty() const {return combinatorial_map().number_of_darts()==0;} Scene_combinatorial_map_item::Bbox Scene_combinatorial_map_item::bbox() const { - typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range; - const Point_range& points=combinatorial_map().attributes<0>(); - CGAL::Bbox_3 bbox=points.begin()->point().bbox(); - for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit) - bbox=bbox+pit->point().bbox(); - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range; + const Point_range& points=combinatorial_map().attributes<0>(); + CGAL::Bbox_3 bbox=points.begin()->point().bbox(); + for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit) + bbox=bbox+pit->point().bbox(); + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); } QString Scene_combinatorial_map_item::toolTip() const{ - if(!m_combinatorial_map) - return QString(); + if(!m_combinatorial_map) + return QString(); - std::vector cells(5); - for (unsigned int i=0; i<=4; ++i) - cells[i]=i; - std::vector res = combinatorial_map().count_cells(cells); - if (volume_to_display==0) + std::vector cells(5); + for (unsigned int i=0; i<=4; ++i) + cells[i]=i; + std::vector res = combinatorial_map().count_cells(cells); + if (volume_to_display==0) + return QObject::tr("

Combinatorial_map_3 %1 (mode: %8, color: %9)

" + "

Number of darts: %2
" + "Number of vertices: %3
" + "Number of edges: %4
" + "Number of facets: %5
" + "Number of volumes: %6
" + "Number of connected components: %7

") + .arg(this->name()) + .arg(combinatorial_map().number_of_darts()) + .arg(res[0]) + .arg(res[1]) + .arg(res[2]) + .arg(res[3]) + .arg(res[4]) + .arg(this->renderingModeName()) + .arg(this->color().name()); return QObject::tr("

Combinatorial_map_3 %1 (mode: %8, color: %9)

" "

Number of darts: %2
" "Number of vertices: %3
" "Number of edges: %4
" "Number of facets: %5
" "Number of volumes: %6
" - "Number of connected components: %7

") - .arg(this->name()) - .arg(combinatorial_map().number_of_darts()) - .arg(res[0]) - .arg(res[1]) - .arg(res[2]) - .arg(res[3]) - .arg(res[4]) - .arg(this->renderingModeName()) - .arg(this->color().name()); - return QObject::tr("

Combinatorial_map_3 %1 (mode: %8, color: %9)

" - "

Number of darts: %2
" - "Number of vertices: %3
" - "Number of edges: %4
" - "Number of facets: %5
" - "Number of volumes: %6
" - "Number of connected components: %7
" - "Currently Displaying facets of volume: %10

") - .arg(this->name()) - .arg(combinatorial_map().number_of_darts()) - .arg(res[0]) - .arg(res[1]) - .arg(res[2]) - .arg(res[3]) - .arg(res[4]) - .arg(this->renderingModeName()) - .arg(this->color().name()) - .arg(volume_to_display-1); + "Number of connected components: %7
" + "Currently Displaying facets of volume: %10

") + .arg(this->name()) + .arg(combinatorial_map().number_of_darts()) + .arg(res[0]) + .arg(res[1]) + .arg(res[2]) + .arg(res[3]) + .arg(res[4]) + .arg(this->renderingModeName()) + .arg(this->color().name()) + .arg(volume_to_display-1); } diff --git a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h index ff32997689e..c6d974031c9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h @@ -6,7 +6,9 @@ #include "Scene_combinatorial_map_item_config.h" #include "Scene_item_with_display_list.h" #include - +#include +#include +#include #include "Polyhedron_type.h" typedef CGAL::internal_IOP::Item_with_points_and_volume_info Items; @@ -19,64 +21,81 @@ class Scene_interface; class Scene_polyhedron_item; class SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Scene_combinatorial_map_item - : public Scene_item_with_display_list + : public Scene_item_with_display_list { - Q_OBJECT + Q_OBJECT public: - Scene_combinatorial_map_item(Scene_interface*,void* ad_A=NULL); - ~Scene_combinatorial_map_item(); + Scene_combinatorial_map_item(Scene_interface*,void* ad_A=NULL); + ~Scene_combinatorial_map_item(); - Scene_combinatorial_map_item* clone() const; - // Function to override the context menu - QMenu* contextMenu(); + Scene_combinatorial_map_item* clone() const; + // Function to override the context menu + QMenu* contextMenu(); -// bool load(std::istream& in); -// void load(Scene_polyhedron_item*); -// bool save(std::ostream& out) const; + // bool load(std::istream& in); + // void load(Scene_polyhedron_item*); + // bool save(std::ostream& out) const; - QString toolTip() const; + QString toolTip() const; - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! - //Event handling - virtual bool keyPressEvent(QKeyEvent*); - // OpenGL drawing in a display list - void direct_draw() const; - void direct_draw_edges() const; - void draw_points() const; + // Indicate if rendering mode is supported + virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! + //Event handling + virtual bool keyPressEvent(QKeyEvent*); + // OpenGL drawing in a display list + void direct_draw() const; + void direct_draw_edges() const; + void draw_points() const; - bool isFinite() const { return true; } - bool is_from_corefinement() const {return address_of_A!=NULL;} - bool isEmpty() const; - Bbox bbox() const; - - const Combinatorial_map_3& combinatorial_map() const - { - return *m_combinatorial_map; - } + bool isFinite() const { return true; } + bool is_from_corefinement() const {return address_of_A!=NULL;} + bool isEmpty() const; + Bbox bbox() const; + + const Combinatorial_map_3& combinatorial_map() const + { + return *m_combinatorial_map; + } + + Combinatorial_map_3& combinatorial_map() + { + return *m_combinatorial_map; + } + + Combinatorial_map_3* m_combinatorial_map; - Combinatorial_map_3& combinatorial_map() - { - return *m_combinatorial_map; - } - - Combinatorial_map_3* m_combinatorial_map; - private: - Kernel::Vector_3 compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const; - Scene_interface* last_known_scene; - std::size_t volume_to_display; - QAction* exportSelectedVolume; - void* address_of_A; - template void export_as_polyhedron(Predicate,const QString&) const; + Kernel::Vector_3 compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const; + Scene_interface* last_known_scene; + std::size_t volume_to_display; + QAction* exportSelectedVolume; + void* address_of_A; + template void export_as_polyhedron(Predicate,const QString&) const; + + std::vector positions; + std::vector normals; + std::vector color_lines; + std::vector color_facets; + + QGLShaderProgram *rendering_program; + GLint location[9]; + + GLuint vao; + QGLBuffer buffer[5]; + void initialize_buffers(); + void compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*, int) const; + void compute_colors(); public slots: - void set_next_volume(); - void export_current_volume_as_polyhedron() const; - void export_union_as_polyhedron() const; - void export_intersection_as_polyhedron() const; - void export_A_minus_B_as_polyhedron() const; - void export_B_minus_A_as_polyhedron() const; + void set_next_volume(); + void export_current_volume_as_polyhedron() const; + void export_union_as_polyhedron() const; + void export_intersection_as_polyhedron() const; + void export_A_minus_B_as_polyhedron() const; + void export_B_minus_A_as_polyhedron() const; + }; // end class Scene_combinatorial_map_item #endif // SCENE_COMBINATORIAL_MAP_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index d211b0791cb..66f84c731f9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -126,7 +126,7 @@ Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(const Nef_polyhedron& p) Scene_nef_polyhedron_item::~Scene_nef_polyhedron_item() { - glDeleteBuffers(6, buffer); + glDeleteBuffers(7, buffer); glDeleteVertexArrays(1, vao); glDeleteProgram(rendering_program_facets); glDeleteProgram(rendering_program_lines); diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h index 024eea69a0b..e4d36ffea2b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h @@ -95,7 +95,7 @@ private: void compile_shaders(void); void compute_normals_and_vertices(void); void uniform_attrib(Viewer_interface*, int) const; - void compute_colors(); + void triangulate_facet(); void triangulate_facet_color(); }; // end class Scene_nef_polyhedron_item diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 4f23b13a9d5..be5b190326f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -9,6 +9,7 @@ #include #include +#include "Viewer_interface.h" #include #include @@ -22,331 +23,771 @@ Scene_points_with_normal_item::Scene_points_with_normal_item() - : Scene_item_with_display_list(), - m_points(new Point_set), - m_has_normals(false) + : Scene_item_with_display_list(), + m_points(new Point_set), + positions_lines(0), + color_lines(0), + color_points(0), + positions_points(0), + m_has_normals(false) { - setRenderingMode(Points); + setRenderingMode(Points); + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); } // Copy constructor Scene_points_with_normal_item::Scene_points_with_normal_item(const Scene_points_with_normal_item& toCopy) - : Scene_item_with_display_list(), // do not call superclass' copy constructor - m_points(new Point_set(*toCopy.m_points)), - m_has_normals(toCopy.m_has_normals) + : Scene_item_with_display_list(), // do not call superclass' copy constructor + m_points(new Point_set(*toCopy.m_points)), + positions_lines(0), + color_lines(0), + color_points(0), + positions_points(0), + m_has_normals(toCopy.m_has_normals) { - if (m_has_normals) - setRenderingMode(PointsPlusNormals); - else - setRenderingMode(Points); + if (m_has_normals) + { + setRenderingMode(PointsPlusNormals); + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); + } + else + { + setRenderingMode(Points); + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); + } } // Converts polyhedron to point set Scene_points_with_normal_item::Scene_points_with_normal_item(const Polyhedron& input_mesh) - : Scene_item_with_display_list(), - m_points(new Point_set), - m_has_normals(true) + : Scene_item_with_display_list(), + m_points(new Point_set), + positions_lines(0), + color_lines(0), + color_points(0), + positions_points(0), + m_has_normals(true) { - // Converts Polyhedron vertices to point set. - // Computes vertices normal from connectivity. - Polyhedron::Vertex_const_iterator v; - for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) - { - const Kernel::Point_3& p = v->point(); - Kernel::Vector_3 n = compute_vertex_normal(*v); - m_points->push_back(UI_point(p,n)); - } + // Converts Polyhedron vertices to point set. + // Computes vertices normal from connectivity. + Polyhedron::Vertex_const_iterator v; + for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) + { + const Kernel::Point_3& p = v->point(); + Kernel::Vector_3 n = compute_vertex_normal(*v); + m_points->push_back(UI_point(p,n)); + } - setRenderingMode(PointsPlusNormals); + setRenderingMode(PointsPlusNormals); + is_selected = true; + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); } Scene_points_with_normal_item::~Scene_points_with_normal_item() { - Q_ASSERT(m_points != NULL); - delete m_points; m_points = NULL; + Q_ASSERT(m_points != NULL); + glDeleteBuffers(7, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_points); + delete m_points; m_points = NULL; } + + +void Scene_points_with_normal_item::initialize_buffers() +{ + glBindVertexArray(vao[0]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_lines.size())*sizeof(double), + positions_lines.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(0, //number of the buffer + 3, //number of floats to be taken + GL_DOUBLE, // 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, + (color_lines.size())*sizeof(double), + color_lines.data(), GL_STATIC_DRAW); + glVertexAttribPointer(1, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); + glBufferData(GL_ARRAY_BUFFER, + (positions_points.size())*sizeof(double), + positions_points.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[3]); + glBufferData(GL_ARRAY_BUFFER, + (color_points.size())*sizeof(double), + color_points.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + glBindVertexArray(vao[1]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glBufferData(GL_ARRAY_BUFFER, + (positions_selected_points.size())*sizeof(double), + positions_selected_points.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(2, //number of the buffer + 3, //number of floats to be taken + GL_DOUBLE, // 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[5]); + glBufferData(GL_ARRAY_BUFFER, + (color_selected_points.size())*sizeof(double), + color_selected_points.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + + // Clean-up + glBindVertexArray(0); +} +void Scene_points_with_normal_item::compile_shaders(void) +{ + //fill the vertex shader + //For the edges + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec3 positions; \n" + "layout (location = 1) in vec3 color_lines; \n" + + "uniform mat4 mvp_matrix; \n" + + "out highp vec3 fColors; \n" + "vec4 positions_lines = vec4(positions, 1.0); \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color_lines; \n" + " gl_Position = mvp_matrix * positions_lines; \n" + "} \n" + }; + //fill the fragment shader + static const GLchar* fragment_shader_source[]= + { + "#version 300 es \n" + " \n" + "precision mediump float; \n" + "in vec3 fColors; \n" + + "out 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_lines, 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); + + //Clean-up + glDeleteShader(vertex_shader); + + rendering_program_lines = program; + + + //For the points + static const GLchar* vertex_shader_source_points[] = + { + "#version 300 es \n" + " \n" + "layout (location = 2) in vec3 positions; \n" + "layout (location = 3) in vec3 color; \n" + "uniform mat4 mvp_matrix; \n" + + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color; \n" + " gl_Position = mvp_matrix * vec4(positions, 1.0); \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); + //Clean-up + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + rendering_program_points = program; +} +void Scene_points_with_normal_item::compute_normals_and_vertices(void) +{ + positions_points.clear(); + positions_lines.clear(); + color_points.clear(); + color_lines.clear(); + + //The points + { + // The *non-selected* points + if (m_points->nb_selected_points()< m_points->size()) + { + + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + if ( ! p.is_selected() ) + { + positions_points.push_back(p.x()); + positions_points.push_back(p.y()); + positions_points.push_back(p.z()); + + if(is_selected) + { + color_points.push_back(this->color().lighter(120).redF()); + color_points.push_back(this->color().lighter(120).greenF()); + color_points.push_back(this->color().lighter(120).blueF()); + } + else + { + color_points.push_back(this->color().redF()); + color_points.push_back(this->color().greenF()); + color_points.push_back(this->color().blueF()); + } + + } + } + + } + + // Draw *selected* points + if (m_points->nb_selected_points() > 0) + { + ::glPointSize(4.f); // selected => bigger + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + if (p.is_selected()) + { + positions_selected_points.push_back(p.x()); + positions_selected_points.push_back(p.y()); + positions_selected_points.push_back(p.z()); + + color_selected_points.push_back(1.0); + color_selected_points.push_back(0.0); + color_selected_points.push_back(0.0); + + } + } + + } + } + + //The lines + { + // Stock normals + Kernel::Sphere_3 region_of_interest = m_points->region_of_interest(); + float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.); + + // Stock normals of *non-selected* points + if (m_points->nb_selected_points() < m_points->size()) + { + // Stock normals + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + const Point_set_3::Vector& n = p.normal(); + if (!p.is_selected()) + { + Point_set_3::Point q = p + normal_length * n; + positions_lines.push_back(p.x()); + positions_lines.push_back(p.y()); + positions_lines.push_back(p.z()); + + positions_lines.push_back(q.x()); + positions_lines.push_back(q.y()); + positions_lines.push_back(q.z()); + + if(is_selected) + { + color_lines.push_back(this->color().lighter(120).redF()); + color_lines.push_back(this->color().lighter(120).greenF()); + color_lines.push_back(this->color().lighter(120).blueF()); + + color_lines.push_back(this->color().lighter(120).redF()); + color_lines.push_back(this->color().lighter(120).greenF()); + color_lines.push_back(this->color().lighter(120).blueF()); + } + else + { + color_lines.push_back(this->color().redF()); + color_lines.push_back(this->color().greenF()); + color_lines.push_back(this->color().blueF()); + + color_lines.push_back(this->color().redF()); + color_lines.push_back(this->color().greenF()); + color_lines.push_back(this->color().blueF()); + } + } + } + } + + // Stock normals of *selected* points + if (m_points->nb_selected_points() > 0) + { + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + const Point_set_3::Vector& n = p.normal(); + if (p.is_selected()) + { + Point_set_3::Point q = p + normal_length * n; + positions_lines.push_back(p.x()); + positions_lines.push_back(p.y()); + positions_lines.push_back(p.z()); + + positions_lines.push_back(q.x()); + positions_lines.push_back(q.y()); + positions_lines.push_back(q.z()); + + 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); + } + } + } + } + location[0] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_points, "mvp_matrix"); +} +void Scene_points_with_normal_item::uniform_attrib(Viewer_interface* viewer, int mode) const +{ + GLfloat mvp_mat[16]; + + //fills the MVP matrix. + + 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]); + } + + if(mode ==0) + { + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + } + else if(mode ==1) + { + glUseProgram(rendering_program_points); + glUniformMatrix4fv(location[1], 1, GL_FALSE, mvp_mat); + } +} + + // Duplicates scene item Scene_points_with_normal_item* Scene_points_with_normal_item::clone() const { - return new Scene_points_with_normal_item(*this); + return new Scene_points_with_normal_item(*this); } // Is selection empty? bool Scene_points_with_normal_item::isSelectionEmpty() const { - return (m_points->nb_selected_points() == 0); + return (m_points->nb_selected_points() == 0); } // Delete selection void Scene_points_with_normal_item::deleteSelection() { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Delete " << m_points->nb_selected_points() << " points..."; + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Delete " << m_points->nb_selected_points() << " points..."; - // Delete selected points - m_points->delete_selection(); + // Delete selected points + m_points->delete_selection(); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "done: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - emit itemChanged(); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "done: " << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated" + << std::endl; + emit itemChanged(); } // Reset selection mark void Scene_points_with_normal_item::resetSelection() { - // Un-select all points - m_points->select(m_points->begin(), m_points->end(), false); - emit itemChanged(); + // Un-select all points + m_points->select(m_points->begin(), m_points->end(), false); + emit itemChanged(); } - //Select duplicated points +//Select duplicated points void Scene_points_with_normal_item::selectDuplicates() { - std::set unique_points; - for (Point_set::Point_iterator ptit=m_points->begin(); ptit!=m_points->end();++ptit ) - if ( !unique_points.insert(*ptit).second ) - m_points->select(&(*ptit)); - emit itemChanged(); + std::set unique_points; + for (Point_set::Point_iterator ptit=m_points->begin(); ptit!=m_points->end();++ptit ) + if ( !unique_points.insert(*ptit).second ) + m_points->select(&(*ptit)); + emit itemChanged(); } // Loads point set from .OFF file bool Scene_points_with_normal_item::read_off_point_set(std::istream& stream) { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - m_points->clear(); - bool ok = stream && + m_points->clear(); + bool ok = stream && CGAL::read_off_points_and_normals(stream, std::back_inserter(*m_points), CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())) && !isEmpty(); - return ok; + return ok; } // Write point set to .OFF file bool Scene_points_with_normal_item::write_off_point_set(std::ostream& stream) const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - return stream && - CGAL::write_off_points_and_normals(stream, - m_points->begin(), m_points->end(), - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())); + return stream && + CGAL::write_off_points_and_normals(stream, + m_points->begin(), m_points->end(), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())); } // Loads point set from .XYZ file bool Scene_points_with_normal_item::read_xyz_point_set(std::istream& stream) { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - m_points->clear(); - bool ok = stream && + m_points->clear(); + bool ok = stream && CGAL::read_xyz_points_and_normals(stream, std::back_inserter(*m_points), CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())) && !isEmpty(); - if (ok) - { - for (Point_set::iterator it=m_points->begin(), - end=m_points->end();it!=end; ++it) + if (ok) { - if (it->normal() != CGAL::NULL_VECTOR) - { - m_has_normals=true; - setRenderingMode(PointsPlusNormals); - break; - } + for (Point_set::iterator it=m_points->begin(), + end=m_points->end();it!=end; ++it) + { + if (it->normal() != CGAL::NULL_VECTOR) + { + m_has_normals=true; + setRenderingMode(PointsPlusNormals); + break; + } + } } - } - return ok; + return ok; } // Write point set to .XYZ file bool Scene_points_with_normal_item::write_xyz_point_set(std::ostream& stream) const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - return stream && - CGAL::write_xyz_points_and_normals(stream, - m_points->begin(), m_points->end(), - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())); + return stream && + CGAL::write_xyz_points_and_normals(stream, + m_points->begin(), m_points->end(), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())); } QString Scene_points_with_normal_item::toolTip() const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - return QObject::tr("

%1 (color: %4)
" - "Point set

" - "

Number of points: %2

") - .arg(name()) - .arg(m_points->size()) - .arg(color().name()); + return QObject::tr("

%1 (color: %4)
" + "Point set

" + "

Number of points: %2

") + .arg(name()) + .arg(m_points->size()) + .arg(color().name()); } bool Scene_points_with_normal_item::supportsRenderingMode(RenderingMode m) const { - return m==Points || - ( has_normals() && - ( m==PointsPlusNormals || m==Splatting ) ); + return m==Points || + ( has_normals() && + ( m==PointsPlusNormals || m==Splatting ) ); } // Points OpenGL drawing in a display list void Scene_points_with_normal_item::direct_draw() const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - // Draw points - m_points->gl_draw_vertices(); + // Draw points + m_points->gl_draw_vertices(); } // Normals OpenGL drawing void Scene_points_with_normal_item::draw_normals() const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - // Draw normals - Kernel::Sphere_3 region_of_interest = m_points->region_of_interest(); - float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.); + // Draw normals + Kernel::Sphere_3 region_of_interest = m_points->region_of_interest(); + float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.); - m_points->gl_draw_normals(normal_length); + m_points->gl_draw_normals(normal_length); } void Scene_points_with_normal_item::draw_splats() const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - // Draw splats - bool points_have_normals = (m_points->begin() != m_points->end() && - m_points->begin()->normal() != CGAL::NULL_VECTOR); - bool points_have_radii = (m_points->begin() != m_points->end() && - m_points->begin()->radius() != 0); - if(points_have_normals && points_have_radii) - { - m_points->gl_draw_splats(); - } + // Draw splats + bool points_have_normals = (m_points->begin() != m_points->end() && + m_points->begin()->normal() != CGAL::NULL_VECTOR); + bool points_have_radii = (m_points->begin() != m_points->end() && + m_points->begin()->radius() != 0); + if(points_have_normals && points_have_radii) + { + m_points->gl_draw_splats(); + } } +void Scene_points_with_normal_item::draw_edges(Viewer_interface* viewer) const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer,0); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); +} +void Scene_points_with_normal_item::draw_points(Viewer_interface* viewer) const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer,1); + glDrawArrays(GL_POINTS, 0, positions_points.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + GLfloat point_size; + glGetFloatv(GL_POINT_SIZE, &point_size); + glPointSize(4.f); + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_points); + uniform_attrib(viewer,1); + glDrawArrays(GL_POINTS, 0, positions_selected_points.size()/3); + glUseProgram(0); + glBindVertexArray(0); + glPointSize(point_size); +} // Gets wrapped point set Point_set* Scene_points_with_normal_item::point_set() { - Q_ASSERT(m_points != NULL); - return m_points; + Q_ASSERT(m_points != NULL); + return m_points; } const Point_set* Scene_points_with_normal_item::point_set() const { - Q_ASSERT(m_points != NULL); - return m_points; + Q_ASSERT(m_points != NULL); + return m_points; } bool Scene_points_with_normal_item::isEmpty() const { - Q_ASSERT(m_points != NULL); - return m_points->empty(); + Q_ASSERT(m_points != NULL); + return m_points->empty(); } Scene_points_with_normal_item::Bbox Scene_points_with_normal_item::bbox() const { - Q_ASSERT(m_points != NULL); + Q_ASSERT(m_points != NULL); - Kernel::Iso_cuboid_3 bbox = m_points->bounding_box(); - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + Kernel::Iso_cuboid_3 bbox = m_points->bounding_box(); + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); } void Scene_points_with_normal_item::computes_local_spacing(int k) { - typedef Kernel Geom_traits; - typedef CGAL::Search_traits_3 TreeTraits; - typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef Neighbor_search::Tree Tree; + typedef Kernel Geom_traits; + typedef CGAL::Search_traits_3 TreeTraits; + typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; + typedef Neighbor_search::Tree Tree; - Point_set::iterator end(m_points->end()); + Point_set::iterator end(m_points->end()); - // build kdtree - Tree tree(m_points->begin(), end); + // build kdtree + Tree tree(m_points->begin(), end); - // Compute the radius of each point = (distance max to k nearest neighbors)/2. - { - int i=0; - for (Point_set::iterator it=m_points->begin(); it!=end; ++it, ++i) + // Compute the radius of each point = (distance max to k nearest neighbors)/2. { - Neighbor_search search(tree, *it, k+1); - double maxdist2 = (--search.end())->second; // squared distance to furthest neighbor - it->radius() = sqrt(maxdist2)/2.; + int i=0; + for (Point_set::iterator it=m_points->begin(); it!=end; ++it, ++i) + { + Neighbor_search search(tree, *it, k+1); + double maxdist2 = (--search.end())->second; // squared distance to furthest neighbor + it->radius() = sqrt(maxdist2)/2.; + } } - } - m_points->set_radii_uptodate(true); + m_points->set_radii_uptodate(true); } QMenu* Scene_points_with_normal_item::contextMenu() { - const char* prop_name = "Menu modified by Scene_points_with_normal_item."; + const char* prop_name = "Menu modified by Scene_points_with_normal_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) { - actionDeleteSelection = menu->addAction(tr("Delete Selection")); - actionDeleteSelection->setObjectName("actionDeleteSelection"); - connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection())); + if(!menuChanged) { + actionDeleteSelection = menu->addAction(tr("Delete Selection")); + actionDeleteSelection->setObjectName("actionDeleteSelection"); + connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection())); - actionResetSelection = menu->addAction(tr("Reset Selection")); - actionResetSelection->setObjectName("actionResetSelection"); - connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection())); + actionResetSelection = menu->addAction(tr("Reset Selection")); + actionResetSelection->setObjectName("actionResetSelection"); + connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection())); - actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points")); - actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints"); - connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates())); + actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points")); + actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints"); + connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates())); - menu->setProperty(prop_name, true); - } + menu->setProperty(prop_name, true); + } - if (isSelectionEmpty()) - { - actionDeleteSelection->setDisabled(true); - actionResetSelection->setDisabled(true); - } - else - { - actionDeleteSelection->setDisabled(false); - actionResetSelection->setDisabled(false); - } + if (isSelectionEmpty()) + { + actionDeleteSelection->setDisabled(true); + actionResetSelection->setDisabled(true); + } + else + { + actionDeleteSelection->setDisabled(false); + actionResetSelection->setDisabled(false); + } - return menu; + return menu; } void Scene_points_with_normal_item::setRenderingMode(RenderingMode m) { - Scene_item_with_display_list::setRenderingMode(m); - if (rendering_mode==Splatting && (!m_points->are_radii_uptodate())) - { - computes_local_spacing(6); // default value = small - } + Scene_item_with_display_list::setRenderingMode(m); + if (rendering_mode==Splatting && (!m_points->are_radii_uptodate())) + { + computes_local_spacing(6); // default value = small + } } bool Scene_points_with_normal_item::has_normals() const { return m_has_normals; } void Scene_points_with_normal_item::set_has_normals(bool b) { - if (b!=m_has_normals){ - m_has_normals=b; - //reset the context menu - delete this->defaultContextMenu; - this->defaultContextMenu = 0; - } + if (b!=m_has_normals){ + m_has_normals=b; + //reset the context menu + delete this->defaultContextMenu; + this->defaultContextMenu = 0; + } } +void Scene_points_with_normal_item::changed() +{ + + compute_normals_and_vertices(); + initialize_buffers(); +} +void Scene_points_with_normal_item::selection_changed(bool p_is_selected) +{ + if(p_is_selected != is_selected) + { + is_selected = p_is_selected; + changed(); + } +} #include "Scene_points_with_normal_item.moc" From 05fe53e652d8ba24f89ce7d638f07ffba24b6751 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Mar 2015 11:38:47 +0100 Subject: [PATCH 49/62] points_with_normal_item upgrade A classic approach, except for the splatting, that won't work until the scene class don't call a GLSplat Renderer anymore. --- Polyhedron/demo/Polyhedron/Scene.cpp | 23 +- .../Scene_points_with_normal_item.cpp | 379 ++++++++++++++---- .../Scene_points_with_normal_item.h | 34 ++ .../demo/Polyhedron/Scene_polyhedron_item.cpp | 8 +- .../Scene_textured_polyhedron_item.cpp | 3 - Polyhedron/demo/Polyhedron/Viewer.cpp | 6 +- 6 files changed, 361 insertions(+), 92 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 69bc66e05f5..9e413684374 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -420,23 +420,34 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) // Splatting if(!with_names && ms_splatting->isSupported()) { + ms_splatting->beginVisibilityPass(); for(int index = 0; index < m_entries.size(); ++index) { Scene_item& item = *m_entries[index]; if(item.visible() && item.renderingMode() == Splatting) { - item.draw_splats(); + + if(viewer) + { + item.draw_splats(viewer); + } + else + item.draw_splats(); } + } ms_splatting->beginAttributePass(); for(int index = 0; index < m_entries.size(); ++index) - { - Scene_item& item = *m_entries[index]; + { Scene_item& item = *m_entries[index]; if(item.visible() && item.renderingMode() == Splatting) { + CGALglcolor(item.color()); - item.draw_splats(); + if(viewer) + item.draw_splats(viewer); + else + item.draw_splats(); } } ms_splatting->finalize(); @@ -711,8 +722,8 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, QColor color = QColorDialog::getColor(model->data(index).value(), 0/*, - tr("Select color"), - QColorDialog::ShowAlphaChannel*/); + tr("Select color"), + QColorDialog::ShowAlphaChannel*/); if (color.isValid()) { model->setData(index, color ); } diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index be5b190326f..c38cf9be127 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -21,6 +21,20 @@ #include #include +struct light_info +{ + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; +}; Scene_points_with_normal_item::Scene_points_with_normal_item() : Scene_item_with_display_list(), @@ -29,13 +43,20 @@ Scene_points_with_normal_item::Scene_points_with_normal_item() color_lines(0), color_points(0), positions_points(0), + normals(0), + positions_splats(0), + positions_selected_points(0), + color_selected_points(0), + tex_coords(0), m_has_normals(false) { setRenderingMode(Points); is_selected = true; - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(7, buffer); + glGenBuffers(9, buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &textureId); compile_shaders(); } @@ -47,24 +68,33 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const Scene_points_ color_lines(0), color_points(0), positions_points(0), + normals(0), + positions_splats(0), + positions_selected_points(0), + color_selected_points(0), + tex_coords(0), m_has_normals(toCopy.m_has_normals) { if (m_has_normals) { setRenderingMode(PointsPlusNormals); is_selected = true; - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(7, buffer); + glGenBuffers(9, buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &textureId); compile_shaders(); } else { setRenderingMode(Points); is_selected = true; - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(7, buffer); + glGenBuffers(9, buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &textureId); compile_shaders(); } } @@ -77,6 +107,11 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const Polyhedron& i color_lines(0), color_points(0), positions_points(0), + normals(0), + positions_splats(0), + positions_selected_points(0), + color_selected_points(0), + tex_coords(0), m_has_normals(true) { // Converts Polyhedron vertices to point set. @@ -91,19 +126,22 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const Polyhedron& i setRenderingMode(PointsPlusNormals); is_selected = true; - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(7, buffer); + glGenBuffers(9, buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &textureId); compile_shaders(); } Scene_points_with_normal_item::~Scene_points_with_normal_item() { Q_ASSERT(m_points != NULL); - glDeleteBuffers(7, buffer); - glDeleteVertexArrays(1, vao); + glDeleteBuffers(9, buffer); + glDeleteVertexArrays(2, vao); glDeleteProgram(rendering_program_lines); glDeleteProgram(rendering_program_points); + glDeleteProgram(rendering_program_splats); delete m_points; m_points = NULL; } @@ -167,6 +205,62 @@ void Scene_points_with_normal_item::initialize_buffers() ); glEnableVertexAttribArray(3); + glBindBuffer(GL_ARRAY_BUFFER, buffer[6]); + glBufferData(GL_ARRAY_BUFFER, + (positions_splats.size())*sizeof(double), + positions_splats.data(), GL_STATIC_DRAW); + glVertexAttribPointer(4, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(4); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[7]); + glBufferData(GL_ARRAY_BUFFER, + (tex_coords.size())*sizeof(double), + tex_coords.data(), GL_STATIC_DRAW); + glVertexAttribPointer(5, + 2, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(5); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[8]); + glBufferData(GL_ARRAY_BUFFER, + (normals.size())*sizeof(double), + normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(6, + 3, + GL_DOUBLE, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(6); + + // glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGB, + 1, + 1, + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glBindVertexArray(vao[1]); glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); @@ -197,7 +291,6 @@ void Scene_points_with_normal_item::initialize_buffers() ); glEnableVertexAttribArray(3); - // Clean-up glBindVertexArray(0); } @@ -239,26 +332,20 @@ void Scene_points_with_normal_item::compile_shaders(void) " color = fColors; \n" "} \n" }; - GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, vertex_shader_source_lines, 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); - //Clean-up glDeleteShader(vertex_shader); - rendering_program_lines = program; - - //For the points static const GLchar* vertex_shader_source_points[] = { @@ -281,25 +368,82 @@ void Scene_points_with_normal_item::compile_shaders(void) 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); //Clean-up glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); rendering_program_points = program; + + //For the splats + static const GLchar* vertex_shader_source_splats[] = + { + "#version 300 es \n" + " \n" + "layout (location = 4) in vec3 positions; \n" + "layout (location = 6) in vec3 normals; \n" + "layout (location = 5) in vec2 v_texCoord; \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" + "uniform sampler2D s_texture; \n" + + "vec4 positions_splats = vec4(positions, 1.0); \n" + "float spec_power = 128.0; \n" + + "out highp vec3 fColors; \n" + " \n" + "void main(void) \n" + "{ \n" + " vec4 P = mv_matrix * positions_splats; \n" + " vec3 N = mat3(mv_matrix)* normals; \n" + " vec3 L = light_pos - P.xyz; \n" + " N = normalize(N); \n" + " L = normalize(L); \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" + " fColors = vec3(1.0,0.0,0.0); \n" /*vec3(texture(s_texture, v_texCoord)) * (light_amb + diffuse);*/ + " gl_Position = mvp_matrix * positions_splats; \n" + "} \n" + }; + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, vertex_shader_source_splats, 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); + + //Clean-up + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + rendering_program_splats = program; + + } void Scene_points_with_normal_item::compute_normals_and_vertices(void) { positions_points.clear(); positions_lines.clear(); + positions_splats.clear(); + positions_selected_points.clear(); color_points.clear(); color_lines.clear(); + normals.clear(); + tex_coords.clear(); //The points { @@ -324,9 +468,9 @@ void Scene_points_with_normal_item::compute_normals_and_vertices(void) } else { - color_points.push_back(this->color().redF()); - color_points.push_back(this->color().greenF()); - color_points.push_back(this->color().blueF()); + color_points.push_back(this->color().redF()); + color_points.push_back(this->color().greenF()); + color_points.push_back(this->color().blueF()); } } @@ -366,90 +510,151 @@ void Scene_points_with_normal_item::compute_normals_and_vertices(void) // Stock normals of *non-selected* points if (m_points->nb_selected_points() < m_points->size()) { - // Stock normals - for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) - { - const UI_point& p = *it; - const Point_set_3::Vector& n = p.normal(); - if (!p.is_selected()) + // Stock normals + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) { - Point_set_3::Point q = p + normal_length * n; - positions_lines.push_back(p.x()); - positions_lines.push_back(p.y()); - positions_lines.push_back(p.z()); + const UI_point& p = *it; + const Point_set_3::Vector& n = p.normal(); + if (!p.is_selected()) + { + Point_set_3::Point q = p + normal_length * n; + positions_lines.push_back(p.x()); + positions_lines.push_back(p.y()); + positions_lines.push_back(p.z()); - positions_lines.push_back(q.x()); - positions_lines.push_back(q.y()); - positions_lines.push_back(q.z()); + positions_lines.push_back(q.x()); + positions_lines.push_back(q.y()); + positions_lines.push_back(q.z()); - if(is_selected) - { - color_lines.push_back(this->color().lighter(120).redF()); - color_lines.push_back(this->color().lighter(120).greenF()); - color_lines.push_back(this->color().lighter(120).blueF()); + if(is_selected) + { + color_lines.push_back(this->color().lighter(120).redF()); + color_lines.push_back(this->color().lighter(120).greenF()); + color_lines.push_back(this->color().lighter(120).blueF()); - color_lines.push_back(this->color().lighter(120).redF()); - color_lines.push_back(this->color().lighter(120).greenF()); - color_lines.push_back(this->color().lighter(120).blueF()); - } - else - { - color_lines.push_back(this->color().redF()); - color_lines.push_back(this->color().greenF()); - color_lines.push_back(this->color().blueF()); + color_lines.push_back(this->color().lighter(120).redF()); + color_lines.push_back(this->color().lighter(120).greenF()); + color_lines.push_back(this->color().lighter(120).blueF()); + } + else + { + color_lines.push_back(this->color().redF()); + color_lines.push_back(this->color().greenF()); + color_lines.push_back(this->color().blueF()); - color_lines.push_back(this->color().redF()); - color_lines.push_back(this->color().greenF()); - color_lines.push_back(this->color().blueF()); - } + color_lines.push_back(this->color().redF()); + color_lines.push_back(this->color().greenF()); + color_lines.push_back(this->color().blueF()); + } + } } - } } // Stock normals of *selected* points if (m_points->nb_selected_points() > 0) { - for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) - { - const UI_point& p = *it; - const Point_set_3::Vector& n = p.normal(); - if (p.is_selected()) + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) { - Point_set_3::Point q = p + normal_length * n; - positions_lines.push_back(p.x()); - positions_lines.push_back(p.y()); - positions_lines.push_back(p.z()); + const UI_point& p = *it; + const Point_set_3::Vector& n = p.normal(); + if (p.is_selected()) + { + Point_set_3::Point q = p + normal_length * n; + positions_lines.push_back(p.x()); + positions_lines.push_back(p.y()); + positions_lines.push_back(p.z()); - positions_lines.push_back(q.x()); - positions_lines.push_back(q.y()); - positions_lines.push_back(q.z()); + positions_lines.push_back(q.x()); + positions_lines.push_back(q.y()); + positions_lines.push_back(q.z()); - 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); - 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); + } + } + } + } + + //The splats + { + // TODO add support for selection + texture[0] = this->color().redF(); + texture[1] = this->color().greenF(); + texture[2] = this->color().blueF(); + + // Draw splats + bool points_have_normals = (m_points->begin() != m_points->end() && + m_points->begin()->normal() != CGAL::NULL_VECTOR); + bool points_have_radii = (m_points->begin() != m_points->end() && + m_points->begin()->radius() != 0); + if(points_have_normals && points_have_radii) + { + for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + normals.push_back(p.normal().x()); + normals.push_back(p.normal().y()); + normals.push_back(p.normal().z()); +#ifdef CGAL_GLEW_ENABLED + tex_coords.push_back(p.radius()); +#endif + positions_splats.push_back(p.x()); + positions_splats.push_back(p.y()); + positions_splats.push_back(p.z()); } - } } } location[0] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program_points, "mvp_matrix"); + + location[2] = glGetUniformLocation(rendering_program_splats, "mvp_matrix"); + location[3] = glGetUniformLocation(rendering_program_splats, "mv_matrix"); + location[4] = glGetUniformLocation(rendering_program_splats, "light_pos"); + location[5] = glGetUniformLocation(rendering_program_splats, "light_diff"); + location[6] = glGetUniformLocation(rendering_program_splats, "light_spec"); + location[7] = glGetUniformLocation(rendering_program_splats, "light_amb"); + location[8] = glGetUniformLocation(rendering_program_splats, "is_two_side"); + sampler_location = glGetUniformLocation(rendering_program_splats, "s_texture"); + } void Scene_points_with_normal_item::uniform_attrib(Viewer_interface* viewer, int mode) const { GLfloat mvp_mat[16]; - - //fills the MVP matrix. + light_info light; + GLint is_both_sides = 0; + GLfloat mv_mat[16]; 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]); + + glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); + + //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); if(mode ==0) { @@ -461,6 +666,20 @@ void Scene_points_with_normal_item::uniform_attrib(Viewer_interface* viewer, int glUseProgram(rendering_program_points); glUniformMatrix4fv(location[1], 1, GL_FALSE, mvp_mat); } + + else if(mode ==2) + { + glUseProgram(rendering_program_splats); + glUniformMatrix4fv(location[2], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[3], 1, GL_FALSE, mv_mat); + glUniform3fv(location[4], 1, light.position); + glUniform3fv(location[5], 1, light.diffuse); + glUniform3fv(location[6], 1, light.specular); + glUniform3fv(location[7], 1, light.ambient); + glUniform1i(location[8], is_both_sides); + glUniform1i(sampler_location, 0); + } + } @@ -631,6 +850,12 @@ void Scene_points_with_normal_item::draw_splats() const } } +void Scene_points_with_normal_item::draw_splats(Viewer_interface* viewer) const +{ + //Needs to be re-thinked because the GlSplat Renderer is deprecated and is a big part of the scene class. + draw_splats(); +} + void Scene_points_with_normal_item::draw_edges(Viewer_interface* viewer) const { glBindVertexArray(vao[0]); diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h index 36d330fbd10..393128c11fc 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h @@ -45,16 +45,22 @@ public: // Function for displaying meta-data of the item virtual QString toolTip() const; + virtual void changed(); + virtual void selection_changed(bool); + // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const; // Points OpenGL drawing in a display list virtual void direct_draw() const; + virtual void draw_edges(Viewer_interface* viewer) const; + virtual void draw_points(Viewer_interface*) const; // Normals OpenGL drawing void draw_normals() const; virtual void draw_edges() const { draw_normals(); }//to tweak scene // Splat OpenGL drawing virtual void draw_splats() const; + virtual void draw_splats(Viewer_interface*) const; // Gets wrapped point set Point_set* point_set(); @@ -88,6 +94,34 @@ private: QAction* actionDeleteSelection; QAction* actionResetSelection; QAction* actionSelectDuplicatedPoints; + + + std::vector positions_lines; + std::vector positions_points; + std::vector positions_splats; + std::vector positions_selected_points; + std::vector color_lines; + std::vector color_points; + std::vector color_selected_points; + std::vector normals; + std::vector tex_coords; + + int texture[3]; + + GLuint rendering_program_lines; + GLuint rendering_program_points; + GLuint rendering_program_splats; + GLint location[9]; + GLuint textureId; + GLint sampler_location; + + GLuint vao[2]; + GLuint buffer[9]; + void initialize_buffers(); + void compile_shaders(void); + void compute_normals_and_vertices(void); + void uniform_attrib(Viewer_interface*, int) const; + }; // end class Scene_points_with_normal_item diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index e326e02264b..dc9cefb2438 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -103,7 +103,6 @@ Scene_polyhedron_item::is_Triangulated() if(nb_points_per_facet !=3) { - std::cout<<"NOT TRIANGLE"<key() == Qt::Key_M) { d->macro_mode = ! d->macro_mode; + if(d->macro_mode) { - camera()->setZNearCoefficient(0.0005f); + camera()->setZNearCoefficient(0.0005f); } else { camera()->setZNearCoefficient(0.005f); } this->displayMessage(tr("Macro mode: %1"). arg(d->macro_mode ? tr("on") : tr("off"))); + + + return; } } From 078ad824ff4dde3b8f451864b951696075cfa192 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Mar 2015 14:04:08 +0100 Subject: [PATCH 50/62] Polyhedron_transform_item upgrade It was quite simple, as there was only lines to draw. I add to add a call to change in replaceItem (scene.cpp) though. --- Polyhedron/demo/Polyhedron/Scene.cpp | 2 +- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 10 +- .../Scene_polyhedron_transform_item.cpp | 249 ++++++++++++++---- .../Scene_polyhedron_transform_item.h | 73 +++-- 4 files changed, 254 insertions(+), 80 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 9e413684374..220ddccb9f1 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -79,6 +79,7 @@ Scene::addItem(Scene_item* item) Scene_item* Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_to_be_destroyed) { + item->changed(); if(index < 0 || index >= m_entries.size()) return 0; @@ -89,7 +90,6 @@ Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_ connect(item, SIGNAL(itemChanged()), this, SLOT(itemChanged())); std::swap(m_entries[index], item); - if ( item->isFinite() && !item->isEmpty() && m_entries[index]->isFinite() && !m_entries[index]->isEmpty() && item->bbox()!=m_entries[index]->bbox() ) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index dc9cefb2438..46ae552a7cb 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -519,6 +519,8 @@ Scene_polyhedron_item::compile_shaders(void) void Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer, int mode) const { + + light_info light; GLint is_both_sides = 0; GLfloat mvp_mat[16]; @@ -556,6 +558,7 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer, int mode) const glGetLightfv(GL_LIGHT0, GL_DIFFUSE, light.diffuse); if(mode ==0) { + glUseProgram(rendering_program_facets); glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); glUniformMatrix4fv(location[1], 1, GL_FALSE, mv_mat); @@ -569,8 +572,11 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer, int mode) const { glUseProgram(rendering_program_lines); glUniformMatrix4fv(location[7], 1, GL_FALSE, mvp_mat); + } + + } void Scene_polyhedron_item::compute_normals_and_vertices(void) @@ -833,7 +839,6 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) glGenVertexArrays(1, vao); //Generates an integer which will be used as ID for each buffer glGenBuffers(5, buffer); - compile_shaders(); } @@ -855,7 +860,6 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) glGenVertexArrays(1, vao); //Generates an integer which will be used as ID for each buffer glGenBuffers(5, buffer); - compile_shaders(); } @@ -1021,8 +1025,6 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { glUseProgram(0); glBindVertexArray(0); - - } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp index 0f5ed7950c6..62138582d87 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp @@ -3,65 +3,222 @@ #include "Polyhedron_type.h" Scene_polyhedron_transform_item::Scene_polyhedron_transform_item(const qglviewer::Vec& pos,const Scene_polyhedron_item* poly_item_,const Scene_interface*): - poly_item(poly_item_), - manipulable(false), - frame(new ManipulatedFrame()), - poly(poly_item->polyhedron()), - center_(pos) { frame->setPosition(pos); } + poly_item(poly_item_), + manipulable(false), + frame(new ManipulatedFrame()), + positions_lines(0), + poly(poly_item->polyhedron()), + center_(pos) { + frame->setPosition(pos); + + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(1, buffer); + compile_shaders(); + +} + +Scene_polyhedron_transform_item::~Scene_polyhedron_transform_item() +{ + + glDeleteBuffers(1, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program); + delete frame; + emit killed(); +} + +void Scene_polyhedron_transform_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 + 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); +} +void Scene_polyhedron_transform_item::compile_shaders() +{ + //fill the vertex shader + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec3 positions; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform mat4 f_matrix; \n" + "uniform vec3 color_lines; \n" + "vec4 positions_lines = vec4(positions, 1.0); \n" + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color_lines; \n" + " gl_Position = mvp_matrix * f_matrix * positions_lines; \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_lines, 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); + glDeleteShader(fragment_shader); + rendering_program = program; + +} +void Scene_polyhedron_transform_item::uniform_attrib(Viewer_interface* viewer) const +{ + GLfloat mvp_mat[16]; + GLfloat f_mat[16]; + GLdouble d_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mat); + for (int i=0; i<16; ++i){ + mvp_mat[i] = GLfloat(d_mat[i]); + f_mat[i] = frame->matrix()[i]; + } + + GLfloat colors[3]; + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + glUseProgram(rendering_program); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[1], 1, colors); + glUniformMatrix4fv(location[2], 1, GL_FALSE, f_mat); +} +void Scene_polyhedron_transform_item::compute_elements() +{ + positions_lines.clear(); + typedef Kernel::Point_3 Point; + typedef Polyhedron::Edge_const_iterator Edge_iterator; + + Edge_iterator he; + for(he = poly->edges_begin(); + he != poly->edges_end(); + he++) + { + const Point& a = he->vertex()->point(); + const Point& b = he->opposite()->vertex()->point(); + positions_lines.push_back(a.x()-center_.x); + positions_lines.push_back(a.y()-center_.y); + positions_lines.push_back(a.z()-center_.z); + + positions_lines.push_back(b.x()-center_.x); + positions_lines.push_back(b.y()-center_.y); + positions_lines.push_back(b.z()-center_.z); + + } + + location[0] = glGetUniformLocation(rendering_program, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program, "color_lines"); + location[2] = glGetUniformLocation(rendering_program, "f_matrix"); +} + void Scene_polyhedron_transform_item::draw() const{ - glPushMatrix(); - glMultMatrixd(frame->matrix()); - direct_draw_edges(); - //Scene_item_with_display_list::draw(); - glPopMatrix(); + glPushMatrix(); + glMultMatrixd(frame->matrix()); + direct_draw_edges(); + //Scene_item_with_display_list::draw(); + glPopMatrix(); } - -void Scene_polyhedron_transform_item::direct_draw_edges() const { - typedef Kernel::Point_3 Point; - typedef Polyhedron::Edge_const_iterator Edge_iterator; +void Scene_polyhedron_transform_item::draw_edges(Viewer_interface* viewer) const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program); + uniform_attrib(viewer); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); - ::glDisable(GL_LIGHTING); - ::glBegin(GL_LINES); - Edge_iterator he; - for(he = poly->edges_begin(); - he != poly->edges_end(); - he++) - { - const Point& a = he->vertex()->point(); - const Point& b = he->opposite()->vertex()->point(); - ::glVertex3d(a.x()-center_.x,a.y()-center_.y,a.z()-center_.z); - ::glVertex3d(b.x()-center_.x,b.y()-center_.y,b.z()-center_.z); - } - ::glEnd(); - ::glEnable(GL_LIGHTING); +} +void Scene_polyhedron_transform_item::direct_draw_edges() const { + typedef Kernel::Point_3 Point; + typedef Polyhedron::Edge_const_iterator Edge_iterator; + + ::glDisable(GL_LIGHTING); + ::glBegin(GL_LINES); + Edge_iterator he; + for(he = poly->edges_begin(); + he != poly->edges_end(); + he++) + { + const Point& a = he->vertex()->point(); + const Point& b = he->opposite()->vertex()->point(); + ::glVertex3d(a.x()-center_.x,a.y()-center_.y,a.z()-center_.z); + ::glVertex3d(b.x()-center_.x,b.y()-center_.y,b.z()-center_.z); + } + ::glEnd(); + ::glEnable(GL_LIGHTING); } QString Scene_polyhedron_transform_item::toolTip() const { - return QObject::tr("

Affine transformation of %1

" - "

Keep Ctrl pressed and use the arcball to define an affine transformation.
" - "Press S to apply the affine transformation to a copy of %1.

") - .arg(getBase()->name()); + return QObject::tr("

Affine transformation of %1

" + "

Keep Ctrl pressed and use the arcball to define an affine transformation.
" + "Press S to apply the affine transformation to a copy of %1.

") + .arg(getBase()->name()); } bool Scene_polyhedron_transform_item::keyPressEvent(QKeyEvent* e){ - if (e->key()==Qt::Key_S){ - emit stop(); - return true; - } - return false; + if (e->key()==Qt::Key_S){ + emit stop(); + return true; + } + return false; } Scene_polyhedron_transform_item::Bbox Scene_polyhedron_transform_item::bbox() const { - const Kernel::Point_3& p = *(poly->points_begin()); - CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); - for(Polyhedron::Point_const_iterator it = poly->points_begin(); - it != poly->points_end(); - ++it) { - bbox = bbox + it->bbox(); - } - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); + const Kernel::Point_3& p = *(poly->points_begin()); + CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); + for(Polyhedron::Point_const_iterator it = poly->points_begin(); + it != poly->points_end(); + ++it) { + bbox = bbox + it->bbox(); + } + return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), + bbox.xmax(),bbox.ymax(),bbox.zmax()); } + +void Scene_polyhedron_transform_item::changed() +{ + compute_elements(); + initialize_buffers(); +} #include "Scene_polyhedron_transform_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h index 7e7f180da38..c689ad35676 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h @@ -9,41 +9,56 @@ // This class represents a polyhedron in the OpenGL scene class SCENE_POLYHEDRON_TRANSFORM_ITEM_EXPORT Scene_polyhedron_transform_item - : public Scene_item { -// : public Scene_item_with_display_list { - Q_OBJECT + : public Scene_item { + // : public Scene_item_with_display_list { + Q_OBJECT - typedef Scene_polyhedron_item Base; + typedef Scene_polyhedron_item Base; public: - Scene_polyhedron_transform_item(const qglviewer::Vec& pos,const Scene_polyhedron_item* poly_item,const Scene_interface* scene_interface); - void direct_draw_edges() const; - Scene_item* clone() const{return NULL;} - QString toolTip() const; - void direct_draw() const {} - void draw() const; - Bbox bbox() const; - ~Scene_polyhedron_transform_item() {delete frame; emit killed();} + Scene_polyhedron_transform_item(const qglviewer::Vec& pos,const Scene_polyhedron_item* poly_item,const Scene_interface* scene_interface); + void direct_draw_edges() const; + Scene_item* clone() const{return NULL;} + QString toolTip() const; + void direct_draw() const {} + void draw() const; + void draw_edges(Viewer_interface*) const; + void draw_edges() const{direct_draw_edges();} + Bbox bbox() const; + ~Scene_polyhedron_transform_item(); + bool manipulatable() const { return manipulable; } + ManipulatedFrame* manipulatedFrame() { return frame; } + void setManipulatable(bool b = true) { manipulable = b;} + const Scene_polyhedron_item* getBase() const{ return poly_item; }; + const qglviewer::Vec& center() const { return center_; } + virtual bool supportsRenderingMode(RenderingMode m) const { return m==Wireframe ; } + virtual void changed(); + virtual bool keyPressEvent(QKeyEvent*); - bool manipulatable() const { return manipulable; } - ManipulatedFrame* manipulatedFrame() { return frame; } - void setManipulatable(bool b = true) { manipulable = b;} - const Scene_polyhedron_item* getBase() const{ return poly_item; }; - const qglviewer::Vec& center() const { return center_; } - virtual bool supportsRenderingMode(RenderingMode m) const { return m==Wireframe ; } - - virtual bool keyPressEvent(QKeyEvent*); - private: - const Scene_polyhedron_item* poly_item; - bool manipulable; - qglviewer::ManipulatedFrame* frame; - const Polyhedron* poly; - qglviewer::Vec center_; - + const Scene_polyhedron_item* poly_item; + bool manipulable; + qglviewer::ManipulatedFrame* frame; + const Polyhedron* poly; + qglviewer::Vec center_; + + std::vector positions_lines; + + + + GLint location[3]; + GLuint vao[1]; + GLuint buffer[1]; + GLuint rendering_program; + + void initialize_buffers(); + void compile_shaders(); + void uniform_attrib(Viewer_interface*) const; + void compute_elements(); + signals: - void stop(); - void killed(); + void stop(); + void killed(); }; // end class Scene_polyhedron_transform_item #endif // SCENE_POLYHEDRON_TRANSFORM_ITEM_H From 4e363dc6e6fd71156bd0154b69be9eca142f3390 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Mar 2015 15:52:54 +0100 Subject: [PATCH 51/62] Scene_plane_item upgraded I added some functions in the .cpp file, that was empty before. --- .../demo/Polyhedron/Scene_plane_item.cpp | 252 ++++++++++++++++++ Polyhedron/demo/Polyhedron/Scene_plane_item.h | 41 ++- 2 files changed, 291 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp index 92c1d9c4c4d..28537996186 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp @@ -1,3 +1,255 @@ #include "Scene_plane_item.h" #include "Scene_plane_item.moc" + + +void Scene_plane_item::initialize_buffers() +{ + glBindVertexArray(vao[0]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_quad.size())*sizeof(float), + positions_quad.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, + (positions_lines.size())*sizeof(float), + positions_lines.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); +} +void Scene_plane_item::compile_shaders(void) +{ + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec3 positions; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform mat4 f_matrix; \n" + "uniform vec3 color; \n" + "out highp vec3 fColors; \n" + + "vec4 positions_quad = vec4 (positions, 1.0); \n" + " \n" + "void main(void) \n" + "{ \n" + " fColors = color; \n" + " gl_Position = mvp_matrix * f_matrix * positions_quad; \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, 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); + + //Clean-up + glDeleteShader(vertex_shader); + + rendering_program_quad = program; + + + //For the edges + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 1) in vec3 positions; \n" + "uniform mat4 mvp_matrix; \n" + "uniform mat4 f_matrix; \n" + "vec4 positions_lines = vec4(positions,1.0); \n" + "out highp vec3 fColors; \n" + " \n" + "void main(void) \n" + "{ \n" + " fColors = vec3(0.0,0.0,0.0); \n" + " gl_Position = mvp_matrix * f_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); + + + //Clean-up + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + rendering_program_lines = program; + +} +void Scene_plane_item::uniform_attrib(Viewer_interface* viewer, int mode) const +{ + GLfloat mvp_mat[16]; + GLdouble d_mat[16]; + GLfloat f_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]); + f_mat[i] = GLfloat(frame->matrix()[i]); + } + + GLfloat colors[3]; + + colors[0] =this->color().redF(); + colors[1] =this->color().greenF(); + colors[2] =this->color().blueF(); + + if(mode ==0) + { + glUseProgram(rendering_program_quad); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[1], 1, colors); + glUniformMatrix4fv(location[2], 1, GL_FALSE, f_mat); + + } + else if(mode ==1) + { + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[3], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[4], 1, GL_FALSE, f_mat); + } + +} +void Scene_plane_item::compute_normals_and_vertices(void) +{ + positions_quad.clear(); + positions_lines.clear(); + + const double diag = scene_diag(); + //The quad + { + + positions_quad.push_back(-diag); + positions_quad.push_back(-diag); + positions_quad.push_back(0.0); + positions_quad.push_back(-diag); + positions_quad.push_back(diag); + positions_quad.push_back(0.0); + positions_quad.push_back(diag); + positions_quad.push_back(-diag); + positions_quad.push_back(0.0); + + positions_quad.push_back(-diag); + positions_quad.push_back(diag); + positions_quad.push_back(0.0); + positions_quad.push_back(diag); + positions_quad.push_back(-diag); + positions_quad.push_back(0.0); + positions_quad.push_back(diag); + positions_quad.push_back(diag); + positions_quad.push_back(0.0); + +} + //The grid + float x = (2*diag)/10.0; + float y = (2*diag)/10.0; + { + for(int u = 0; u < 11; u++) + { + + positions_lines.push_back(-diag + x* u); + positions_lines.push_back(-diag); + positions_lines.push_back(0.0); + + positions_lines.push_back(-diag + x* u); + positions_lines.push_back(diag); + positions_lines.push_back(0.0); + } + for(int v=0; v<11; v++) + { + + positions_lines.push_back(-diag); + positions_lines.push_back(-diag + v * y); + positions_lines.push_back(0.0); + + positions_lines.push_back(diag); + positions_lines.push_back(-diag + v * y); + positions_lines.push_back(0.0); + } + + } + + + location[0] = glGetUniformLocation(rendering_program_quad, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_quad, "color"); + location[2] = glGetUniformLocation(rendering_program_quad, "f_matrix"); + location[3] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[4] = glGetUniformLocation(rendering_program_lines, "f_matrix"); +} + +void Scene_plane_item::draw(Viewer_interface* viewer)const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_quad); + uniform_attrib(viewer,0); + glDrawArrays(GL_TRIANGLES, 0, positions_quad.size()/3);\ + glUseProgram(0); + glBindVertexArray(0); + +} + +void Scene_plane_item::draw_edges(Viewer_interface* viewer)const +{ + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer,1); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3);\ + glUseProgram(0); + glBindVertexArray(0); +} diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.h b/Polyhedron/demo/Polyhedron/Scene_plane_item.h index 7e8ebc33389..1846d55750f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.h @@ -1,6 +1,7 @@ #ifndef SCENE_PLANE_ITEM_H #define SCENE_PLANE_ITEM_H +#include #include "Scene_item.h" #include "Scene_interface.h" @@ -8,6 +9,7 @@ #include #include +#include #include @@ -26,12 +28,23 @@ public: : scene(scene_interface), manipulable(false), can_clone(true), + positions_lines(0), + positions_quad(0), frame(new ManipulatedFrame()) { setNormal(0., 0., 1.); + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(2, buffer); + compile_shaders(); + changed(); } ~Scene_plane_item() { + glDeleteBuffers(2, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_quad); delete frame; } @@ -108,7 +121,7 @@ public: ::glEnable(GL_LIGHTING); ::glPopMatrix(); }; - + virtual void draw(Viewer_interface*) const; // Wireframe OpenGL drawing void draw_edges() const { ::glPushMatrix(); @@ -116,7 +129,7 @@ public: QGLViewer::drawGrid((float)scene_diag()); ::glPopMatrix(); } - + virtual void draw_edges(Viewer_interface* viewer)const; Plane_3 plane() const { const qglviewer::Vec& pos = frame->position(); const qglviewer::Vec& n = @@ -137,6 +150,12 @@ private: } public slots: + virtual void changed() + { +compute_normals_and_vertices(); +initialize_buffers(); + } + void setPosition(float x, float y, float z) { frame->setPosition(x, y, z); } @@ -165,6 +184,24 @@ private: bool manipulable; bool can_clone; qglviewer::ManipulatedFrame* frame; + std::vector positions_lines; + std::vector positions_quad; + + + + + GLuint rendering_program_quad; + GLuint rendering_program_lines; + GLint location[10]; + GLint sampler_location; + + GLuint vao[1]; + GLuint buffer[2]; + bool smooth_shading; + void initialize_buffers(); + void compile_shaders(void); + void uniform_attrib(Viewer_interface*, int) const; + void compute_normals_and_vertices(void); }; #endif // SCENE_PLANE_ITEM_H From e6c6efb86d88ddf0449cf36b69546aa3a3b6a1ef Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Mar 2015 11:57:54 +0100 Subject: [PATCH 52/62] Selection_item upgrade --- .../Polyhedron/Scene_polygon_soup_item.cpp | 2 +- .../Scene_polyhedron_selection_item.cpp | 457 ++++++ .../Scene_polyhedron_selection_item.h | 1302 +++++++++-------- .../Scene_polyhedron_transform_item.cpp | 1 + 4 files changed, 1131 insertions(+), 631 deletions(-) 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() { From 7db52de9b52ca309208d0c1f0e34e2b66726bf15 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Mar 2015 12:04:32 +0100 Subject: [PATCH 53/62] Edit --- Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 2abbcd975d0..b7785c563cd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -411,7 +411,6 @@ void Scene_polyhedron_selection_item::compute_elements() void Scene_polyhedron_selection_item::draw(Viewer_interface* viewer) const { - draw(); draw_points(viewer); GLfloat offset_factor; From a87c87a6119146757b67ea435f67617ccaf8b9e8 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Mar 2015 16:19:52 +0100 Subject: [PATCH 54/62] Scene c3t3 item upgrade I had to implement the clipping myself, appart from that everything went fine. --- .../Polyhedron/Polyhedron_demo_cut_plugin.cpp | 313 ++++- .../Polyhedron_demo_mesh_3_plugin.cpp | 232 ++-- ...olyhedron_demo_mesh_3_plugin_cgal_code.cpp | 1203 +++++++++++++---- Polyhedron/demo/Polyhedron/Scene.cpp | 5 +- Polyhedron/demo/Polyhedron/Scene_c2t3_item.h | 1 - .../Scene_points_with_normal_item.cpp | 16 +- .../Polyhedron/Scene_polygon_soup_item.cpp | 21 +- 7 files changed, 1362 insertions(+), 429 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp index ec98cb56588..665918b2c7d 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp @@ -11,10 +11,10 @@ #include "Polyhedron_demo_io_plugin_interface.h" #include -#include +#include #include #include -#include +#include #include #include @@ -38,7 +38,21 @@ class Q_DECL_EXPORT Scene_aabb_item : public Scene_item_with_display_list { Q_OBJECT public: - Scene_aabb_item(const AABB_tree& tree_) : tree(tree_) {} + Scene_aabb_item(const AABB_tree& tree_) : tree(tree_) + { + positions_lines.resize(0); + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(1, buffer); + compile_shaders(); + } + + ~Scene_aabb_item() + { + glDeleteBuffers(1, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); + } bool isFinite() const { return true; } bool isEmpty() const { return tree.empty(); } @@ -76,18 +90,161 @@ public: // Wireframe OpenGL drawing in a display list void direct_draw() const { CGAL::AABB_drawing_traits > traits; - tree.traversal(0, traits); + tree.traversal(0, traits, new std::vector(0)); } + void changed() + { + compute_elements(); + initialize_buffers(); + } public: const AABB_tree& tree; +private: + std::vector positions_lines; + + GLint location[2]; + GLuint vao[1]; + GLuint buffer[1]; + GLuint rendering_program_lines; + + void 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 + 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); + + glBindVertexArray(0); + } + void compile_shaders() + { + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) 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" + }; + + //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, 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); + glDeleteShader(fragment_shader); + rendering_program_lines = program; + } + void uniform_attrib(Viewer_interface* viewer) const + { + GLfloat colors[3]; + GLfloat mvp_mat[16]; + + //fills the MVP and MV matrices. + + GLdouble d_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mat); + for (int i=0; i<16; ++i) + mvp_mat[i] = GLfloat(d_mat[i]); + + + //fills the arraw of colors with the current color + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + + + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[1],1,colors); + } + void compute_elements() + { + positions_lines.clear(); + + CGAL::AABB_drawing_traits > traits; + tree.traversal(0, traits, &positions_lines); + + location[0] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_lines, "color"); + } + void draw_edges(Viewer_interface* viewer) const + { + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + } }; // end class Scene_aabb_item class Q_DECL_EXPORT Scene_edges_item : public Scene_item { Q_OBJECT public: - bool isFinite() const { return true; } + Scene_edges_item() + { + positions_lines.resize(0); + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(1, buffer); + compile_shaders(); + } + ~Scene_edges_item() + { + glDeleteBuffers(1, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); + } + bool isFinite() const { return true; } bool isEmpty() const { return edges.empty(); } Bbox bbox() const { if(isEmpty()) @@ -103,9 +260,14 @@ public: bbox.ymax(), bbox.zmax()); } + void changed() + { + compute_elements(); + initialize_buffers(); + } Scene_edges_item* clone() const { - Scene_edges_item* item = new Scene_edges_item; + Scene_edges_item* item = new Scene_edges_item(); item->edges = edges; return item; } @@ -127,11 +289,12 @@ public: } // Flat/Gouraud OpenGL drawing - void draw() const {} + void draw() const { + } // Wireframe OpenGL drawing void draw_edges() const { - ::glBegin(GL_LINES); + /*::glBegin(GL_LINES); for(size_t i = 0, end = edges.size(); i < end; ++i) { @@ -140,7 +303,7 @@ public: ::glVertex3d(a.x(), a.y(), a.z()); ::glVertex3d(b.x(), b.y(), b.z()); } - ::glEnd(); + ::glEnd();*/ } bool save(std::ostream& os) const @@ -154,6 +317,138 @@ public: public: std::vector edges; + +private: + std::vector positions_lines; + + GLint location[2]; + GLuint vao[1]; + GLuint buffer[1]; + GLuint rendering_program_lines; + + void 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 + 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); + + glBindVertexArray(0); + } + void compile_shaders() + { + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) 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" + }; + + //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, 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); + glDeleteShader(fragment_shader); + rendering_program_lines = program; + } + void uniform_attrib(Viewer_interface* viewer) const + { + GLfloat colors[3]; + GLfloat mvp_mat[16]; + + //fills the MVP and MV matrices. + + GLdouble d_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mat); + for (int i=0; i<16; ++i) + mvp_mat[i] = GLfloat(d_mat[i]); + + + //fills the arraw of colors with the current color + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + + + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[1],1,colors); + } + void compute_elements() + { + positions_lines.clear(); + + for(size_t i = 0, end = edges.size(); + i < end; ++i) + { + const Epic_kernel::Point_3& a = edges[i].source(); + const Epic_kernel::Point_3& b = edges[i].target(); + 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()); + } + + location[0] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_lines, "color"); + } + void draw_edges(Viewer_interface* viewer) const + { + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + } + }; // end class Scene_edges_item diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp index fb36761e628..9852d01c71c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp @@ -26,160 +26,160 @@ Scene_item* cgal_code_mesh_3(const Polyhedron*, Scene_interface* scene); class Polyhedron_demo_mesh_3_plugin : - public QObject, - protected Polyhedron_demo_plugin_helper + public QObject, + protected Polyhedron_demo_plugin_helper { - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionMesh_3 = new QAction("Create a tetrahedral mesh", mw); - if(actionMesh_3) { - connect(actionMesh_3, SIGNAL(triggered()), - this, SLOT(mesh_3())); + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + this->scene = scene_interface; + this->mw = mainWindow; + actionMesh_3 = new QAction("Create a tetrahedral mesh", mw); + if(actionMesh_3) { + connect(actionMesh_3, SIGNAL(triggered()), + this, SLOT(mesh_3())); + } } - } - QList actions() const { - return QList() << actionMesh_3; - } + QList actions() const { + return QList() << actionMesh_3; + } - bool applicable(QAction*) const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); - } + bool applicable(QAction*) const { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } public slots: - void mesh_3(); + void mesh_3(); private: - QAction* actionMesh_3; + QAction* actionMesh_3; }; // end class Polyhedron_demo_mesh_3_plugin double get_approximate(double d, int precision, int& decimals) { - if ( d<0 ) { return 0; } + if ( d<0 ) { return 0; } - double i = std::pow(10.,precision-1); + double i = std::pow(10.,precision-1); - decimals = 0; - while ( d > i*10 ) { d = d/10.; ++decimals; } - while ( d < i ) { d = d*10.; --decimals; } + decimals = 0; + while ( d > i*10 ) { d = d/10.; ++decimals; } + while ( d < i ) { d = d*10.; --decimals; } - return std::floor(d)*std::pow(10.,decimals); + return std::floor(d)*std::pow(10.,decimals); } void Polyhedron_demo_mesh_3_plugin::mesh_3() { - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); + const Scene_interface::Item_id index = scene->mainSelectionIndex(); - if(!item) return; + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); - Polyhedron* pMesh = item->polyhedron(); + if(!item) return; - if(!pMesh) return; + Polyhedron* pMesh = item->polyhedron(); - // ----------------------------------- - // Create Mesh dialog - // ----------------------------------- - QDialog dialog(mw); - Ui::Meshing_dialog ui; - ui.setupUi(&dialog); - connect(ui.buttonBox, SIGNAL(accepted()), - &dialog, SLOT(accept())); - connect(ui.buttonBox, SIGNAL(rejected()), - &dialog, SLOT(reject())); + if(!pMesh) return; - // Connect checkboxes to spinboxes - connect(ui.noApprox, SIGNAL(toggled(bool)), - ui.approx, SLOT(setEnabled(bool))); + // ----------------------------------- + // Create Mesh dialog + // ----------------------------------- + QDialog dialog(mw); + Ui::Meshing_dialog ui; + ui.setupUi(&dialog); + connect(ui.buttonBox, SIGNAL(accepted()), + &dialog, SLOT(accept())); + connect(ui.buttonBox, SIGNAL(rejected()), + &dialog, SLOT(reject())); - connect(ui.noFacetSizing, SIGNAL(toggled(bool)), - ui.facetSizing, SLOT(setEnabled(bool))); + // Connect checkboxes to spinboxes + connect(ui.noApprox, SIGNAL(toggled(bool)), + ui.approx, SLOT(setEnabled(bool))); - connect(ui.noAngle, SIGNAL(toggled(bool)), - ui.facetAngle, SLOT(setEnabled(bool))); + connect(ui.noFacetSizing, SIGNAL(toggled(bool)), + ui.facetSizing, SLOT(setEnabled(bool))); - connect(ui.noTetSizing, SIGNAL(toggled(bool)), - ui.tetSizing, SLOT(setEnabled(bool))); + connect(ui.noAngle, SIGNAL(toggled(bool)), + ui.facetAngle, SLOT(setEnabled(bool))); - connect(ui.noTetShape, SIGNAL(toggled(bool)), - ui.tetShape, SLOT(setEnabled(bool))); + connect(ui.noTetSizing, SIGNAL(toggled(bool)), + ui.tetSizing, SLOT(setEnabled(bool))); - // Set default parameters - Scene_interface::Bbox bbox = item->bbox(); - ui.objectName->setText(item->name()); - ui.objectNameSize->setText(tr("Object bbox size (w,h,d): %1, %2, %3") - .arg(bbox.width(),0,'g',3) - .arg(bbox.height(),0,'g',3) - .arg(bbox.depth(),0,'g',3) ); + connect(ui.noTetShape, SIGNAL(toggled(bool)), + ui.tetShape, SLOT(setEnabled(bool))); - double diag = bbox.diagonal_length(); - int decimals = 0; - double sizing_default = get_approximate(diag * 0.05, 2, decimals); - ui.facetSizing->setDecimals(-decimals+2); - ui.facetSizing->setSingleStep(std::pow(10.,decimals)); - ui.facetSizing->setRange(diag * 10e-6, // min + // Set default parameters + Scene_interface::Bbox bbox = item->bbox(); + ui.objectName->setText(item->name()); + ui.objectNameSize->setText(tr("Object bbox size (w,h,d): %1, %2, %3") + .arg(bbox.width(),0,'g',3) + .arg(bbox.height(),0,'g',3) + .arg(bbox.depth(),0,'g',3) ); + + double diag = bbox.diagonal_length(); + int decimals = 0; + double sizing_default = get_approximate(diag * 0.05, 2, decimals); + ui.facetSizing->setDecimals(-decimals+2); + ui.facetSizing->setSingleStep(std::pow(10.,decimals)); + ui.facetSizing->setRange(diag * 10e-6, // min + diag); // max + ui.facetSizing->setValue(sizing_default); // default value + + ui.tetSizing->setDecimals(-decimals+2); + ui.tetSizing->setSingleStep(std::pow(10.,decimals)); + ui.tetSizing->setRange(diag * 10e-6, // min diag); // max - ui.facetSizing->setValue(sizing_default); // default value + ui.tetSizing->setValue(sizing_default); // default value - ui.tetSizing->setDecimals(-decimals+2); - ui.tetSizing->setSingleStep(std::pow(10.,decimals)); - ui.tetSizing->setRange(diag * 10e-6, // min - diag); // max - ui.tetSizing->setValue(sizing_default); // default value + double approx_default = get_approximate(diag * 0.005, 2, decimals); + ui.approx->setDecimals(-decimals+2); + ui.approx->setSingleStep(std::pow(10.,decimals)); + ui.approx->setRange(diag * 10e-7, // min + diag); // max + ui.approx->setValue(approx_default); - double approx_default = get_approximate(diag * 0.005, 2, decimals); - ui.approx->setDecimals(-decimals+2); - ui.approx->setSingleStep(std::pow(10.,decimals)); - ui.approx->setRange(diag * 10e-7, // min - diag); // max - ui.approx->setValue(approx_default); + // ----------------------------------- + // Get values + // ----------------------------------- + int i = dialog.exec(); + if( i == QDialog::Rejected ) { return; } - // ----------------------------------- - // Get values - // ----------------------------------- - int i = dialog.exec(); - if( i == QDialog::Rejected ) { return; } + // 0 means parameter is not considered + const double angle = !ui.noAngle->isChecked() ? 0 : ui.facetAngle->value(); + const double approx = !ui.noApprox->isChecked() ? 0 : ui.approx->value(); + const double facet_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); + const double radius_edge = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); + const double tet_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); + const bool protect_features = ui.protect->isChecked(); - // 0 means parameter is not considered - const double angle = !ui.noAngle->isChecked() ? 0 : ui.facetAngle->value(); - const double approx = !ui.noApprox->isChecked() ? 0 : ui.approx->value(); - const double facet_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); - const double radius_edge = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); - const double tet_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); - const bool protect_features = ui.protect->isChecked(); + QApplication::setOverrideCursor(Qt::WaitCursor); - QApplication::setOverrideCursor(Qt::WaitCursor); - - Scene_item* result_item = cgal_code_mesh_3(pMesh, - item->name(), - angle, - facet_sizing, - approx, - tet_sizing, - radius_edge, - protect_features, - scene); - if(result_item) { - result_item->setName(tr("%1 3d mesh (%2 %3 %4 %5)") - .arg(item->name()) - .arg(angle) - .arg(facet_sizing) - .arg(tet_sizing) - .arg(approx)); - result_item->setColor(Qt::magenta); - result_item->setRenderingMode(item->renderingMode()); - item->setVisible(false); - scene->itemChanged(index); - scene->addItem(result_item); - } - QApplication::restoreOverrideCursor(); + Scene_item* result_item = cgal_code_mesh_3(pMesh, + item->name(), + angle, + facet_sizing, + approx, + tet_sizing, + radius_edge, + protect_features, + scene); + if(result_item) { + result_item->setName(tr("%1 3d mesh (%2 %3 %4 %5)") + .arg(item->name()) + .arg(angle) + .arg(facet_sizing) + .arg(tet_sizing) + .arg(approx)); + result_item->setColor(Qt::magenta); + result_item->setRenderingMode(item->renderingMode()); + item->setVisible(false); + scene->itemChanged(index); + scene->addItem(result_item); + } + QApplication::restoreOverrideCursor(); } Q_EXPORT_PLUGIN2(Polyhedron_demo_mesh_3_plugin, Polyhedron_demo_mesh_3_plugin) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp index 0812962bf6d..42e828c8ce3 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp @@ -20,7 +20,7 @@ #include typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; +Polyhedron> Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -43,299 +43,912 @@ typedef Tr::Point Point_3; #include namespace { - void CGALglcolor(QColor c) - { +void CGALglcolor(QColor c) +{ ::glColor4d(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); - } +} } class Q_DECL_EXPORT Scene_c3t3_item : public Scene_item { - Q_OBJECT + Q_OBJECT public: - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef qglviewer::ManipulatedFrame ManipulatedFrame; - Scene_c3t3_item(const C3t3& c3t3) - : c3t3_(c3t3), frame(new ManipulatedFrame()), last_known_scene(NULL) - {} - - ~Scene_c3t3_item() - { - delete frame; - } - - const C3t3& c3t3() const { - return c3t3_; - } - - bool manipulatable() const { - return true; - } - ManipulatedFrame* manipulatedFrame() { - return frame; - } - - void setPosition(float x, float y, float z) { - frame->setPosition(x, y, z); - } - - void setNormal(float x, float y, float z) { - frame->setOrientation(x, y, z, 0.f); - } - - Kernel::Plane_3 plane() const { - const qglviewer::Vec& pos = frame->position(); - const qglviewer::Vec& n = - frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); - return Kernel::Plane_3(n[0], n[1], n[2], - n * pos); - } - - bool isFinite() const { return true; } - bool isEmpty() const { - return c3t3().triangulation().number_of_vertices() == 0; - } - - Bbox bbox() const { - if(isEmpty()) - return Bbox(); - else { - CGAL::Bbox_3 result = c3t3().triangulation().finite_vertices_begin()->point().bbox(); - for(Tr::Finite_vertices_iterator - vit = ++c3t3().triangulation().finite_vertices_begin(), - end = c3t3().triangulation().finite_vertices_end(); - vit != end; ++vit) - { - result = result + vit->point().bbox(); - } - return Bbox(result.xmin(), result.ymin(), result.zmin(), - result.xmax(), result.ymax(), result.zmax()); - } - } - - Scene_c3t3_item* clone() const { - return 0; - } - - QString toolTip() const { - int number_of_tets = 0; - for(Tr::Finite_cells_iterator - cit = c3t3().triangulation().finite_cells_begin(), - end = c3t3().triangulation().finite_cells_end(); - cit != end; ++cit) + Scene_c3t3_item(const C3t3& c3t3) + : c3t3_(c3t3), frame(new ManipulatedFrame()), last_known_scene(NULL) { - if( c3t3().is_in_complex(cit) ) - ++number_of_tets; + positions_lines.resize(0); + positions_poly.resize(0); + color_lines.resize(0); + color_poly.resize(0); + color_grid.resize(0); + normals.resize(0); + glGenVertexArrays(2, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(7, buffer); + compile_shaders(); } - return tr("

3D complex in a 3D triangulation

" - "

Number of vertices: %1
" - "Number of surface facets: %2
" - "Number of volume tetrahedra: %3

") - .arg(c3t3().triangulation().number_of_vertices()) - .arg(c3t3().number_of_facets()) - .arg(number_of_tets); - } - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { - return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS! - } - - void draw() const { - ::glPushMatrix(); - ::glMultMatrixd(frame->matrix()); - QGLViewer::drawGrid((float)complex_diag()); - ::glPopMatrix(); - - if(isEmpty()) - return; - - GLboolean two_side; - ::glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &two_side); - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - - const Kernel::Plane_3& plane = this->plane(); - GLdouble clip_plane[4]; - clip_plane[0] = -plane.a(); - clip_plane[1] = -plane.b(); - clip_plane[2] = -plane.c(); - clip_plane[3] = -plane.d(); - - ::glClipPlane(GL_CLIP_PLANE0, clip_plane); - ::glEnable(GL_CLIP_PLANE0); - ::glBegin(GL_TRIANGLES); - for(C3t3::Facet_iterator - fit = c3t3().facets_begin(), - end = c3t3().facets_end(); - fit != end; ++fit) + ~Scene_c3t3_item() { - const Tr::Cell_handle& cell = fit->first; - const int& index = fit->second; - const Kernel::Point_3& pa = cell->vertex((index+1)&3)->point(); - const Kernel::Point_3& pb = cell->vertex((index+2)&3)->point(); - const Kernel::Point_3& pc = cell->vertex((index+3)&3)->point(); - typedef Kernel::Oriented_side Side; - using CGAL::ON_ORIENTED_BOUNDARY; - const Side sa = plane.oriented_side(pa); - const Side sb = plane.oriented_side(pb); - const Side sc = plane.oriented_side(pc); - if( sa != ON_ORIENTED_BOUNDARY && - sb != ON_ORIENTED_BOUNDARY && - sc != ON_ORIENTED_BOUNDARY && - sb == sa && sc == sa ) - { - draw_triangle(pa, pb, pc); - } + glDeleteBuffers(7, buffer); + glDeleteVertexArrays(2, vao); + glDeleteProgram(rendering_program_lines); + glDeleteProgram(rendering_program_poly); + delete frame; } - ::glEnd(); - ::glDisable(GL_CLIP_PLANE0); - ::glBegin(GL_TRIANGLES); -// workaround for Qt-4.2. + void changed() + { + compute_elements(); + initialize_buffers(); + } + + void contextual_changed() + { + if(frame->isInMouseGrabberPool()) + changed(); + } + const C3t3& c3t3() const { + return c3t3_; + } + + bool manipulatable() const { + return true; + } + ManipulatedFrame* manipulatedFrame() { + return frame; + } + + void setPosition(float x, float y, float z) { + frame->setPosition(x, y, z); + } + + void setNormal(float x, float y, float z) { + frame->setOrientation(x, y, z, 0.f); + } + + Kernel::Plane_3 plane() const { + const qglviewer::Vec& pos = frame->position(); + const qglviewer::Vec& n = + frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + return Kernel::Plane_3(n[0], n[1], n[2], - n * pos); + } + + bool isFinite() const { return true; } + bool isEmpty() const { + return c3t3().triangulation().number_of_vertices() == 0; + } + + Bbox bbox() const { + if(isEmpty()) + return Bbox(); + else { + CGAL::Bbox_3 result = c3t3().triangulation().finite_vertices_begin()->point().bbox(); + for(Tr::Finite_vertices_iterator + vit = ++c3t3().triangulation().finite_vertices_begin(), + end = c3t3().triangulation().finite_vertices_end(); + vit != end; ++vit) + { + result = result + vit->point().bbox(); + } + return Bbox(result.xmin(), result.ymin(), result.zmin(), + result.xmax(), result.ymax(), result.zmax()); + } + } + + Scene_c3t3_item* clone() const { + return 0; + } + + QString toolTip() const { + int number_of_tets = 0; + for(Tr::Finite_cells_iterator + cit = c3t3().triangulation().finite_cells_begin(), + end = c3t3().triangulation().finite_cells_end(); + cit != end; ++cit) + { + if( c3t3().is_in_complex(cit) ) + ++number_of_tets; + } + return tr("

3D complex in a 3D triangulation

" + "

Number of vertices: %1
" + "Number of surface facets: %2
" + "Number of volume tetrahedra: %3

") + .arg(c3t3().triangulation().number_of_vertices()) + .arg(c3t3().number_of_facets()) + .arg(number_of_tets); + } + + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const { + return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS! + } + + void draw() const { + ::glPushMatrix(); + ::glMultMatrixd(frame->matrix()); + QGLViewer::drawGrid((float)complex_diag()); + ::glPopMatrix(); + + if(isEmpty()) + return; + + GLboolean two_side; + ::glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &two_side); + ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + const Kernel::Plane_3& plane = this->plane(); + GLdouble clip_plane[4]; + clip_plane[0] = -plane.a(); + clip_plane[1] = -plane.b(); + clip_plane[2] = -plane.c(); + clip_plane[3] = -plane.d(); + + ::glClipPlane(GL_CLIP_PLANE0, clip_plane); + ::glEnable(GL_CLIP_PLANE0); + ::glBegin(GL_TRIANGLES); + for(C3t3::Facet_iterator + fit = c3t3().facets_begin(), + end = c3t3().facets_end(); + fit != end; ++fit) + { + const Tr::Cell_handle& cell = fit->first; + const int& index = fit->second; + const Kernel::Point_3& pa = cell->vertex((index+1)&3)->point(); + const Kernel::Point_3& pb = cell->vertex((index+2)&3)->point(); + const Kernel::Point_3& pc = cell->vertex((index+3)&3)->point(); + typedef Kernel::Oriented_side Side; + using CGAL::ON_ORIENTED_BOUNDARY; + const Side sa = plane.oriented_side(pa); + const Side sb = plane.oriented_side(pb); + const Side sc = plane.oriented_side(pc); + if( sa != ON_ORIENTED_BOUNDARY && + sb != ON_ORIENTED_BOUNDARY && + sc != ON_ORIENTED_BOUNDARY && + sb == sa && sc == sa ) + { + // draw_triangle(pa, pb, pc); + } + } + ::glEnd(); + ::glDisable(GL_CLIP_PLANE0); + + ::glBegin(GL_TRIANGLES); + // workaround for Qt-4.2. #if QT_VERSION < 0x040300 # define darker dark #endif - CGALglcolor(this->color().darker(150)); + CGALglcolor(this->color().darker(150)); #undef darker - for(Tr::Finite_cells_iterator - cit = c3t3().triangulation().finite_cells_begin(), - end = c3t3().triangulation().finite_cells_end(); - cit != end; ++cit) - { - if(! c3t3().is_in_complex(cit) ) - continue; - - const Kernel::Point_3& pa = cit->vertex(0)->point(); - const Kernel::Point_3& pb = cit->vertex(1)->point(); - const Kernel::Point_3& pc = cit->vertex(2)->point(); - const Kernel::Point_3& pd = cit->vertex(3)->point(); - typedef Kernel::Oriented_side Side; - using CGAL::ON_ORIENTED_BOUNDARY; - const Side sa = plane.oriented_side(pa); - const Side sb = plane.oriented_side(pb); - const Side sc = plane.oriented_side(pc); - const Side sd = plane.oriented_side(pd); - - if( sa == ON_ORIENTED_BOUNDARY || - sb == ON_ORIENTED_BOUNDARY || - sc == ON_ORIENTED_BOUNDARY || - sd == ON_ORIENTED_BOUNDARY || - sb != sa || sc != sa || sd != sa) + for(Tr::Finite_cells_iterator + cit = c3t3().triangulation().finite_cells_begin(), + end = c3t3().triangulation().finite_cells_end(); + cit != end; ++cit) { - draw_triangle(pa, pb, pc); - draw_triangle(pa, pb, pd); - draw_triangle(pa, pc, pd); - draw_triangle(pb, pc, pd); + if(! c3t3().is_in_complex(cit) ) + continue; + + const Kernel::Point_3& pa = cit->vertex(0)->point(); + const Kernel::Point_3& pb = cit->vertex(1)->point(); + const Kernel::Point_3& pc = cit->vertex(2)->point(); + const Kernel::Point_3& pd = cit->vertex(3)->point(); + typedef Kernel::Oriented_side Side; + using CGAL::ON_ORIENTED_BOUNDARY; + const Side sa = plane.oriented_side(pa); + const Side sb = plane.oriented_side(pb); + const Side sc = plane.oriented_side(pc); + const Side sd = plane.oriented_side(pd); + + if( sa == ON_ORIENTED_BOUNDARY || + sb == ON_ORIENTED_BOUNDARY || + sc == ON_ORIENTED_BOUNDARY || + sd == ON_ORIENTED_BOUNDARY || + sb != sa || sc != sa || sd != sa) + { + // draw_triangle(pa, pb, pc); + // draw_triangle(pa, pb, pd); + // draw_triangle(pa, pc, pd); + // draw_triangle(pb, pc, pd); + } + + // for(int i = 0; i < 4; ++i) { + // if(c3t3().is_in_complex(cit, i)) continue; + // const Point_3& pa = cit->vertex((i+1)&3)->point(); + // const Point_3& pb = cit->vertex((i+2)&3)->point(); + // const Point_3& pc= cit->vertex((i+3)&3)->point(); + // typedef Kernel::Oriented_side Side; + // using CGAL::ON_ORIENTED_BOUNDARY; + // const Side sa = plane.oriented_side(pa); + // const Side sb = plane.oriented_side(pb); + // const Side sc = plane.oriented_side(pc); + + // if( sa == ON_ORIENTED_BOUNDARY || + // sb == ON_ORIENTED_BOUNDARY || + // sc == ON_ORIENTED_BOUNDARY || + // sb != sa || sc != sa ) + // { + // draw_triangle(pa, pb, pc); + // } + // } } + ::glEnd(); + if(!two_side) + ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + }; + void draw(Viewer_interface* viewer) const { + + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_poly); + uniform_attrib(viewer,0); + glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/3); + glUseProgram(0); + glBindVertexArray(0); -// for(int i = 0; i < 4; ++i) { -// if(c3t3().is_in_complex(cit, i)) continue; -// const Point_3& pa = cit->vertex((i+1)&3)->point(); -// const Point_3& pb = cit->vertex((i+2)&3)->point(); -// const Point_3& pc= cit->vertex((i+3)&3)->point(); -// typedef Kernel::Oriented_side Side; -// using CGAL::ON_ORIENTED_BOUNDARY; -// const Side sa = plane.oriented_side(pa); -// const Side sb = plane.oriented_side(pb); -// const Side sc = plane.oriented_side(pc); -// if( sa == ON_ORIENTED_BOUNDARY || -// sb == ON_ORIENTED_BOUNDARY || -// sc == ON_ORIENTED_BOUNDARY || -// sb != sa || sc != sa ) -// { -// draw_triangle(pa, pb, pc); -// } -// } } - ::glEnd(); - if(!two_side) - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - }; + void draw_edges(Viewer_interface* viewer) const { + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer,2); + glDrawArrays(GL_LINES, 0, positions_grid.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer,1); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + } private: - static void draw_triangle(const Kernel::Point_3& pa, - const Kernel::Point_3& pb, - const Kernel::Point_3& pc) { - Kernel::Vector_3 n = cross_product(pb - pa, pc -pa); - n = n / CGAL::sqrt(n*n); + void draw_triangle(const Kernel::Point_3& pa, + const Kernel::Point_3& pb, + const Kernel::Point_3& pc, bool is_cut) { + // workaround for Qt-4.2. +#if QT_VERSION < 0x040300 +# define darker dark +#endif +#undef darker + Kernel::Vector_3 n = cross_product(pb - pa, pc - pa); + n = n / CGAL::sqrt(n*n); - ::glNormal3d(n.x(),n.y(),n.z()); +if(!is_cut) +{ + for(int i=0; i<3; i++) + { - ::glVertex3d(pa.x(),pa.y(),pa.z()); - ::glVertex3d(pb.x(),pb.y(),pb.z()); - ::glVertex3d(pc.x(),pc.y(),pc.z()); - } + color_poly.push_back(this->color().redF()); + color_poly.push_back(this->color().greenF()); + color_poly.push_back(this->color().blueF()); + } +} +else +{ + for(int i=0; i<3; i++) + { - double complex_diag() const { - const Bbox& bbox = this->bbox(); - const double& xdelta = bbox.xmax-bbox.xmin; - const double& ydelta = bbox.ymax-bbox.ymin; - const double& zdelta = bbox.zmax-bbox.zmin; - const double diag = std::sqrt(xdelta*xdelta + - ydelta*ydelta + - zdelta*zdelta); - return diag * 0.7; - } + color_poly.push_back(this->color().darker(150).redF()); + color_poly.push_back(this->color().darker(150).greenF()); + color_poly.push_back(this->color().darker(150).blueF()); + } +} + for(int i=0; i<3; i++) + { + normals.push_back(n.x()); + normals.push_back(n.y()); + normals.push_back(n.z()); + } + positions_poly.push_back(pa.x()); + positions_poly.push_back(pa.y()); + positions_poly.push_back(pa.z()); + + positions_poly.push_back(pb.x()); + positions_poly.push_back(pb.y()); + positions_poly.push_back(pb.z()); + + positions_poly.push_back(pc.x()); + positions_poly.push_back(pc.y()); + positions_poly.push_back(pc.z()); + + } + + void draw_triangle_edges(const Kernel::Point_3& pa, + const Kernel::Point_3& pb, + const Kernel::Point_3& pc) { + // workaround for Qt-4.2. +#if QT_VERSION < 0x040300 +# define darker dark +#endif +#undef darker + Kernel::Vector_3 n = cross_product(pb - pa, pc - pa); + n = n / CGAL::sqrt(n*n); + for(int i=0; i<6; i++) + { + color_lines.push_back(0.0); + color_lines.push_back(0.0); + color_lines.push_back(0.0); + } + positions_lines.push_back(pa.x()); + positions_lines.push_back(pa.y()); + positions_lines.push_back(pa.z()); + + positions_lines.push_back(pb.x()); + positions_lines.push_back(pb.y()); + positions_lines.push_back(pb.z()); + + positions_lines.push_back(pb.x()); + positions_lines.push_back(pb.y()); + positions_lines.push_back(pb.z()); + + positions_lines.push_back(pc.x()); + positions_lines.push_back(pc.y()); + positions_lines.push_back(pc.z()); + + positions_lines.push_back(pc.x()); + positions_lines.push_back(pc.y()); + positions_lines.push_back(pc.z()); + + positions_lines.push_back(pa.x()); + positions_lines.push_back(pa.y()); + positions_lines.push_back(pa.z()); + + } + + + + double complex_diag() const { + const Bbox& bbox = this->bbox(); + const double& xdelta = bbox.xmax-bbox.xmin; + const double& ydelta = bbox.ymax-bbox.ymin; + const double& zdelta = bbox.zmax-bbox.zmin; + const double diag = std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + return diag * 0.7; + } public slots: - void export_facets_in_complex() - { - std::stringstream off_sstream; - c3t3().output_facets_in_complex_to_off(off_sstream); - std::string backup = off_sstream.str(); - // Try to read .off in a polyhedron - Scene_polyhedron_item* item = new Scene_polyhedron_item(); - if(!item->load(off_sstream)) + void export_facets_in_complex() { - delete item; - off_sstream.str(backup); + std::stringstream off_sstream; + c3t3().output_facets_in_complex_to_off(off_sstream); + std::string backup = off_sstream.str(); + // Try to read .off in a polyhedron + Scene_polyhedron_item* item = new Scene_polyhedron_item(); + if(!item->load(off_sstream)) + { + delete item; + off_sstream.str(backup); - // Try to read .off in a polygon soup - Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item; + // Try to read .off in a polygon soup + Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item; - if(!soup_item->load(off_sstream)) { - delete soup_item; - return; - } + if(!soup_item->load(off_sstream)) { + delete soup_item; + return; + } - soup_item->setName(QString("%1_%2").arg(this->name()).arg("facets")); - last_known_scene->addItem(soup_item); + soup_item->setName(QString("%1_%2").arg(this->name()).arg("facets")); + last_known_scene->addItem(soup_item); + } + else{ + item->setName(QString("%1_%2").arg(this->name()).arg("facets")); + last_known_scene->addItem(item); + } } - else{ - item->setName(QString("%1_%2").arg(this->name()).arg("facets")); - last_known_scene->addItem(item); - } - } public: - QMenu* contextMenu() - { - const char* prop_name = "Menu modified by Scene_c3t3_item."; + QMenu* contextMenu() + { + const char* prop_name = "Menu modified by Scene_c3t3_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) { - QAction* actionExportFacetsInComplex = - menu->addAction(tr("Export facets in complex")); - actionExportFacetsInComplex->setObjectName("actionExportFacetsInComplex"); - connect(actionExportFacetsInComplex, - SIGNAL(triggered()),this, - SLOT(export_facets_in_complex())); + if(!menuChanged) { + QAction* actionExportFacetsInComplex = + menu->addAction(tr("Export facets in complex")); + actionExportFacetsInComplex->setObjectName("actionExportFacetsInComplex"); + connect(actionExportFacetsInComplex, + SIGNAL(triggered()),this, + SLOT(export_facets_in_complex())); + } + return menu; } - return menu; - } - void set_scene(Scene_interface* scene){ last_known_scene=scene; } + void set_scene(Scene_interface* scene){ last_known_scene=scene; } private: - C3t3 c3t3_; - qglviewer::ManipulatedFrame* frame; - Scene_interface* last_known_scene; + + struct light_info + { + //position + GLfloat position[4]; + + //ambient + GLfloat ambient[4]; + + //diffuse + GLfloat diffuse[4]; + + //specular + GLfloat specular[4]; + GLfloat spec_power; + + }; + C3t3 c3t3_; + qglviewer::ManipulatedFrame* frame; + Scene_interface* last_known_scene; + + + std::vector positions_lines; + std::vector positions_grid; + std::vector positions_poly; + std::vector normals; + std::vector color_lines; + std::vector color_poly; + std::vector color_grid; + + GLint location[10]; + GLuint vao[2]; + GLuint buffer[7]; + GLuint rendering_program_lines; + GLuint rendering_program_poly; + + void initialize_buffers() + { + glBindVertexArray(vao[0]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); + glBufferData(GL_ARRAY_BUFFER, + (positions_poly.size())*sizeof(float), + positions_poly.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, + (positions_lines.size())*sizeof(float), + positions_lines.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, + (normals.size())*sizeof(float), + normals.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, + (color_poly.size())*sizeof(float), + color_poly.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); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[4]); + glBufferData(GL_ARRAY_BUFFER, + (color_lines.size())*sizeof(float), + color_lines.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(4, //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(4); + + glBindVertexArray(vao[1]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[5]); + glBufferData(GL_ARRAY_BUFFER, + (positions_grid.size())*sizeof(float), + positions_grid.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[6]); + glBufferData(GL_ARRAY_BUFFER, + (color_grid.size())*sizeof(float), + color_grid.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(4, //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(4); + glBindVertexArray(0); + } + void compile_shaders() + { + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) in vec3 positions; \n" + "layout (location = 2) in vec3 vNormals; \n" + "layout (location = 3) in vec3 color_facets; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform mat4 mv_matrix; \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" + " diffuse = abs(dot(N,L)) * light_diff * color_facets; \n" + " vec3 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" + + " fColors = light_amb*color_facets + 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" + "precision mediump float; \n" + "in vec3 fColors; \n" + + "out 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, 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); + + //Clean-up + glDeleteShader(vertex_shader); + + rendering_program_poly = program; + + //For the edges + static const GLchar* vertex_shader_source_lines[] = + { + "#version 300 es \n" + " \n" + "layout (location = 1) in vec3 positions; \n" + "layout (location = 4) in vec3 color_lines; \n" + + "uniform mat4 mvp_matrix; \n" + "uniform mat4 f_matrix; \n" + "vec4 positions_lines = vec4(positions, 1.0); \n" + "out highp vec3 fColors; \n" + " \n" + + "void main(void) \n" + "{ \n" + " fColors = color_lines; \n" + " gl_Position = mvp_matrix * f_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); + //Clean-up + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + rendering_program_lines = program; + + } + void uniform_attrib(Viewer_interface* viewer, int mode) const + { + light_info light; + GLint is_both_sides = 0; + GLfloat mvp_mat[16]; + GLfloat mv_mat[16]; + GLfloat f_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); + + + //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); + //Polys + if(mode ==0) + { + + glUseProgram(rendering_program_poly); + 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); + } + //Edges + else if(mode ==1) + { + for(int i=0; i<16; i++) + { + if(i%5 == 0) + f_mat[i] = 1.0; + else + f_mat[i] = 0.0; + } + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[6], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[7], 1, GL_FALSE, f_mat); + + } + //Grid + else if(mode ==2) + { + for(int i=0; i<16; i++) + f_mat[i] = frame->matrix()[i]; + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[6], 1, GL_FALSE, mvp_mat); + glUniformMatrix4fv(location[7], 1, GL_FALSE, f_mat); + + } + + } + void compute_elements() + { + positions_lines.clear(); + positions_poly.clear(); + color_lines.clear(); + color_grid.clear(); + color_poly.clear(); + normals.clear(); + + //The grid + { + float x = (2*(float)complex_diag())/10.0; + float y = (2*(float)complex_diag())/10.0; + for(int u = 0; u < 11; u++) + { + + positions_grid.push_back(-(float)complex_diag() + x* u); + positions_grid.push_back(-(float)complex_diag()); + positions_grid.push_back(0.0); + + positions_grid.push_back(-(float)complex_diag() + x* u); + positions_grid.push_back((float)complex_diag()); + positions_grid.push_back(0.0); + } + for(int v=0; v<11; v++) + { + + positions_grid.push_back(-(float)complex_diag()); + positions_grid.push_back(-(float)complex_diag() + v * y); + positions_grid.push_back(0.0); + + positions_grid.push_back((float)complex_diag()); + positions_grid.push_back(-(float)complex_diag() + v * y); + positions_grid.push_back(0.0); + } + float colors[3]; + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + + for(int i=0; i< 132; i++) + { + color_grid.push_back(colors[i%3]); + } + } + + //The facets + { + if(isEmpty()) + return; + + + const Kernel::Plane_3& plane = this->plane(); + GLdouble clip_plane[4]; + clip_plane[0] = -plane.a(); + clip_plane[1] = -plane.b(); + clip_plane[2] = -plane.c(); + clip_plane[3] = -plane.d(); + + + + for(C3t3::Facet_iterator + fit = c3t3().facets_begin(), + end = c3t3().facets_end(); + fit != end; ++fit) + { + const Tr::Cell_handle& cell = fit->first; + const int& index = fit->second; + const Kernel::Point_3& pa = cell->vertex((index+1)&3)->point(); + const Kernel::Point_3& pb = cell->vertex((index+2)&3)->point(); + const Kernel::Point_3& pc = cell->vertex((index+3)&3)->point(); + typedef Kernel::Oriented_side Side; + using CGAL::ON_ORIENTED_BOUNDARY; + const Side sa = plane.oriented_side(pa); + const Side sb = plane.oriented_side(pb); + const Side sc = plane.oriented_side(pc); + bool is_showned = false; + if(pa.x() * clip_plane[0] + pa.y() * clip_plane[1] + pa.z() * clip_plane[2] + clip_plane[3] > 0 + && pb.x() * clip_plane[0] + pb.y() * clip_plane[1] + pb.z() * clip_plane[2] + clip_plane[3] > 0 + && pc.x() * clip_plane[0] + pc.y() * clip_plane[1] + pc.z() * clip_plane[2] + clip_plane[3] > 0) + is_showned = true; + + if(is_showned && sa != ON_ORIENTED_BOUNDARY && + sb != ON_ORIENTED_BOUNDARY && + sc != ON_ORIENTED_BOUNDARY && + sb == sa && sc == sa ) + { + draw_triangle(pa, pb, pc, false); + draw_triangle_edges(pa, pb, pc); + } + + } + + + for(Tr::Finite_cells_iterator + cit = c3t3().triangulation().finite_cells_begin(), + end = c3t3().triangulation().finite_cells_end(); + cit != end; ++cit) + { + if(! c3t3().is_in_complex(cit) ) + continue; + + const Kernel::Point_3& pa = cit->vertex(0)->point(); + const Kernel::Point_3& pb = cit->vertex(1)->point(); + const Kernel::Point_3& pc = cit->vertex(2)->point(); + const Kernel::Point_3& pd = cit->vertex(3)->point(); + typedef Kernel::Oriented_side Side; + using CGAL::ON_ORIENTED_BOUNDARY; + const Side sa = plane.oriented_side(pa); + const Side sb = plane.oriented_side(pb); + const Side sc = plane.oriented_side(pc); + const Side sd = plane.oriented_side(pd); + + if( sa == ON_ORIENTED_BOUNDARY || + sb == ON_ORIENTED_BOUNDARY || + sc == ON_ORIENTED_BOUNDARY || + sd == ON_ORIENTED_BOUNDARY || + sb != sa || sc != sa || sd != sa) + { + draw_triangle(pa,pb,pc, true); + draw_triangle(pa,pb,pd, true); + draw_triangle(pa,pc,pd, true); + draw_triangle(pb,pc,pd, true); + + draw_triangle_edges(pa,pb,pc); + draw_triangle_edges(pa,pb,pd); + draw_triangle_edges(pa,pc,pd); + draw_triangle_edges(pb,pc,pd); + + } + + + } + + } + + + + location[0] = glGetUniformLocation(rendering_program_poly, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_poly, "mv_matrix"); + location[2] = glGetUniformLocation(rendering_program_poly, "light_pos"); + location[3] = glGetUniformLocation(rendering_program_poly, "light_diff"); + location[4] = glGetUniformLocation(rendering_program_poly, "light_spec"); + location[5] = glGetUniformLocation(rendering_program_poly, "light_amb"); + location[6] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[7] = glGetUniformLocation(rendering_program_lines, "f_matrix"); + } + }; Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, @@ -348,58 +961,58 @@ Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, const bool protect_features, Scene_interface* scene) { - if(!pMesh) return 0; + if(!pMesh) return 0; - // remesh + // remesh - // Set mesh criteria - Edge_criteria edge_criteria(facet_sizing); - Facet_criteria facet_criteria(angle, facet_sizing, approx); // angle, size, approximation - Cell_criteria cell_criteria(tet_shape, tet_sizing); // radius-edge ratio, size - Mesh_criteria criteria(edge_criteria, facet_criteria, cell_criteria); + // Set mesh criteria + Edge_criteria edge_criteria(facet_sizing); + Facet_criteria facet_criteria(angle, facet_sizing, approx); // angle, size, approximation + Cell_criteria cell_criteria(tet_shape, tet_sizing); // radius-edge ratio, size + Mesh_criteria criteria(edge_criteria, facet_criteria, cell_criteria); - CGAL::Timer timer; - timer.start(); - std::cerr << "Meshing file \"" << qPrintable(filename) << "\"\n"; - std::cerr << " angle: " << angle << std::endl - << " facets size bound: " << facet_sizing << std::endl - << " approximation bound: " << approx << std::endl - << " tetrahedra size bound: " << tet_sizing << std::endl; - std::cerr << "Build AABB tree..."; - // Create domain - Mesh_domain domain(*pMesh); - if(protect_features) { - domain.detect_features(); - } - std::cerr << "done (" << timer.time() << " ms)" << std::endl; + CGAL::Timer timer; + timer.start(); + std::cerr << "Meshing file \"" << qPrintable(filename) << "\"\n"; + std::cerr << " angle: " << angle << std::endl + << " facets size bound: " << facet_sizing << std::endl + << " approximation bound: " << approx << std::endl + << " tetrahedra size bound: " << tet_sizing << std::endl; + std::cerr << "Build AABB tree..."; + // Create domain + Mesh_domain domain(*pMesh); + if(protect_features) { + domain.detect_features(); + } + std::cerr << "done (" << timer.time() << " ms)" << std::endl; - // Meshing - std::cerr << "Mesh..."; - CGAL::parameters::internal::Features_options features = - protect_features ? - CGAL::parameters::features(domain) : - CGAL::parameters::no_features(); + // Meshing + std::cerr << "Mesh..."; + CGAL::parameters::internal::Features_options features = + protect_features ? + CGAL::parameters::features(domain) : + CGAL::parameters::no_features(); - Scene_c3t3_item* new_item = - new Scene_c3t3_item(CGAL::make_mesh_3(domain, criteria, features)); - new_item->set_scene(scene); - std::cerr << "done (" << timer.time() << " ms, " << new_item->c3t3().triangulation().number_of_vertices() << " vertices)" << std::endl; + Scene_c3t3_item* new_item = + new Scene_c3t3_item(CGAL::make_mesh_3(domain, criteria, features)); + new_item->set_scene(scene); + std::cerr << "done (" << timer.time() << " ms, " << new_item->c3t3().triangulation().number_of_vertices() << " vertices)" << std::endl; - if(new_item->c3t3().triangulation().number_of_vertices() > 0) - { - std::ofstream medit_out("out.mesh"); - new_item->c3t3().output_to_medit(medit_out); + if(new_item->c3t3().triangulation().number_of_vertices() > 0) + { + std::ofstream medit_out("out.mesh"); + new_item->c3t3().output_to_medit(medit_out); - const Scene_item::Bbox& bbox = new_item->bbox(); - new_item->setPosition((float)(bbox.xmin + bbox.xmax)/2.f, - (float)(bbox.ymin + bbox.ymax)/2.f, - (float)(bbox.zmin + bbox.zmax)/2.f); - return new_item; - } - else { - delete new_item; - return 0; - } + const Scene_item::Bbox& bbox = new_item->bbox(); + new_item->setPosition((float)(bbox.xmin + bbox.xmax)/2.f, + (float)(bbox.ymin + bbox.ymax)/2.f, + (float)(bbox.zmin + bbox.zmax)/2.f); + return new_item; + } + else { + delete new_item; + return 0; + } } #include "Scene_c3t3_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 220ddccb9f1..0a0567f5229 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -275,7 +275,6 @@ Scene::drawWithNames(Viewer_interface* viewer) void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { - // Flat/Gouraud OpenGL drawing for(int index = 0; index < m_entries.size(); ++index) { @@ -437,8 +436,8 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) } } - ms_splatting->beginAttributePass(); - for(int index = 0; index < m_entries.size(); ++index) + ms_splatting->beginAttributePass(); + for(int index = 0; index < m_entries.size(); ++index) { Scene_item& item = *m_entries[index]; if(item.visible() && item.renderingMode() == Splatting) { diff --git a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h index ff6b79af22d..69ff7ab440c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h @@ -104,7 +104,6 @@ private: const Tr::Point& pc) { Tr::Geom_traits::Vector_3 n = cross_product(pb - pa, pc -pa); n = n / CGAL::sqrt(n*n); - ::glNormal3d(n.x(),n.y(),n.z()); ::glVertex3d(pa.x(),pa.y(),pa.z()); diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index c38cf9be127..4ea7130e06a 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -602,6 +602,7 @@ void Scene_points_with_normal_item::compute_normals_and_vertices(void) normals.push_back(p.normal().z()); #ifdef CGAL_GLEW_ENABLED tex_coords.push_back(p.radius()); + ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); #endif positions_splats.push_back(p.x()); positions_splats.push_back(p.y()); @@ -853,7 +854,20 @@ void Scene_points_with_normal_item::draw_splats() const void Scene_points_with_normal_item::draw_splats(Viewer_interface* viewer) const { //Needs to be re-thinked because the GlSplat Renderer is deprecated and is a big part of the scene class. - draw_splats(); + + // TODO add support for selection + ::glBegin(GL_POINTS); + for ( Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + ::glNormal3dv(&p.normal().x()); +#ifdef CGAL_GLEW_ENABLED + ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); +#endif + ::glVertex3dv(&p.x()); + } + ::glEnd(); + } void Scene_points_with_normal_item::draw_edges(Viewer_interface* viewer) const diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 61df7bdab00..436b4d4568c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -458,7 +458,7 @@ Scene_polygon_soup_item::triangulate_polygon(Polygons_iterator pit) void Scene_polygon_soup_item::compute_normals_and_vertices(){ //get the vertices and normals - +/* typedef Polygon_soup::Polygons::size_type size_type; positions_poly.clear(); normals.clear(); @@ -517,7 +517,20 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ positions_lines.push_back(pb.z()); positions_lines.push_back(1.0); } + }*/ + positions_poly.clear(); + positions_poly.push_back(0.0); + positions_poly.push_back(0.0); + positions_poly.push_back(0.0); + positions_poly.push_back(1.0); + for(int i = 0; i < 360; i+=2) + { + positions_poly.push_back(cos(i)); + positions_poly.push_back(sin(i)); + positions_poly.push_back(0.0); + positions_poly.push_back(1.0); } + location[0] = glGetUniformLocation(rendering_program_poly, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program_poly, "mv_matrix"); location[2] = glGetUniformLocation(rendering_program_poly, "light_pos"); @@ -727,7 +740,7 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { glUseProgram(rendering_program_poly); //draw the polygons // the third argument is the number of vec4 that will be entered - glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); + glDrawArrays(GL_TRIANGLE_FAN, 0, positions_poly.size()/4); // Clean-up glUseProgram(0); glBindVertexArray(0); @@ -754,7 +767,7 @@ void Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { if(soup == 0) return; - glBindVertexArray(vao); + /* glBindVertexArray(vao); uniform_attrib(viewer,1); glUseProgram(rendering_program_lines); //draw the edges @@ -762,7 +775,7 @@ Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { // Clean-up glUseProgram(0); glBindVertexArray(0); - +*/ } bool From c7e8bc22d821a3954293de35f436f0d429c1a8a7 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Mar 2015 16:47:55 +0100 Subject: [PATCH 55/62] Draw point implementation I realized I forgot to add a call to contextual_changed in the wiremode and points mode. --- .../Polyhedron_demo_mesh_3_plugin_cgal_code.cpp | 16 ++++++++++++++++ Polyhedron/demo/Polyhedron/Scene.cpp | 2 ++ 2 files changed, 18 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp index 42e828c8ce3..642daa51e06 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp @@ -304,7 +304,22 @@ public: glBindVertexArray(0); } + void draw_points(Viewer_interface * viewer) const + { + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer,1); + glDrawArrays(GL_POINTS, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); + glBindVertexArray(vao[1]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer,2); + glDrawArrays(GL_LINES, 0, positions_grid.size()/3); + glUseProgram(0); + glBindVertexArray(0); + } private: void draw_triangle(const Kernel::Point_3& pa, const Kernel::Point_3& pb, @@ -930,6 +945,7 @@ private: draw_triangle_edges(pa,pc,pd); draw_triangle_edges(pb,pc,pd); + } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 0a0567f5229..d67e47a8d3e 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -383,6 +383,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) } } } + item.contextual_changed(); if(with_names) { ::glPopName(); } @@ -411,6 +412,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) item.draw_points(); } } + item.contextual_changed(); if(with_names) { ::glPopName(); } From c270b32c24d4b87828e236e3f657d82d493b0880 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Mar 2015 17:02:24 +0100 Subject: [PATCH 56/62] bbox_item upgraded --- .../Polyhedron_demo_trivial_plugin.cpp | 373 +++++++++++++----- 1 file changed, 272 insertions(+), 101 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp index 8bed5d1ad8e..889e3548a01 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp @@ -1,149 +1,320 @@ +#include #include #include "Scene_item.h" #include "Scene_interface.h" #include +#include "Viewer_interface.h" #include #include class Q_DECL_EXPORT Scene_bbox_item : public Scene_item { - Q_OBJECT + Q_OBJECT public: - Scene_bbox_item(const Scene_interface* scene_interface) - : scene(scene_interface) - {} + Scene_bbox_item(const Scene_interface* scene_interface) + : scene(scene_interface) + { - bool isFinite() const { return true; } - bool isEmpty() const { return true; } - Bbox bbox() const { return Bbox(); } + positions_lines.resize(0); + glGenVertexArrays(1, vao); + //Generates an integer which will be used as ID for each buffer + glGenBuffers(1, buffer); + compile_shaders(); + } + ~Scene_bbox_item() + { + glDeleteBuffers(1, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); + } + bool isFinite() const { return true; } + bool isEmpty() const { return true; } + Bbox bbox() const { return Bbox(); } - Scene_bbox_item* clone() const { - return 0; - } + Scene_bbox_item* clone() const { + return 0; + } - QString toolTip() const { - const Bbox& bb = scene->bbox(); - return QString("

Scene bounding box

" - "

x range: (%1, %2)
" - "y range: (%3, %4)
" - "z range: (%5, %6)

") - .arg(bb.xmin).arg(bb.xmax) - .arg(bb.ymin).arg(bb.ymax) - .arg(bb.zmin).arg(bb.zmax); - } + QString toolTip() const { + const Bbox& bb = scene->bbox(); + return QString("

Scene bounding box

" + "

x range: (%1, %2)
" + "y range: (%3, %4)
" + "z range: (%5, %6)

") + .arg(bb.xmin).arg(bb.xmax) + .arg(bb.ymin).arg(bb.ymax) + .arg(bb.zmin).arg(bb.zmax); + } - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { - return (m == Wireframe); - } + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const { + return (m == Wireframe); + } - // Flat/Gouraud OpenGL drawing - void draw() const {} + // Flat/Gouraud OpenGL drawing + void draw() const {} - // Wireframe OpenGL drawing - void draw_edges() const { - const Bbox& bb = scene->bbox(); - ::glBegin(GL_LINES); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, - bb.xmax, bb.ymin, bb.zmin); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, - bb.xmin, bb.ymax, bb.zmin); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, - bb.xmin, bb.ymin, bb.zmax); - - gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, - bb.xmax, bb.ymax, bb.zmin); - gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, - bb.xmax, bb.ymin, bb.zmax); - - gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, - bb.xmax, bb.ymax, bb.zmin); - gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, - bb.xmin, bb.ymax, bb.zmax); - - gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, - bb.xmax, bb.ymin, bb.zmax); - gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, - bb.xmin, bb.ymax, bb.zmax); - - gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, - bb.xmin, bb.ymax, bb.zmax); - gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, - bb.xmax, bb.ymin, bb.zmax); - gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, - bb.xmax, bb.ymax, bb.zmin); - ::glEnd(); - } + // Wireframe OpenGL drawing + void draw_edges() const { + const Bbox& bb = scene->bbox(); + ::glBegin(GL_LINES); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmax, bb.ymin, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmin, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmin, bb.ymin, bb.zmax); + + gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, + bb.xmax, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, + bb.xmax, bb.ymin, bb.zmax); + + gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, + bb.xmax, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, + bb.xmin, bb.ymax, bb.zmax); + + gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, + bb.xmax, bb.ymin, bb.zmax); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, + bb.xmin, bb.ymax, bb.zmax); + + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmin, bb.ymax, bb.zmax); + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmax, bb.ymin, bb.zmax); + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmax, bb.ymax, bb.zmin); + ::glEnd(); + } + void draw_edges(Viewer_interface* viewer) const + { + glBindVertexArray(vao[0]); + glUseProgram(rendering_program_lines); + uniform_attrib(viewer); + glDrawArrays(GL_LINES, 0, positions_lines.size()/3); + glUseProgram(0); + glBindVertexArray(0); + + } + + void changed() + { + compute_elements(); + initialize_buffers(); + } private: - static void gl_draw_edge(double px, double py, double pz, - double qx, double qy, double qz) - { - ::glVertex3d(px,py,pz); - ::glVertex3d(qx,qy,qz); - } + static void gl_draw_edge(double px, double py, double pz, + double qx, double qy, double qz) + { + ::glVertex3d(px,py,pz); + ::glVertex3d(qx,qy,qz); + } - const Scene_interface* scene; + std::vector positions_lines; + GLint location[2]; + GLuint vao[1]; + GLuint buffer[1]; + GLuint rendering_program_lines; + + void 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 + 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); + + glBindVertexArray(0); + } + void compile_shaders() + { + //fill the vertex shader + static const GLchar* vertex_shader_source[] = + { + "#version 300 es \n" + " \n" + "layout (location = 0) 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" + }; + + //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, 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); + glDeleteShader(fragment_shader); + rendering_program_lines = program; + } + void uniform_attrib(Viewer_interface* viewer) const + { + GLfloat colors[3]; + GLfloat mvp_mat[16]; + + //fills the MVP and MV matrices. + + GLdouble d_mat[16]; + viewer->camera()->getModelViewProjectionMatrix(d_mat); + for (int i=0; i<16; ++i) + mvp_mat[i] = GLfloat(d_mat[i]); + + + //fills the arraw of colors with the current color + colors[0] = this->color().redF(); + colors[1] = this->color().greenF(); + colors[2] = this->color().blueF(); + + + glUseProgram(rendering_program_lines); + glUniformMatrix4fv(location[0], 1, GL_FALSE, mvp_mat); + glUniform3fv(location[1],1,colors); + } + void compute_elements() + { + positions_lines.clear(); + const Bbox& bb = scene->bbox(); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmax); + + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmax); + + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmin); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmax); + + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmax); + + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmin); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymin); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmax); + positions_lines.push_back(bb.xmax); positions_lines.push_back(bb.ymax); positions_lines.push_back(bb.zmin); + + location[0] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); + location[1] = glGetUniformLocation(rendering_program_lines, "color"); + } + + const Scene_interface* scene; }; #include "Polyhedron_demo_plugin_interface.h" class Polyhedron_demo_trivial_plugin : - public QObject, - public Polyhedron_demo_plugin_interface + public QObject, + public Polyhedron_demo_plugin_interface { - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface); - QList actions() const { - return QList() << actionBbox; - } + void init(QMainWindow* mainWindow, Scene_interface* scene_interface); + QList actions() const { + return QList() << actionBbox; + } - bool applicable(QAction*) const { - return true; - } + bool applicable(QAction*) const { + return true; + } public slots: - void bbox(); - void enableAction(); + + void bbox(); + void enableAction(); private: - Scene_interface* scene; - QAction* actionBbox; + Scene_interface* scene; + QAction* actionBbox; + }; // end Polyhedron_demo_trivial_plugin void Polyhedron_demo_trivial_plugin::init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - scene = scene_interface; - actionBbox = new QAction(tr("Create bbox"), mainWindow); - connect(actionBbox, SIGNAL(triggered()), - this, SLOT(bbox())); + scene = scene_interface; + actionBbox = new QAction(tr("Create bbox"), mainWindow); + connect(actionBbox, SIGNAL(triggered()), + this, SLOT(bbox())); } void Polyhedron_demo_trivial_plugin::bbox() { - for(int i = 0, end = scene->numberOfEntries(); - i < end; ++i) - { - if(qobject_cast(scene->item(i))) - return; - } - Scene_item* item = new Scene_bbox_item(scene); - connect(item, SIGNAL(destroyed()), - this, SLOT(enableAction())); - item->setName("Scene bbox"); - item->setColor(Qt::black); - item->setRenderingMode(Wireframe); - scene->addItem(item); - actionBbox->setEnabled(false); + for(int i = 0, end = scene->numberOfEntries(); + i < end; ++i) + { + if(qobject_cast(scene->item(i))) + return; + } + Scene_item* item = new Scene_bbox_item(scene); + connect(item, SIGNAL(destroyed()), + this, SLOT(enableAction())); + item->setName("Scene bbox"); + item->setColor(Qt::black); + item->setRenderingMode(Wireframe); + scene->addItem(item); + actionBbox->setEnabled(false); } void Polyhedron_demo_trivial_plugin::enableAction() { - actionBbox->setEnabled(true); + actionBbox->setEnabled(true); } Q_EXPORT_PLUGIN2(Polyhedron_demo_trivial_plugin, Polyhedron_demo_trivial_plugin) From fa9ec055a6c9cf401a7a40c4cb712fecdc05d865 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Mar 2015 17:39:55 +0100 Subject: [PATCH 57/62] little fix --- .../Polyhedron/Scene_polygon_soup_item.cpp | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 436b4d4568c..0b8dcc891bb 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -458,9 +458,10 @@ Scene_polygon_soup_item::triangulate_polygon(Polygons_iterator pit) void Scene_polygon_soup_item::compute_normals_and_vertices(){ //get the vertices and normals -/* + typedef Polygon_soup::Polygons::size_type size_type; positions_poly.clear(); + positions_lines.clear(); normals.clear(); for(Polygons_iterator it = soup->polygons.begin(); it != soup->polygons.end(); ++it) @@ -517,20 +518,10 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ positions_lines.push_back(pb.z()); positions_lines.push_back(1.0); } - }*/ - positions_poly.clear(); - positions_poly.push_back(0.0); - positions_poly.push_back(0.0); - positions_poly.push_back(0.0); - positions_poly.push_back(1.0); - for(int i = 0; i < 360; i+=2) - { - positions_poly.push_back(cos(i)); - positions_poly.push_back(sin(i)); - positions_poly.push_back(0.0); - positions_poly.push_back(1.0); } + + location[0] = glGetUniformLocation(rendering_program_poly, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program_poly, "mv_matrix"); location[2] = glGetUniformLocation(rendering_program_poly, "light_pos"); @@ -546,7 +537,7 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ Scene_polygon_soup_item::Scene_polygon_soup_item() : Scene_item(), - soup(0),positions_poly(0), normals(0), + soup(0),positions_poly(0),positions_lines(0), normals(0), oriented(false) { glGenVertexArrays(1, &vao); @@ -740,7 +731,7 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { glUseProgram(rendering_program_poly); //draw the polygons // the third argument is the number of vec4 that will be entered - glDrawArrays(GL_TRIANGLE_FAN, 0, positions_poly.size()/4); + glDrawArrays(GL_TRIANGLES, 0, positions_poly.size()/4); // Clean-up glUseProgram(0); glBindVertexArray(0); @@ -767,7 +758,7 @@ void Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { if(soup == 0) return; - /* glBindVertexArray(vao); + glBindVertexArray(vao); uniform_attrib(viewer,1); glUseProgram(rendering_program_lines); //draw the edges @@ -775,7 +766,7 @@ Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { // Clean-up glUseProgram(0); glBindVertexArray(0); -*/ + } bool From 1b11fca61463a51973b5ed9f66f4294910404752 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 25 Mar 2015 18:05:00 +0100 Subject: [PATCH 58/62] slow draw of polyhedron_items fixed --- Polyhedron/demo/Polyhedron/Scene.cpp | 2 +- .../demo/Polyhedron/Scene_polygon_soup_item.cpp | 1 - .../demo/Polyhedron/Scene_polyhedron_item.cpp | 15 ++++----------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index d67e47a8d3e..7d811b0b96e 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -286,7 +286,6 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) { if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) { - item.selection_changed(false); ::glEnable(GL_LIGHTING); ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); ::glPointSize(2.f); @@ -299,6 +298,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) else { + item.selection_changed(false); CGALglcolor(item.color()); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 0b8dcc891bb..540b2f50fba 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -722,7 +722,6 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { if(soup == 0) return; - //Calls the buffer info again so that it's the right one used even if //there are several objects drawn glBindVertexArray(vao); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 46ae552a7cb..2e7b40514c9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -574,9 +574,6 @@ Scene_polyhedron_item::uniform_attrib(Viewer_interface* viewer, int mode) const glUniformMatrix4fv(location[7], 1, GL_FALSE, mvp_mat); } - - - } void Scene_polyhedron_item::compute_normals_and_vertices(void) @@ -1014,13 +1011,8 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) 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); - uniform_attrib(viewer,0); - //draw the polygons - // the third argument is the number of vec4 that will be entered glDrawArrays(GL_TRIANGLES, 0, positions_facets.size()/4); glUseProgram(0); glBindVertexArray(0); @@ -1108,12 +1100,13 @@ void Scene_polyhedron_item::selection_changed(bool p_is_selected) { if(p_is_selected != is_selected) - {is_selected = p_is_selected; + { + is_selected = p_is_selected; compute_colors(); + std::cout<<"coucou"< Date: Thu, 26 Mar 2015 09:31:34 +0100 Subject: [PATCH 59/62] Selection improve I added a vao for handling the selection color change, which is now instant. --- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 195 +++++++++++++----- .../demo/Polyhedron/Scene_polyhedron_item.h | 7 +- 2 files changed, 146 insertions(+), 56 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 2e7b40514c9..9b72f0e3515 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -273,18 +273,15 @@ Scene_polyhedron_item::triangulate_facet_color(Facet_iterator fit) for(int i = 0; i<3; ++i) { const int this_patch_id = fit->patch_id(); - if(is_selected) - { - color_facets.push_back(colors_[this_patch_id].lighter(120).redF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).greenF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).blueF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).redF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).greenF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).blueF()); - } - else - { + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).redF()); + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).greenF()); + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).blueF()); + + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).redF()); + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).greenF()); + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).blueF()); + color_facets.push_back(colors_[this_patch_id].redF()); color_facets.push_back(colors_[this_patch_id].greenF()); color_facets.push_back(colors_[this_patch_id].blueF()); @@ -293,7 +290,7 @@ Scene_polyhedron_item::triangulate_facet_color(Facet_iterator fit) color_facets.push_back(colors_[this_patch_id].greenF()); color_facets.push_back(colors_[this_patch_id].blueF()); - } + } } } @@ -390,9 +387,79 @@ Scene_polyhedron_item::initialize_buffers() ); glEnableVertexAttribArray(4); + + glBindVertexArray(vao[1]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[5]); + glBufferData(GL_ARRAY_BUFFER, + (positions_facets.size())*sizeof(float), + positions_facets.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[6]); + glBufferData(GL_ARRAY_BUFFER, + (positions_lines.size())*sizeof(float), + positions_lines.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[7]); + glBufferData(GL_ARRAY_BUFFER, + (normals.size())*sizeof(float), + normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[8]); + glBufferData(GL_ARRAY_BUFFER, + (color_facets_selected.size())*sizeof(float), + color_facets_selected.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(3); + + glBindBuffer(GL_ARRAY_BUFFER, buffer[9]); + glBufferData(GL_ARRAY_BUFFER, + (color_lines_selected.size())*sizeof(float), + color_lines_selected.data(), GL_STATIC_DRAW); + glVertexAttribPointer(4, + 3, + GL_FLOAT, + GL_FALSE, + 0, + NULL + ); + glEnableVertexAttribArray(4); // Clean-up glBindVertexArray(0); + } void @@ -703,10 +770,10 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) void Scene_polyhedron_item::compute_colors() { - GLfloat colors[4]; color_lines.clear(); color_facets.clear(); - + color_lines_selected.clear(); + color_facets_selected.clear(); //Facets typedef typename Polyhedron::Traits Kernel; typedef typename Kernel::Point_3 Point; @@ -719,19 +786,7 @@ Scene_polyhedron_item::compute_colors() // int patch_id = -1; Facet_iterator f = poly->facets_begin(); - QColor temp = colors_[f->patch_id()]; - if(is_selected) - { - colors[0]=0.0; - colors[1]=0.0; - colors[2]=0.0; - } - else - { - colors[0]=temp.lighter(50).redF(); - colors[1]=temp.lighter(50).greenF(); - colors[2]=temp.lighter(50).blueF(); - } + for(f = poly->facets_begin(); f != poly->facets_end(); f++) @@ -746,18 +801,15 @@ Scene_polyhedron_item::compute_colors() { const int this_patch_id = f->patch_id(); - if(is_selected) - { - color_facets.push_back(colors_[this_patch_id].lighter(120).redF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).greenF()); - color_facets.push_back(colors_[this_patch_id].lighter(120).blueF()); - } - else - { + + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).redF()); + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).greenF()); + color_facets_selected.push_back(colors_[this_patch_id].lighter(120).blueF()); + color_facets.push_back(colors_[this_patch_id].redF()); color_facets.push_back(colors_[this_patch_id].greenF()); color_facets.push_back(colors_[this_patch_id].blueF()); - } + } } @@ -772,13 +824,20 @@ Scene_polyhedron_item::compute_colors() he++) { if(he->is_feature_edge()) continue; - color_lines.push_back(colors[0]); - color_lines.push_back(colors[1]); - color_lines.push_back(colors[2]); - color_lines.push_back(colors[0]); - color_lines.push_back(colors[1]); - color_lines.push_back(colors[2]); + color_lines_selected.push_back(0.0); + color_lines_selected.push_back(0.0); + color_lines_selected.push_back(0.0); + + color_lines_selected.push_back(0.0); + color_lines_selected.push_back(0.0); + color_lines_selected.push_back(0.0); + + color_lines.push_back(this->color().lighter(50).redF()); + color_lines.push_back(this->color().lighter(50).greenF()); + color_lines.push_back(this->color().lighter(50).blueF()); + + } } @@ -794,6 +853,14 @@ Scene_polyhedron_item::compute_colors() color_lines.push_back(1.0); color_lines.push_back(0.0); color_lines.push_back(0.0); + + color_lines_selected.push_back(1.0); + color_lines_selected.push_back(0.0); + color_lines_selected.push_back(0.0); + + color_lines_selected.push_back(1.0); + color_lines_selected.push_back(0.0); + color_lines_selected.push_back(0.0); } } @@ -801,6 +868,10 @@ Scene_polyhedron_item::Scene_polyhedron_item() : Scene_item(), positions_facets(0), positions_lines(0), + color_facets(0), + color_facets_selected(0), + color_lines(0), + color_lines_selected(0), normals(0), poly(new Polyhedron), is_Triangle(true), @@ -812,9 +883,9 @@ Scene_polyhedron_item::Scene_polyhedron_item() cur_shading=GL_FLAT; is_selected = false; //init(); - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(5, buffer); + glGenBuffers(10, buffer); compile_shaders(); } @@ -822,6 +893,10 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) : Scene_item(), positions_facets(0), positions_lines(0), + color_facets(0), + color_facets_selected(0), + color_lines(0), + color_lines_selected(0), normals(0), poly(p), is_Triangle(true), @@ -833,9 +908,9 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) cur_shading=GL_FLAT; is_selected = false; init(); - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(5, buffer); + glGenBuffers(10, buffer); compile_shaders(); } @@ -843,6 +918,10 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) : Scene_item(), positions_facets(0), positions_lines(0), + color_facets(0), + color_facets_selected(0), + color_lines(0), + color_lines_selected(0), normals(0), poly(new Polyhedron(p)), is_Triangle(true), @@ -854,9 +933,9 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) cur_shading=GL_FLAT; is_selected=false; init(); - glGenVertexArrays(1, vao); + glGenVertexArrays(2, vao); //Generates an integer which will be used as ID for each buffer - glGenBuffers(5, buffer); + glGenBuffers(10, buffer); compile_shaders(); } @@ -869,8 +948,8 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) Scene_polyhedron_item::~Scene_polyhedron_item() { - glDeleteBuffers(5, buffer); - glDeleteVertexArrays(1, vao); + glDeleteBuffers(10, buffer); + glDeleteVertexArrays(2, vao); glDeleteProgram(rendering_program_facets); glDeleteProgram(rendering_program_lines); @@ -1010,19 +1089,29 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) } void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { - glBindVertexArray(vao[0]); + std::cout< color_lines; std::vector color_facets; + std::vector color_lines_selected; + std::vector color_facets_selected; + GLuint rendering_program_facets; GLuint rendering_program_lines; GLint location[9]; - GLuint vao[1]; - GLuint buffer[5]; + GLuint vao[2]; + GLuint buffer[10]; void initialize_buffers(); void compile_shaders(void); void compute_normals_and_vertices(void); From 85dc68ac9e3846228e14b4a93d5b7c2ec7e6e503 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 26 Mar 2015 09:40:09 +0100 Subject: [PATCH 60/62] Forgot to remove my logs again --- Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 9b72f0e3515..0877bdb2d02 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -1089,7 +1089,6 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) } void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { - std::cout< Date: Fri, 24 Apr 2015 15:59:23 +0200 Subject: [PATCH 61/62] cut_plugin fixed - replaced the missing modified files by the originals - added a reference to a vector of floats in traits so that it fills it instead of drawing the bboxes --- .../internal/AABB_tree/AABB_drawing_traits.h | 16 ++- .../cmake/modules/FindGLEW.cmake | 0 Polyhedron/demo/Polyhedron/CMakeLists.txt | 16 +-- .../Polyhedron/GlSplat/cmake/FindGLEW.cmake | 105 ------------------ .../Polyhedron/Polyhedron_demo_cut_plugin.cpp | 18 +-- Polyhedron/demo/Polyhedron/Scene.cpp | 21 +--- .../Scene_points_with_normal_item.cpp | 11 +- 7 files changed, 39 insertions(+), 148 deletions(-) rename {Mesh_3/demo/Mesh_3 => Installation}/cmake/modules/FindGLEW.cmake (100%) delete mode 100644 Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake diff --git a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_drawing_traits.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_drawing_traits.h index 26893bd0916..4b16e52c597 100644 --- a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_drawing_traits.h +++ b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_drawing_traits.h @@ -23,12 +23,15 @@ #include #include +#include namespace CGAL { template struct AABB_drawing_traits { + std::vector *v_edges; + typedef CGAL::Bbox_3 Bbox; bool go_further() { return true; } @@ -45,7 +48,7 @@ struct AABB_drawing_traits } // draw bbox - static void gl_draw(const Bbox& bb) + void gl_draw(const Bbox& bb) { ::glBegin(GL_LINES); gl_draw_edge(bb.xmin(), bb.ymin(), bb.zmin(), @@ -79,11 +82,16 @@ struct AABB_drawing_traits ::glEnd(); } - static void gl_draw_edge(double px, double py, double pz, + void gl_draw_edge(double px, double py, double pz, double qx, double qy, double qz) { - ::glVertex3d(px,py,pz); - ::glVertex3d(qx,qy,qz); + v_edges->push_back((float)px); + v_edges->push_back((float)py); + v_edges->push_back((float)pz); + + v_edges->push_back((float)qx); + v_edges->push_back((float)qy); + v_edges->push_back((float)qz); } }; // AABB_drawing_traits diff --git a/Mesh_3/demo/Mesh_3/cmake/modules/FindGLEW.cmake b/Installation/cmake/modules/FindGLEW.cmake similarity index 100% rename from Mesh_3/demo/Mesh_3/cmake/modules/FindGLEW.cmake rename to Installation/cmake/modules/FindGLEW.cmake diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 12b5edd5033..6921a8a32f5 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -56,8 +56,7 @@ if( POLYHEDRON_QTSCRIPT_DEBUGGER) endif() find_package(Qt4) -# Find Glew (optional), for splatting -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/GlSplat/cmake) +# Find Glew (required) find_package(GLEW) # Find OpenGL @@ -70,24 +69,19 @@ if(QT4_FOUND) find_package(QGLViewer ) endif(QT4_FOUND) -if(GLEW_FOUND) - include_directories ( ${GLEW_INCLUDE_DIR} ) - add_definitions(-DCGAL_GLEW_ENABLED) -else(GLEW_FOUND) - message(STATUS "NOTICE: GLEW library is not found. Splat rendering will not be available.") -endif(GLEW_FOUND) find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) if (EIGEN3_FOUND) include( ${EIGEN3_USE_FILE} ) endif(EIGEN3_FOUND) -if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) - +if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND GLEW_FOUND) + add_definitions(-DCGAL_GLEW_ENABLED) set(Boost_USE_MULTITHREADED ON) find_package(Boost COMPONENTS thread system) include_directories ( ${QGLVIEWER_INCLUDE_DIR} ) + include_directories ( ${GLEW_INCLUDE_DIR} ) qt4_wrap_ui( MainWindowUI_files MainWindow.ui ) qt4_wrap_ui( FileLoaderDialogUI_files FileLoaderDialog.ui ) @@ -504,4 +498,4 @@ else (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) message(STATUS "NOTICE: This demo requires ${POLYHEDRON_MISSING_DEPS}and will not be compiled.") -endif (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) +endif (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND GLEW_FOUND) diff --git a/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake b/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake deleted file mode 100644 index 54da20f12bd..00000000000 --- a/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2009 Boudewijn Rempt -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# -# - try to find glew library and include files -# GLEW_INCLUDE_DIR, where to find GL/glew.h, etc. -# GLEW_LIBRARIES, the libraries to link against -# GLEW_FOUND, If false, do not try to use GLEW. -# Also defined, but not for general use are: -# GLEW_GLEW_LIBRARY = the full path to the glew library. - -IF (WIN32) - - IF(CYGWIN) - - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h) - - FIND_LIBRARY( GLEW_GLEW_LIBRARY glew32 - ${OPENGL_LIBRARY_DIR} - /usr/lib/w32api - /usr/X11R6/lib - ) - - - ELSE(CYGWIN) - - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h - $ENV{GLEW_ROOT_PATH}/include - ) - - FIND_LIBRARY( GLEW_GLEW_LIBRARY - NAMES glew glew32 - PATHS - $ENV{GLEW_ROOT_PATH}/lib - ${OPENGL_LIBRARY_DIR} - ) - - ENDIF(CYGWIN) - -ELSE (WIN32) - - IF (APPLE) -# These values for Apple could probably do with improvement. - FIND_PATH( GLEW_INCLUDE_DIR glew.h - /System/Library/Frameworks/GLEW.framework/Versions/A/Headers - ${OPENGL_LIBRARY_DIR} - ) - SET(GLEW_GLEW_LIBRARY "-framework GLEW" CACHE STRING "GLEW library for OSX") - SET(GLEW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") - ELSE (APPLE) - - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h - /usr/include/GL - /usr/openwin/share/include - /usr/openwin/include - /usr/X11R6/include - /usr/include/X11 - /opt/graphics/OpenGL/include - /opt/graphics/OpenGL/contrib/libglew - ) - - FIND_LIBRARY( GLEW_GLEW_LIBRARY GLEW - /usr/openwin/lib - /usr/X11R6/lib - ) - - ENDIF (APPLE) - -ENDIF (WIN32) - -SET( GLEW_FOUND "NO" ) -IF(GLEW_INCLUDE_DIR) - IF(GLEW_GLEW_LIBRARY) - # Is -lXi and -lXmu required on all platforms that have it? - # If not, we need some way to figure out what platform we are on. - SET( GLEW_LIBRARIES - ${GLEW_GLEW_LIBRARY} - ${GLEW_cocoa_LIBRARY} - ) - SET( GLEW_FOUND "YES" ) - -#The following deprecated settings are for backwards compatibility with CMake1.4 - SET (GLEW_LIBRARY ${GLEW_LIBRARIES}) - SET (GLEW_INCLUDE_PATH ${GLEW_INCLUDE_DIR}) - - ENDIF(GLEW_GLEW_LIBRARY) -ENDIF(GLEW_INCLUDE_DIR) - -IF(GLEW_FOUND) - IF(NOT GLEW_FIND_QUIETLY) - MESSAGE(STATUS "Found Glew: ${GLEW_LIBRARIES}") - ENDIF(NOT GLEW_FIND_QUIETLY) -ELSE(GLEW_FOUND) - IF(GLEW_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Glew") - ENDIF(GLEW_FIND_REQUIRED) -ENDIF(GLEW_FOUND) - -MARK_AS_ADVANCED( - GLEW_INCLUDE_DIR - GLEW_GLEW_LIBRARY - GLEW_Xmu_LIBRARY - GLEW_Xi_LIBRARY -) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp index 665918b2c7d..eaa7e9cddc6 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp @@ -11,10 +11,10 @@ #include "Polyhedron_demo_io_plugin_interface.h" #include -#include +#include #include #include -#include +#include #include #include @@ -89,8 +89,8 @@ public: // Wireframe OpenGL drawing in a display list void direct_draw() const { - CGAL::AABB_drawing_traits > traits; - tree.traversal(0, traits, new std::vector(0)); + // CGAL::AABB_drawing_traits > traits; + // tree.traversal(0, traits, new std::vector(0)); } void changed() @@ -209,7 +209,9 @@ private: positions_lines.clear(); CGAL::AABB_drawing_traits > traits; - tree.traversal(0, traits, &positions_lines); + traits.v_edges = &positions_lines; + + tree.traversal(0, traits); location[0] = glGetUniformLocation(rendering_program_lines, "mvp_matrix"); location[1] = glGetUniformLocation(rendering_program_lines, "color"); @@ -240,9 +242,9 @@ public: } ~Scene_edges_item() { - glDeleteBuffers(1, buffer); - glDeleteVertexArrays(1, vao); - glDeleteProgram(rendering_program_lines); + glDeleteBuffers(1, buffer); + glDeleteVertexArrays(1, vao); + glDeleteProgram(rendering_program_lines); } bool isFinite() const { return true; } bool isEmpty() const { return edges.empty(); } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 7d811b0b96e..fe9c7217a83 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -1,7 +1,6 @@ -#ifdef CGAL_GLEW_ENABLED -# include "GlSplat/GlSplat.h" -#endif +#include "GlSplat/GlSplat.h" + #include @@ -30,7 +29,7 @@ void CGALglcolor(QColor c) } } -#ifdef CGAL_GLEW_ENABLED + GlSplat::SplatRenderer* Scene::ms_splatting = 0; int Scene::ms_splattingCounter = 0; GlSplat::SplatRenderer* Scene::splatting() @@ -38,7 +37,7 @@ GlSplat::SplatRenderer* Scene::splatting() assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); return ms_splatting; } -#endif + Scene::Scene(QObject* parent) : QAbstractListModel(parent), @@ -51,11 +50,10 @@ Scene::Scene(QObject* parent) double, double, double)), this, SLOT(setSelectionRay(double, double, double, double, double, double))); -#ifdef CGAL_GLEW_ENABLED + if(ms_splatting==0) ms_splatting = new GlSplat::SplatRenderer(); ms_splattingCounter++; -#endif } @@ -167,10 +165,8 @@ Scene::~Scene() } m_entries.clear(); -#ifdef CGAL_GLEW_ENABLED if((--ms_splattingCounter)==0) delete ms_splatting; -#endif } Scene_item* @@ -214,7 +210,6 @@ Scene::duplicate(Item_id index) void Scene::initializeGL() { -#ifdef CGAL_GLEW_ENABLED ms_splatting->init(); //Setting the light options @@ -231,7 +226,6 @@ void Scene::initializeGL() glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); glLightfv(GL_LIGHT0, GL_POSITION, position); -#endif } // workaround for Qt-4.2. @@ -417,7 +411,6 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) ::glPopName(); } } -#ifdef CGAL_GLEW_ENABLED // Splatting if(!with_names && ms_splatting->isSupported()) { @@ -452,8 +445,8 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) } } ms_splatting->finalize(); + } -#endif } // workaround for Qt-4.2 (see above) @@ -617,9 +610,7 @@ Scene::setData(const QModelIndex &index, RenderingMode rendering_mode = static_cast(value.toInt()); // Find next supported rendering mode while ( ! item->supportsRenderingMode(rendering_mode) - #ifdef CGAL_GLEW_ENABLED || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) - #endif ) { rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 4ea7130e06a..ea6d78dc85e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -600,10 +600,9 @@ void Scene_points_with_normal_item::compute_normals_and_vertices(void) normals.push_back(p.normal().x()); normals.push_back(p.normal().y()); normals.push_back(p.normal().z()); -#ifdef CGAL_GLEW_ENABLED tex_coords.push_back(p.radius()); - ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); -#endif + tex_coords.push_back(0); + //::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); positions_splats.push_back(p.x()); positions_splats.push_back(p.y()); positions_splats.push_back(p.z()); @@ -861,13 +860,15 @@ void Scene_points_with_normal_item::draw_splats(Viewer_interface* viewer) const { const UI_point& p = *it; ::glNormal3dv(&p.normal().x()); -#ifdef CGAL_GLEW_ENABLED ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); -#endif ::glVertex3dv(&p.x()); + } ::glEnd(); + + + } void Scene_points_with_normal_item::draw_edges(Viewer_interface* viewer) const From f44c824205692dfe2f9c1be4a0d5d141975dbed5 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 27 Apr 2015 08:24:19 +0200 Subject: [PATCH 62/62] Warning fixed - Replaced the seond "fit" iterator by "fit2" to avoid conflict --- Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 0877bdb2d02..7e01ef855ad 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -141,11 +141,11 @@ Scene_polyhedron_item::triangulate_facet(Facet_iterator fit) // sets mark is_external for(typename CDT::All_faces_iterator - fit = cdt.all_faces_begin(), + fit2 = cdt.all_faces_begin(), end = cdt.all_faces_end(); - fit != end; ++fit) + fit2 != end; ++fit2) { - fit->info().is_external = false; + fit2->info().is_external = false; } //check if the facet is external or internal std::queue face_queue;