From 656fa17e7b7e0914cc8416c63cabd2bcd55f208f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 18 Mar 2016 16:14:59 +0100 Subject: [PATCH] Operations secured --- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 33 +- .../demo/Polyhedron/Scene_polyhedron_item.h | 3 +- .../Scene_polyhedron_selection_item.cpp | 589 ++++++++++++------ .../Scene_polyhedron_selection_item.h | 55 +- 4 files changed, 459 insertions(+), 221 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index cff893c12e7..80c65520eeb 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -169,7 +169,6 @@ Input_facets_AABB_tree* get_aabb_tree(Scene_polyhedron_item* item) new Input_facets_AABB_tree()/*faces(*poly).first, faces(*poly).second, *poly)*/; - typedef Polyhedron::Traits Kernel; typedef Kernel::Point_3 Point; typedef Kernel::Vector_3 Vector; @@ -720,7 +719,6 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) nb_facets = 0; nb_lines = 0; nb_f_lines = 0; - skip_emits = false; init(); invalidateOpenGLBuffers(); } @@ -741,7 +739,6 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) nb_facets = 0; nb_lines = 0; nb_f_lines = 0; - skip_emits = false; invalidateOpenGLBuffers(); } @@ -1141,6 +1138,7 @@ Scene_polyhedron_item::select(double orig_x, double dir_y, double dir_z) { + void* vertex_to_emit; if(facet_picking_m) { typedef Input_facets_AABB_tree Tree; typedef Tree::Object_and_primitive_id Object_and_primitive_id; @@ -1178,7 +1176,6 @@ Scene_polyhedron_item::select(double orig_x, } 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'. @@ -1201,26 +1198,30 @@ Scene_polyhedron_item::select(double orig_x, nearest_v = v; } } - Q_EMIT selected_vertex((void*)(&*nearest_v)); + vertex_to_emit = (void*)(&*nearest_v); } - if(!skip_emits &&(QObject::receivers(SIGNAL(selected_edge(void*))) > 0 - || QObject::receivers(SIGNAL(selected_halfedge(void*))) > 0)) + 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; - //segfault when performing "remove_center_vertex Kernel::FT sq_dist = CGAL::squared_distance(*closest_point, - Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->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())); + 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; @@ -1230,9 +1231,9 @@ Scene_polyhedron_item::select(double orig_x, Q_EMIT selected_halfedge((void*)(&*nearest_h)); Q_EMIT selected_edge((void*)(std::min)(&*nearest_h, &*nearest_h->opposite())); } - set_skip_emits(false); - + Q_EMIT selected_vertex(vertex_to_emit); Q_EMIT selected_facet((void*)(&*selected_fh)); + if(erase_next_picked_facet_m) { polyhedron()->erase_facet(selected_fh->halfedge()); polyhedron()->normalize_border(); @@ -1245,6 +1246,7 @@ Scene_polyhedron_item::select(double orig_x, } } Base::select(orig_x, orig_y, orig_z, dir_x, dir_y, dir_z); + Q_EMIT selection_done(); } void Scene_polyhedron_item::update_vertex_indices() @@ -1427,8 +1429,3 @@ CGAL::Three::Scene_item::Header_data Scene_polyhedron_item::header() const data.titles.append(QString("Average")); return data; } - -void Scene_polyhedron_item::set_skip_emits(bool b) -{ - skip_emits = b; -} diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index ac5156dd780..3c4d0044a9c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -108,13 +108,13 @@ public Q_SLOTS: double dir_x, double dir_y, double dir_z); - void set_skip_emits(bool b); void update_vertex_indices(); void update_facet_indices(); void update_halfedge_indices(); void invalidate_aabb_tree(); Q_SIGNALS: + void selection_done(); void selected_vertex(void*); void selected_facet(void*); void selected_edge(void*); @@ -136,7 +136,6 @@ private: Color_vector colors_; - bool skip_emits; bool show_only_feature_edges_m; bool show_feature_edges_m; bool facet_picking_m; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 0ec042c48fb..951a5da38a6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -16,85 +16,168 @@ void Scene_polyhedron_selection_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer)const { - //vao containing the data for the unselected facets - { - program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); - program->bind(); + //vao containing the data for the facets + { + program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); + program->bind(); - vaos[0]->bind(); - buffers[0].bind(); - buffers[0].allocate(positions_facets.data(), - static_cast(positions_facets.size()*sizeof(float))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[0].release(); + vaos[0]->bind(); + buffers[0].bind(); + buffers[0].allocate(positions_facets.data(), + static_cast(positions_facets.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[0].release(); - buffers[1].bind(); - buffers[1].allocate(normals.data(), - static_cast(normals.size()*sizeof(float))); - program->enableAttributeArray("normals"); - program->setAttributeBuffer("normals",GL_FLOAT,0,3); - buffers[1].release(); + buffers[1].bind(); + buffers[1].allocate(normals.data(), + static_cast(normals.size()*sizeof(float))); + program->enableAttributeArray("normals"); + program->setAttributeBuffer("normals",GL_FLOAT,0,3); + buffers[1].release(); - vaos[0]->release(); - program->release(); + vaos[0]->release(); + program->release(); - } - //vao containing the data for the unselected lines - { - program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); - program->bind(); - vaos[1]->bind(); + } + //vao containing the data for the lines + { + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program->bind(); + vaos[1]->bind(); - buffers[2].bind(); - buffers[2].allocate(positions_lines.data(), - static_cast(positions_lines.size()*sizeof(float))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[2].release(); + buffers[2].bind(); + buffers[2].allocate(positions_lines.data(), + static_cast(positions_lines.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[2].release(); - program->release(); + program->release(); - vaos[1]->release(); + vaos[1]->release(); - } - //vao containing the data for the points - { - program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); - program->bind(); - vaos[2]->bind(); + } + //vao containing the data for the points + { + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program->bind(); + vaos[2]->bind(); - buffers[3].bind(); - buffers[3].allocate(positions_points.data(), - static_cast(positions_points.size()*sizeof(float))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[3].release(); + buffers[3].bind(); + buffers[3].allocate(positions_points.data(), + static_cast(positions_points.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[3].release(); + program->release(); - buffers[6].release(); - program->release(); + vaos[2]->release(); + } - vaos[2]->release(); - } - nb_facets = positions_facets.size(); - positions_facets.resize(0); - std::vector(positions_facets).swap(positions_facets); + nb_facets = positions_facets.size(); + positions_facets.resize(0); + std::vector(positions_facets).swap(positions_facets); - normals.resize(0); - std::vector(normals).swap(normals); + normals.resize(0); + std::vector(normals).swap(normals); - nb_lines = positions_lines.size(); - positions_lines.resize(0); - std::vector(positions_lines).swap(positions_lines); + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); - nb_points = positions_points.size(); - positions_points.resize(0); - std::vector(positions_points).swap(positions_points); + nb_points = positions_points.size(); + positions_points.resize(0); + std::vector(positions_points).swap(positions_points); - are_buffers_filled = true; + + + are_buffers_filled = true; } + +void Scene_polyhedron_selection_item::initialize_temp_buffers(CGAL::Three::Viewer_interface *viewer)const +{ + //vao containing the data for the temp facets + { + program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); + program->bind(); + + vaos[3]->bind(); + buffers[4].bind(); + buffers[4].allocate(positions_temp_facets.data(), + static_cast(positions_temp_facets.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[4].release(); + + + + buffers[5].bind(); + buffers[5].allocate(temp_normals.data(), + static_cast(temp_normals.size()*sizeof(float))); + program->enableAttributeArray("normals"); + program->setAttributeBuffer("normals",GL_FLOAT,0,3); + buffers[5].release(); + + vaos[3]->release(); + program->release(); + + } + //vao containing the data for the temp lines + { + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program->bind(); + vaos[4]->bind(); + + buffers[6].bind(); + buffers[6].allocate(positions_temp_lines.data(), + static_cast(positions_temp_lines.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[6].release(); + + program->release(); + + vaos[4]->release(); + + } + //vao containing the data for the temp points + { + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program->bind(); + vaos[5]->bind(); + + buffers[7].bind(); + buffers[7].allocate(positions_temp_points.data(), + static_cast(positions_temp_points.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[7].release(); + + program->release(); + + vaos[5]->release(); + } + nb_temp_facets = positions_temp_facets.size(); + positions_temp_facets.resize(0); + std::vector(positions_temp_facets).swap(positions_temp_facets); + + temp_normals.resize(0); + std::vector(temp_normals).swap(temp_normals); + + nb_temp_lines = positions_temp_lines.size(); + positions_temp_lines.resize(0); + std::vector(positions_temp_lines).swap(positions_temp_lines); + + nb_temp_points = positions_temp_points.size(); + positions_temp_points.resize(0); + std::vector(positions_temp_points).swap(positions_temp_points); + + are_temp_buffers_filled = true; +} + template void push_back_xyz(const TypeWithXYZ& t, ContainerWithPushBack& vector) @@ -136,8 +219,8 @@ typedef boost::graph_traits::vertex_descriptor vertex_descriptor; template void -Scene_polyhedron_selection_item::triangulate_facet(Facet_handle fit, - const FaceNormalPmap& fnmap) const +Scene_polyhedron_selection_item::triangulate_facet(Facet_handle fit,const FaceNormalPmap& fnmap, + std::vector &p_facets,std::vector &p_normals ) const { //Computes the normal of the facet Traits::Vector_3 normal = get(fnmap, fit); @@ -205,23 +288,24 @@ Scene_polyhedron_selection_item::triangulate_facet(Facet_handle fit, if(ffit->info().is_external) continue; - push_back_xyz(ffit->vertex(0)->point(), positions_facets); - push_back_xyz(ffit->vertex(1)->point(), positions_facets); - push_back_xyz(ffit->vertex(2)->point(), positions_facets); + push_back_xyz(ffit->vertex(0)->point(), p_facets); + push_back_xyz(ffit->vertex(1)->point(), p_facets); + push_back_xyz(ffit->vertex(2)->point(), p_facets); - push_back_xyz(normal, normals); - push_back_xyz(normal, normals); - push_back_xyz(normal, normals); + push_back_xyz(normal, p_normals); + push_back_xyz(normal, p_normals); + push_back_xyz(normal, p_normals); } } -void Scene_polyhedron_selection_item::compute_elements()const +void Scene_polyhedron_selection_item::compute_any_elements(std::vector& p_facets, std::vector& p_lines, std::vector& p_points, std::vector& p_normals, + const Selection_set_vertex& p_sel_vertices, const Selection_set_facet& p_sel_facets, const Selection_set_edge& p_sel_edges)const { - positions_facets.clear(); - positions_lines.clear(); - positions_points.clear(); - normals.clear(); + p_facets.clear(); + p_lines.clear(); + p_points.clear(); + p_normals.clear(); //The facet boost::container::flat_map face_normals_map; boost::associative_property_map< boost::container::flat_map > @@ -233,8 +317,8 @@ if(!poly) return; PMP::compute_normals(*poly, nv_pmap, nf_pmap); for(Selection_set_facet::iterator - it = selected_facets.begin(), - end = selected_facets.end(); + it = p_sel_facets.begin(), + end = p_sel_facets.end(); it != end; it++) { Facet_handle f = (*it); @@ -246,17 +330,17 @@ if(!poly) const Kernel::Vector_3 n = CGAL::Polygon_mesh_processing::compute_face_normal(f, *this->poly_item->polyhedron()); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + p_normals.push_back(n.x()); + p_normals.push_back(n.y()); + p_normals.push_back(n.z()); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + p_normals.push_back(n.x()); + p_normals.push_back(n.y()); + p_normals.push_back(n.z()); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + p_normals.push_back(n.x()); + p_normals.push_back(n.y()); + p_normals.push_back(n.z()); Polyhedron::Halfedge_around_facet_circulator @@ -266,9 +350,9 @@ if(!poly) 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()); + p_facets.push_back(p.x()); + p_facets.push_back(p.y()); + p_facets.push_back(p.z()); } } else if (is_quad(f->halfedge(), *poly)) @@ -280,67 +364,97 @@ if(!poly) Point p1 = f->halfedge()->next()->vertex()->point(); Point p2 = f->halfedge()->next()->next()->vertex()->point(); - push_back_xyz(p0, positions_facets); - push_back_xyz(p1, positions_facets); - push_back_xyz(p2, positions_facets); + push_back_xyz(p0, p_facets); + push_back_xyz(p1, p_facets); + push_back_xyz(p2, p_facets); - push_back_xyz(nf, normals); - push_back_xyz(nf, normals); - push_back_xyz(nf, normals); + push_back_xyz(nf, p_normals); + push_back_xyz(nf, p_normals); + push_back_xyz(nf, p_normals); //2nd half-quad p0 = f->halfedge()->next()->next()->vertex()->point(); p1 = f->halfedge()->prev()->vertex()->point(); p2 = f->halfedge()->vertex()->point(); - push_back_xyz(p0, positions_facets); - push_back_xyz(p1, positions_facets); - push_back_xyz(p2, positions_facets); + push_back_xyz(p0, p_facets); + push_back_xyz(p1, p_facets); + push_back_xyz(p2, p_facets); - push_back_xyz(nf, normals); - push_back_xyz(nf, normals); - push_back_xyz(nf, normals); + push_back_xyz(nf, p_normals); + push_back_xyz(nf, p_normals); + push_back_xyz(nf, p_normals); } else { - triangulate_facet(f, nf_pmap); + triangulate_facet(f, nf_pmap, p_facets, p_normals); } } //The Lines { - for(Selection_set_edge::iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) { + for(Selection_set_edge::iterator it = p_sel_edges.begin(); it != p_sel_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()); + p_lines.push_back(a.x()); + p_lines.push_back(a.y()); + p_lines.push_back(a.z()); - positions_lines.push_back(b.x()); - positions_lines.push_back(b.y()); - positions_lines.push_back(b.z()); + p_lines.push_back(b.x()); + p_lines.push_back(b.y()); + p_lines.push_back(b.z()); } } //The points { for(Selection_set_vertex::iterator - it = selected_vertices.begin(), - end = selected_vertices.end(); + it = p_sel_vertices.begin(), + end = p_sel_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()); + p_points.push_back(p.x()); + p_points.push_back(p.y()); + p_points.push_back(p.z()); } } } +void Scene_polyhedron_selection_item::compute_elements()const +{ + compute_any_elements(positions_facets, positions_lines, positions_points, normals, + selected_vertices, selected_facets, selected_edges); +} +void Scene_polyhedron_selection_item::compute_temp_elements()const +{ + compute_any_elements(positions_temp_facets, positions_temp_lines, positions_temp_points, temp_normals, + temp_selected_vertices, temp_selected_facets, temp_selected_edges); +} void Scene_polyhedron_selection_item::draw(CGAL::Three::Viewer_interface* viewer) const { + GLfloat offset_factor; + GLfloat offset_units; + if(!are_temp_buffers_filled) + { + compute_temp_elements(); + initialize_temp_buffers(viewer); + } + + viewer->glGetFloatv( GL_POLYGON_OFFSET_FACTOR, &offset_factor); + viewer->glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); + glPolygonOffset(-1.f, 1.f); + vaos[3]->bind(); + program = getShaderProgram(PROGRAM_WITH_LIGHT); + attrib_buffers(viewer,PROGRAM_WITH_LIGHT); + program->bind(); + program->setAttributeValue("colors",QColor(0,255,0)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_temp_facets/3)); + program->release(); + vaos[3]->release(); + glPolygonOffset(offset_factor, offset_units); if(!are_buffers_filled) { compute_elements(); @@ -348,8 +462,6 @@ void Scene_polyhedron_selection_item::draw(CGAL::Three::Viewer_interface* viewer } draw_points(viewer); - GLfloat offset_factor; - GLfloat offset_units; viewer->glGetFloatv( GL_POLYGON_OFFSET_FACTOR, &offset_factor); viewer->glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); glPolygonOffset(-1.f, 1.f); @@ -365,48 +477,82 @@ void Scene_polyhedron_selection_item::draw(CGAL::Three::Viewer_interface* viewer glPolygonOffset(offset_factor, offset_units); draw_edges(viewer); - } void Scene_polyhedron_selection_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const { - if(!are_buffers_filled) - { - compute_elements(); - initialize_buffers(viewer); - } - viewer->glLineWidth(3.f); - vaos[1]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); - attrib_buffers(viewer,PROGRAM_NO_SELECTION); - program->bind(); + viewer->glLineWidth(3.f); + if(!are_temp_buffers_filled) + { + compute_temp_elements(); + initialize_temp_buffers(viewer); + } - program->setAttributeValue("colors",edge_color); - viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); - program->release(); - vaos[1]->release(); - viewer->glLineWidth(1.f); + vaos[4]->bind(); + program = getShaderProgram(PROGRAM_NO_SELECTION); + attrib_buffers(viewer,PROGRAM_NO_SELECTION); + program->bind(); + + program->setAttributeValue("colors",QColor(0,200,0)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_temp_lines/3)); + program->release(); + vaos[4]->release(); + + if(!are_buffers_filled) + { + compute_elements(); + initialize_buffers(viewer); + } + + vaos[1]->bind(); + program = getShaderProgram(PROGRAM_NO_SELECTION); + attrib_buffers(viewer,PROGRAM_NO_SELECTION); + program->bind(); + + program->setAttributeValue("colors",edge_color); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); + program->release(); + vaos[1]->release(); + + + viewer->glLineWidth(1.f); } void Scene_polyhedron_selection_item::draw_points(CGAL::Three::Viewer_interface* viewer) const { - if(!are_buffers_filled) - { - compute_elements(); - initialize_buffers(viewer); - } - viewer->glPointSize(5.f); - vaos[2]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); - attrib_buffers(viewer,PROGRAM_NO_SELECTION); - program->bind(); - program->setAttributeValue("colors",vertex_color); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_points/3)); - program->release(); - vaos[2]->release(); - viewer->glPointSize(1.f); + viewer->glPointSize(5.f); + + if(!are_temp_buffers_filled) + { + compute_temp_elements(); + initialize_temp_buffers(viewer); + } + vaos[5]->bind(); + program = getShaderProgram(PROGRAM_NO_SELECTION); + attrib_buffers(viewer,PROGRAM_NO_SELECTION); + program->bind(); + program->setAttributeValue("colors",QColor(0,125,0)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_temp_points/3)); + program->release(); + vaos[5]->release(); + + if(!are_buffers_filled) + { + compute_elements(); + initialize_buffers(viewer); + } + vaos[2]->bind(); + program = getShaderProgram(PROGRAM_NO_SELECTION); + attrib_buffers(viewer,PROGRAM_NO_SELECTION); + program->bind(); + program->setAttributeValue("colors",vertex_color); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_points/3)); + program->release(); + vaos[2]->release(); + + viewer->glPointSize(1.f); } @@ -539,9 +685,6 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set tr(this); switch(operation_mode) { @@ -583,12 +726,16 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set(0)); + polyhedron()->join_vertex(target); + + temp_selected_edges.erase(to_join_ed); + //set to select edge + set_active_handle_type(static_cast(2)); tempInstructions("Vertices joined.", - "Select the edge with extremities you want to join."); } + "Select the edge with extremities you want to join."); + invalidateOpenGLBuffers(); + polyhedron_item()->invalidateOpenGLBuffers(); + } } break; //Split vertex @@ -597,15 +744,17 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set(1)); + invalidateOpenGLBuffers(); Q_EMIT updateInstructions("Select first facet."); break; } //Split face case 4: { + static Vertex_handle s; static Polyhedron::Halfedge_handle h1,h2; static bool found_h1(false), found_h2(false); if(!first_selected) @@ -633,7 +782,8 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set(1)); tempInstructions("Face split.", "Select a facet."); + polyhedron_item()->invalidateOpenGLBuffers(); } } break; } //Add edge case 5: + { + static Vertex_handle s; if(!first_selected) { BOOST_FOREACH(Vertex_handle vh, selection) @@ -707,18 +861,21 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::setinvalidateOpenGLBuffers(); } first_selected = false; - selected_vertices.erase(s); + temp_selected_vertices.erase(s); } + invalidateOpenGLBuffers(); break; + } //Remove center vertex case 9: BOOST_FOREACH(Vertex_handle vh, selection) @@ -735,25 +892,44 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::sethalfedge(),*polyhedron()); + polyhedron_item()->invalidateOpenGLBuffers(); + } else { tempInstructions("Vertex not selected : There must be no hole incident to the selection.", "Select the vertex you want to remove."); } } - //Avoids a segfault in Scene_polyhedron_item::select() - Q_EMIT skipEmits(true); break; //Add vertex and face to border } - polyhedron_item()->invalidateOpenGLBuffers(); - invalidateOpenGLBuffers(); } is_treated = true; } +//returns true if halfedge's facet's degree >= degree + +int facet_degree(Halfedge_handle h) +{ + if(h->is_border()) + { + Halfedge_handle it = h; + int deg =0; + do + { + deg ++; + it=it->next(); + } + while(it != h); + return deg; + } + else + return h->facet()->facet_degree(); +} + bool Scene_polyhedron_selection_item:: treat_selection(const std::set& selection) { if(!is_treated) @@ -782,12 +958,9 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setis_border() && - halfedge(ed, *polyhedron())->facet()->facet_degree()<4) + if(facet_degree(halfedge(ed, *polyhedron())) < 4 || - (!opposite(halfedge(ed, *polyhedron()), *polyhedron())->is_border() && - opposite(halfedge(ed, *polyhedron()), *polyhedron())->facet()->facet_degree()<4) - ) + facet_degree(halfedge(ed, *polyhedron())->opposite())< 4) { tempInstructions("Edge not selected: the incident facets must have a degree of at least 4.", "Select the edge with extremities you want to join."); @@ -795,7 +968,8 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::set(0)); Q_EMIT updateInstructions("Select the vertex that will remain."); @@ -811,7 +985,12 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setvertex()->point() = p; + selected_vertices.insert(hhandle->vertex()); + invalidateOpenGLBuffers(); + poly_item->invalidateOpenGLBuffers(); } + tempInstructions("Edge splitted.", + "Select the edge you want to split."); break; //Join face case 3: @@ -822,7 +1001,10 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setjoin_facet(halfedge(ed, *polyhedron())); + poly_item->invalidateOpenGLBuffers(); + } } break; //Collapse edge @@ -842,6 +1024,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setinvalidateOpenGLBuffers(); tempInstructions("Edge collapsed.", "Select the edge you want to collapse."); } @@ -852,9 +1035,10 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setfacet()->facet_degree() == 3 && halfedge(ed, *polyhedron())->opposite()->facet()->facet_degree() == 3) + if(facet_degree(halfedge(ed, *polyhedron())) == 3 && facet_degree(halfedge(ed, *polyhedron())->opposite()) == 3) { CGAL::Euler::flip_edge(halfedge(ed, *polyhedron()), *polyhedron()); + polyhedron_item()->invalidateOpenGLBuffers(); } else { @@ -865,7 +1049,6 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setvertex()); + temp_selected_edges.insert(edge(t, *polyhedron())); + temp_selected_vertices.insert(t->vertex()); + invalidateOpenGLBuffers(); Q_EMIT updateInstructions("Select second edge."); } else @@ -966,18 +1150,19 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setvertex()); + temp_selected_edges.erase(edge(t,*polyhedron())); + temp_selected_vertices.erase(t->vertex()); + invalidateOpenGLBuffers(); + polyhedron_item()->invalidateOpenGLBuffers(); tempInstructions("Face and vertex added.", "Select a border edge."); } } break; -} + } //Add face to border case 11: { - static bool first_selected = false; static Halfedge_handle t; if(!first_selected) { @@ -998,7 +1183,8 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setvertex()); - selected_edges.erase(edge(t,*polyhedron())); + temp_selected_vertices.erase(t->vertex()); + temp_selected_edges.erase(edge(t,*polyhedron())); + invalidateOpenGLBuffers(); + polyhedron_item()->invalidateOpenGLBuffers(); tempInstructions("Face added.", "Select a border edge."); } @@ -1084,8 +1272,6 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setinvalidateOpenGLBuffers(); - invalidateOpenGLBuffers(); } is_treated = true; } @@ -1114,9 +1300,9 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::setsplit_vertex(h1,h2); + Polyhedron::Halfedge_handle hhandle = CGAL::Euler::split_vertex(h1,h2,*polyhedron()); - selected_facets.erase(h1->facet()); - hhandle->vertex()->point() = to_split_vh->point(); + temp_selected_facets.erase(h1->facet()); + Polyhedron::Point_3 p1t = h1->vertex()->point(); + Polyhedron::Point_3 p1s = h1->opposite()->vertex()->point(); + double x = p1t.x() + 0.01 * (p1t.x() - p1s.x()); + double y = p1t.y() + 0.01 * (p1t.y() - p1s.y()); + double z = p1t.z() + 0.01 * (p1t.z() - p1s.z()); + hhandle->vertex()->point() = Polyhedron::Point_3(x,y,z);; first_selected = false; - selected_vertices.erase(to_split_vh); + temp_selected_vertices.erase(to_split_vh); + invalidateOpenGLBuffers(); //reset selection mode set_active_handle_type(static_cast(0)); - tempInstructions("Point splitted.", "Select the vertex you want splitted"); + poly_item->invalidateOpenGLBuffers(); + tempInstructions("Vertex splitted.", "Select the vertex you want splitted"); } else if(h1 == h2) { @@ -1196,7 +1390,8 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set(0)); Q_EMIT updateInstructions("Select first vertex."); @@ -1227,13 +1422,12 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::setfacet_begin(), *polyhedron()); if(total !=0) hhandle->vertex()->point() = Polyhedron::Point_3(x/(double)total, y/(double)total, z/(double)total); + poly_item->invalidateOpenGLBuffers(); } } break; } - polyhedron_item()->invalidateOpenGLBuffers(); - invalidateOpenGLBuffers(); } is_treated = true; } @@ -1250,3 +1444,12 @@ void Scene_polyhedron_selection_item::emitTempInstruct() Q_EMIT updateInstructions(m_temp_instructs); } +void Scene_polyhedron_selection_item::on_Ctrlz_pressed() +{ + first_selected = false; + temp_selected_vertices.clear(); + temp_selected_edges.clear(); + temp_selected_facets.clear(); + are_temp_buffers_filled = false; + set_operation_mode(operation_mode); +} diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h index 01817c40d81..abf6eff5570 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h @@ -187,13 +187,13 @@ public: { original_sel_mode = static_cast(0); this ->operation_mode = -1; - for(int i=0; i<3; i++) + for(int i=0; i<6; i++) { addVaos(i); vaos[i]->create(); } - for(int i=0; i<7; i++) + for(int i=0; i<10; i++) { buffers[i].create(); } @@ -201,7 +201,9 @@ public: nb_points = 0; nb_lines = 0; this->setColor(facet_color); + first_selected = false; is_treated = false; + poly_need_update = false; } Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw) @@ -213,20 +215,22 @@ public: nb_points = 0; nb_lines = 0; - for(int i=0; i<3; i++) + for(int i=0; i<6; i++) { addVaos(i); vaos[i]->create(); } - for(int i=0; i<7; i++) + for(int i=0; i<8; i++) { buffers[i].create(); } init(poly_item, mw); this->setColor(facet_color); invalidateOpenGLBuffers(); + first_selected = false; is_treated = false; + poly_need_update = false; } ~Scene_polyhedron_selection_item() @@ -244,7 +248,7 @@ protected: SLOT(selected(const std::set&))); connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, SLOT(selected(const std::set&))); - connect(this, SIGNAL(skipEmits(bool)), poly_item, SLOT(set_skip_emits(bool))); + connect(poly_item, SIGNAL(selection_done()), this, SLOT(update_poly())); connect(&k_ring_selector, SIGNAL(endSelection()), this,SLOT(endSelection())); connect(&k_ring_selector, SIGNAL(toogle_insert(bool)), this,SLOT(toggle_insert(bool))); @@ -798,10 +802,15 @@ public: Q_SIGNALS: void updateInstructions(QString); - void skipEmits(bool); void simplicesSelected(CGAL::Three::Scene_item*); public Q_SLOTS: + void update_poly() + { + if(poly_need_update) + poly_item->invalidateOpenGLBuffers(); + } + void on_Ctrlz_pressed(); void emitTempInstruct(); void resetIsTreated() { is_treated = false;} void save_handleType() @@ -816,6 +825,7 @@ public Q_SLOTS: // do not use decorator function, which calls changed on poly_item which cause deletion of AABB // poly_item->invalidateOpenGLBuffers(); are_buffers_filled = false; + are_temp_buffers_filled = false; poly = polyhedron(); compute_bbox(); } @@ -842,6 +852,14 @@ public Q_SLOTS: protected: bool eventFilter(QObject* /*target*/, QEvent * gen_event) { + if(gen_event->type() == QEvent::KeyPress + && static_cast(gen_event)->key()==Qt::Key_Z) + { + QKeyEvent *keyEvent = static_cast(gen_event); + if(keyEvent->modifiers().testFlag(Qt::ControlModifier)) + on_Ctrlz_pressed(); + } + if(!visible() || !k_ring_selector.state.shift_pressing) { return false; } if(gen_event->type() == QEvent::Wheel) { @@ -962,11 +980,18 @@ public: 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) + + Selection_set_vertex temp_selected_vertices; + Selection_set_facet temp_selected_facets; + Selection_set_edge temp_selected_edges; // stores one halfedge for each pair (halfedge with minimum address) // QColor vertex_color, facet_color, edge_color; private: + bool poly_need_update; + mutable bool are_temp_buffers_filled; //Specifies Selection/edition mode + bool first_selected; int operation_mode; QString m_temp_instructs; bool is_treated; @@ -983,14 +1008,28 @@ private: mutable std::size_t nb_facets; mutable std::size_t nb_points; mutable std::size_t nb_lines; + + mutable std::vector positions_temp_facets; + mutable std::vector temp_normals; + mutable std::vector positions_temp_lines; + mutable std::vector positions_temp_points; + mutable std::size_t nb_temp_facets; + mutable std::size_t nb_temp_points; + mutable std::size_t nb_temp_lines; + mutable QOpenGLShaderProgram *program; using CGAL::Three::Scene_item::initialize_buffers; void initialize_buffers(CGAL::Three::Viewer_interface *viewer) const; + void initialize_temp_buffers(CGAL::Three::Viewer_interface *viewer) const; void compute_elements() const; + void compute_any_elements(std::vector &p_facets, std::vector &p_lines, std::vector &p_points, std::vector &p_normals, + const Selection_set_vertex& p_sel_vertex, const Selection_set_facet &p_sel_facet, const Selection_set_edge &p_sel_edges) const; + void compute_temp_elements() const; template - void triangulate_facet(Facet_handle, - const FaceNormalPmap&) const; + void triangulate_facet(Facet_handle, const FaceNormalPmap&, + std::vector &p_facets,std::vector &p_normals) const; void tempInstructions(QString s1, QString s2); }; + #endif