From 00b834b7d80b4b9b64d38a62254ddea5d0ebb99d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 9 May 2016 15:07:50 +0200 Subject: [PATCH] D-pointer for Scene_edit_polyhedron_item --- .../Scene_edit_polyhedron_item.cpp | 923 ++++++++++++++---- .../Scene_edit_polyhedron_item.h | 487 +-------- 2 files changed, 741 insertions(+), 669 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp index 0b2b831c6a4..e84004cecda 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp @@ -9,38 +9,127 @@ #include #include +struct Scene_edit_polyhedron_item_priv +{ + Scene_edit_polyhedron_item_priv(Scene_polyhedron_item* poly_item, Ui::DeformMesh* ui_widget, QMainWindow* mw, Scene_edit_polyhedron_item* parent) + : ui_widget(ui_widget), + poly_item(poly_item), + is_rot_free(true), + own_poly_item(true), + k_ring_selector(poly_item, mw, Scene_polyhedron_item_k_ring_selection::Active_handle::VERTEX, true) + { + item = parent; + nb_ROI = 0; + nb_control = 0; + nb_axis = 0; + nb_bbox = 0; + spheres = NULL; + need_change = false; + } + ~Scene_edit_polyhedron_item_priv() + { + delete deform_mesh; + if (own_poly_item) + delete poly_item; + } + void remesh(); + void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const; + void compute_normals_and_vertices(void); + void compute_bbox(const CGAL::Three::Scene_interface::Bbox&); + void reset_drawing_data(); + enum Buffer + { + Facet_vertices =0, + Facet_normals, + Roi_vertices, + Control_vertices, + Bbox_vertices, + Axis_vertices, + Axis_colors, + Frame_vertices, + NumberOfBuffers + }; + enum Vao + { + Facets=0, + Roi_points, + Edges, + BBox, + Control_points, + Axis, + Frame_plane, + NumberOfVaos + }; + + Ui::DeformMesh* ui_widget; + Scene_polyhedron_item* poly_item; + bool need_change; + // For drawing + mutable std::vector positions; + mutable std::vector tris; + mutable std::vector edges; + mutable std::vector color_lines; + mutable std::vector color_bbox; + mutable std::vector ROI_points; + mutable std::vector control_points; + mutable std::vector ROI_color; + mutable std::vector control_color; + mutable std::vector normals; + mutable std::vector pos_bbox; + mutable std::vector pos_axis; + mutable std::vector pos_frame_plane; + mutable QOpenGLShaderProgram *program; + mutable QOpenGLShaderProgram bbox_program; + mutable std::size_t nb_ROI; + mutable std::size_t nb_control; + mutable std::size_t nb_axis; + mutable std::size_t nb_bbox; + mutable Scene_spheres_item* spheres; + mutable bool are_buffers_filled; + mutable QOpenGLBuffer *in_bu; + + Deform_mesh* deform_mesh; + typedef std::list Ctrl_vertices_group_data_list; + Ctrl_vertices_group_data_list::iterator active_group; + Ctrl_vertices_group_data_list ctrl_vertex_frame_map; // keep list of group of control vertices with assoc data + + double length_of_axis; // for drawing axis at a group of control vertices + + // by interleaving 'viewer's events (check constructor), keep followings: + Mouse_keyboard_state_deformation state; + + //For constraint rotation + qglviewer::LocalConstraint rot_constraint; + bool is_rot_free; + + bool own_poly_item; //indicates if the poly_item should be deleted by the destructor + Scene_polyhedron_item_k_ring_selection k_ring_selector; + Scene_edit_polyhedron_item *item; + +}; //end Scene_edit_polyhedron_item_priv Scene_edit_polyhedron_item::Scene_edit_polyhedron_item (Scene_polyhedron_item* poly_item, Ui::DeformMesh* ui_widget, QMainWindow* mw) - : Scene_group_item("unnamed",NumberOfBuffers,NumberOfVaos), - ui_widget(ui_widget), - poly_item(poly_item), - is_rot_free(true), - own_poly_item(true), - k_ring_selector(poly_item, mw, Scene_polyhedron_item_k_ring_selection::Active_handle::VERTEX, true) + : Scene_group_item("unnamed",Scene_edit_polyhedron_item_priv::NumberOfBuffers,Scene_edit_polyhedron_item_priv::NumberOfVaos) + { - nb_ROI = 0; - nb_control = 0; - nb_axis = 0; - nb_bbox = 0; - spheres = NULL; - need_change = false; mw->installEventFilter(this); + d = new Scene_edit_polyhedron_item_priv(poly_item, ui_widget, mw, this); // bind vertex picking - connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, + connect(&d->k_ring_selector, SIGNAL(selected(const std::set&)), this, SLOT(selected(const std::set&))); - poly_item->set_color_vector_read_only(true); // to prevent recomputation of color vector in invalidateOpenGLBuffers() - poly_item->update_vertex_indices(); + d->poly_item->set_color_vector_read_only(true); // to prevent recomputation of color vector in invalidateOpenGLBuffers() + d->poly_item->update_vertex_indices(); - deform_mesh = new Deform_mesh(*(poly_item->polyhedron()), + d->deform_mesh = new Deform_mesh(*(poly_item->polyhedron()), Deform_mesh::Vertex_index_map(), Deform_mesh::Hedge_index_map(), - Array_based_vertex_point_map(&positions)); + Array_based_vertex_point_map(&d->positions)); - length_of_axis = (CGAL::sqrt((bbox().xmax()-bbox().xmin())*(bbox().xmax()-bbox().xmin()) + (bbox().ymax()-bbox().ymin())*(bbox().ymax()-bbox().ymin()) + (bbox().zmax()-bbox().zmin())*(bbox().zmax()-bbox().zmin()))) / 15.0; + d->length_of_axis = (CGAL::sqrt((bbox().xmax()-bbox().xmin())*(bbox().xmax()-bbox().xmin()) + (bbox().ymax()-bbox().ymin())*(bbox().ymax()-bbox().ymin()) + (bbox().zmax()-bbox().zmin())*(bbox().zmax()-bbox().zmin()))) / 15.0; // interleave events of viewer (there is only one viewer) QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); @@ -50,7 +139,7 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item create_ctrl_vertices_group(); // Required for drawing functionality - reset_drawing_data(); + d->reset_drawing_data(); //Generates an integer which will be used as ID for each buffer @@ -83,15 +172,15 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item " gl_FragColor = vec4(fColors, 1.0); \n" "} \n" }; - bbox_program.addShaderFromSourceCode(QOpenGLShader::Vertex,vertex_shader_source_bbox); - bbox_program.addShaderFromSourceCode(QOpenGLShader::Fragment,fragment_shader_source); - bbox_program.link(); + d->bbox_program.addShaderFromSourceCode(QOpenGLShader::Vertex,vertex_shader_source_bbox); + d->bbox_program.addShaderFromSourceCode(QOpenGLShader::Fragment,fragment_shader_source); + d->bbox_program.link(); - ui_widget->remeshing_iterations_spinbox->setValue(1); + d->ui_widget->remeshing_iterations_spinbox->setValue(1); - ui_widget->remeshing_edge_length_spinbox->setValue(length_of_axis); - ui_widget->remeshing_edge_length_spinbox->setDisabled(true); - ui_widget->remeshingEdgeLengthInput_checkBox->setChecked(false); + d->ui_widget->remeshing_edge_length_spinbox->setValue(d->length_of_axis); + d->ui_widget->remeshing_edge_length_spinbox->setDisabled(true); + d->ui_widget->remeshingEdgeLengthInput_checkBox->setChecked(false); connect(ui_widget->remeshingEdgeLengthInput_checkBox, SIGNAL(toggled(bool)), ui_widget->remeshing_edge_length_spinbox, SLOT(setEnabled(bool))); @@ -105,46 +194,45 @@ Scene_edit_polyhedron_item::~Scene_edit_polyhedron_item() delete_ctrl_vertices_group(false); } - delete deform_mesh; - if (own_poly_item) delete poly_item; + delete d; } ///////////////////////////// /// For the Shader gestion/// -void Scene_edit_polyhedron_item::initializeBuffers(CGAL::Three::Viewer_interface *viewer =0) const +void Scene_edit_polyhedron_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer =0) const { //vao for the facets { - program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); + program = item->getShaderProgram(Scene_edit_polyhedron_item::PROGRAM_WITH_LIGHT, viewer); program->bind(); - vaos[Facets]->bind(); - buffers[Facet_vertices].bind(); - buffers[Facet_vertices].allocate(positions.data(), + item->vaos[Facets]->bind(); + item->buffers[Facet_vertices].bind(); + item->buffers[Facet_vertices].allocate(positions.data(), static_cast(positions.size()*sizeof(double))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Facet_vertices].release(); + item->buffers[Facet_vertices].release(); - buffers[Facet_normals].bind(); - buffers[Facet_normals].allocate(normals.data(), + item->buffers[Facet_normals].bind(); + item->buffers[Facet_normals].allocate(normals.data(), static_cast(normals.size()*sizeof(double))); program->enableAttributeArray("normals"); program->setAttributeBuffer("normals",GL_DOUBLE,0,3); - buffers[Facet_normals].release(); - vaos[Facets]->release(); + item->buffers[Facet_normals].release(); + item->vaos[Facets]->release(); program->release(); } //vao for the ROI points - { program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + { program = item->getShaderProgram(Scene_edit_polyhedron_item::PROGRAM_NO_SELECTION, viewer); program->bind(); - vaos[Roi_points]->bind(); - buffers[Roi_vertices].bind(); - buffers[Roi_vertices].allocate(ROI_points.data(), + item->vaos[Roi_points]->bind(); + item->buffers[Roi_vertices].bind(); + item->buffers[Roi_vertices].allocate(ROI_points.data(), static_cast(ROI_points.size()*sizeof(double))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Roi_vertices].release(); - vaos[Roi_points]->release(); + item->buffers[Roi_vertices].release(); + item->vaos[Roi_points]->release(); program->release(); nb_ROI = ROI_points.size(); @@ -153,28 +241,28 @@ void Scene_edit_polyhedron_item::initializeBuffers(CGAL::Three::Viewer_interface } //vao for the edges { - program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program = item->getShaderProgram(Scene_edit_polyhedron_item::PROGRAM_NO_SELECTION, viewer); program->bind(); - vaos[Edges]->bind(); - buffers[Facet_vertices].bind(); + item->vaos[Edges]->bind(); + item->buffers[Facet_vertices].bind(); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Facet_vertices].release(); - vaos[Edges]->release(); + item->buffers[Facet_vertices].release(); + item->vaos[Edges]->release(); program->release(); } //vao for the BBOX { bbox_program.bind(); - vaos[BBox]->bind(); - buffers[Bbox_vertices].bind(); - buffers[Bbox_vertices].allocate(pos_bbox.data(), + item->vaos[BBox]->bind(); + item->buffers[Bbox_vertices].bind(); + item->buffers[Bbox_vertices].allocate(pos_bbox.data(), static_cast(pos_bbox.size()*sizeof(double))); bbox_program.enableAttributeArray("vertex"); bbox_program.setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Bbox_vertices].release(); + item->buffers[Bbox_vertices].release(); - vaos[BBox]->release(); + item->vaos[BBox]->release(); nb_bbox = pos_bbox.size(); pos_bbox.resize(0); std::vector(pos_bbox).swap(pos_bbox); @@ -184,17 +272,17 @@ void Scene_edit_polyhedron_item::initializeBuffers(CGAL::Three::Viewer_interface } //vao for the control points { - program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program = item->getShaderProgram(Scene_edit_polyhedron_item::PROGRAM_NO_SELECTION, viewer); program->bind(); - vaos[Control_points]->bind(); - buffers[Control_vertices].bind(); - buffers[Control_vertices].allocate(control_points.data(), + item->vaos[Control_points]->bind(); + item->buffers[Control_vertices].bind(); + item->buffers[Control_vertices].allocate(control_points.data(), static_cast(control_points.size()*sizeof(double))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Control_vertices].release(); + item->buffers[Control_vertices].release(); - vaos[Control_points]->release(); + item->vaos[Control_points]->release(); program->release(); nb_control = control_points.size(); control_points.clear(); @@ -202,22 +290,22 @@ void Scene_edit_polyhedron_item::initializeBuffers(CGAL::Three::Viewer_interface } //vao for the axis { - program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program = item->getShaderProgram(Scene_edit_polyhedron_item::PROGRAM_NO_SELECTION, viewer); program->bind(); - vaos[Axis]->bind(); - buffers[Axis_vertices].bind(); - buffers[Axis_vertices].allocate(pos_axis.data(), + item->vaos[Axis]->bind(); + item->buffers[Axis_vertices].bind(); + item->buffers[Axis_vertices].allocate(pos_axis.data(), static_cast(pos_axis.size()*sizeof(double))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Axis_vertices].release(); - buffers[Axis_colors].bind(); - buffers[Axis_colors].allocate(color_lines.data(), + item->buffers[Axis_vertices].release(); + item->buffers[Axis_colors].bind(); + item->buffers[Axis_colors].allocate(color_lines.data(), static_cast(color_lines.size()*sizeof(double))); program->enableAttributeArray("colors"); program->setAttributeBuffer("colors",GL_DOUBLE,0,3); - buffers[Axis_colors].release(); - vaos[Axis]->release(); + item->buffers[Axis_colors].release(); + item->vaos[Axis]->release(); program->release(); nb_axis = pos_axis.size(); pos_axis.resize(0); @@ -227,32 +315,32 @@ void Scene_edit_polyhedron_item::initializeBuffers(CGAL::Three::Viewer_interface } //vao for the frame plane { - program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program = item->getShaderProgram(Scene_edit_polyhedron_item::PROGRAM_NO_SELECTION, viewer); program->bind(); - vaos[Frame_plane]->bind(); - buffers[Frame_vertices].bind(); - buffers[Frame_vertices].allocate(pos_frame_plane.data(), + item->vaos[Frame_plane]->bind(); + item->buffers[Frame_vertices].bind(); + item->buffers[Frame_vertices].allocate(pos_frame_plane.data(), static_cast(pos_frame_plane.size()*sizeof(double))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - buffers[Frame_vertices].release(); + item->buffers[Frame_vertices].release(); program->disableAttributeArray("colors"); - vaos[Frame_plane]->release(); + item->vaos[Frame_plane]->release(); program->release(); } are_buffers_filled = true; } -void Scene_edit_polyhedron_item::reset_drawing_data() +void Scene_edit_polyhedron_item_priv::reset_drawing_data() { positions.clear(); - positions.resize(num_vertices(*polyhedron()) * 3); + positions.resize(num_vertices(*item->polyhedron()) * 3); normals.clear(); normals.resize(positions.size()); std::size_t counter = 0; - BOOST_FOREACH(vertex_descriptor vb, vertices(*polyhedron())) + BOOST_FOREACH(vertex_descriptor vb, vertices(*item->polyhedron())) { positions[counter * 3] = vb->point().x(); positions[counter * 3 + 1] = vb->point().y(); @@ -268,9 +356,9 @@ void Scene_edit_polyhedron_item::reset_drawing_data() } tris.clear(); - tris.resize(polyhedron()->size_of_facets() * 3); + tris.resize(item->polyhedron()->size_of_facets() * 3); counter = 0; - BOOST_FOREACH(face_descriptor fb, faces(*polyhedron())) + BOOST_FOREACH(face_descriptor fb, faces(*item->polyhedron())) { tris[counter * 3] = static_cast(fb->halfedge()->vertex()->id()); tris[counter * 3 + 1] = static_cast(fb->halfedge()->next()->vertex()->id()); @@ -279,17 +367,17 @@ void Scene_edit_polyhedron_item::reset_drawing_data() } edges.clear(); - edges.resize(polyhedron()->size_of_halfedges()); + edges.resize(item->polyhedron()->size_of_halfedges()); counter = 0; - for (Polyhedron::Edge_iterator eb = polyhedron()->edges_begin(); - eb != polyhedron()->edges_end(); ++eb, ++counter) + for (Polyhedron::Edge_iterator eb = item->polyhedron()->edges_begin(); + eb != item->polyhedron()->edges_end(); ++eb, ++counter) { edges[counter * 2] = static_cast(eb->vertex()->id()); edges[counter * 2 + 1] = static_cast(eb->opposite()->vertex()->id()); } } -void Scene_edit_polyhedron_item::compute_normals_and_vertices(void) +void Scene_edit_polyhedron_item_priv::compute_normals_and_vertices(void) { ROI_points.resize(0); control_points.resize(0); @@ -372,7 +460,7 @@ void Scene_edit_polyhedron_item::compute_normals_and_vertices(void) color_lines[13] = 1.0; color_lines[16] = 1.0; if(ui_widget->ActivateFixedPlaneCheckBox->isChecked()) - draw_frame_plane(viewer); + item->draw_frame_plane(viewer); } @@ -382,11 +470,11 @@ void Scene_edit_polyhedron_item::deform() { 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) + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) { it->set_target_positions(); } - deform_mesh->deform(); + d->deform_mesh->deform(); - poly_item->invalidate_aabb_tree(); // invalidate the AABB-tree of the poly_item + d->poly_item->invalidate_aabb_tree(); // invalidate the AABB-tree of the poly_item Q_EMIT itemChanged(); } @@ -415,8 +503,11 @@ struct ROI_border_pmap else if(get(map,k)) map.m_set_ptr->erase(k); } }; - void Scene_edit_polyhedron_item::remesh() +{ + d->remesh(); +} +void Scene_edit_polyhedron_item_priv::remesh() { const Polyhedron& g = deform_mesh->halfedge_graph(); Array_based_vertex_point_map vpmap(&positions); @@ -440,7 +531,7 @@ void Scene_edit_polyhedron_item::remesh() // set face_index map needed for border_halfedges and isotropic_remeshing boost::property_map::type fim - = get(CGAL::face_index, *polyhedron()); + = get(CGAL::face_index, *item->polyhedron()); unsigned int id = 0; // estimate the target_length using the perimeter of the region to remesh @@ -448,7 +539,7 @@ void Scene_edit_polyhedron_item::remesh() double estimated_target_length = 0.; if (automatic_target_length) { - BOOST_FOREACH(face_descriptor f, faces(*polyhedron())) + BOOST_FOREACH(face_descriptor f, faces(*item->polyhedron())) put(fim, f, id++); std::set roi_border_halfedges; CGAL::Polygon_mesh_processing::border_halfedges(roi_facets, g, @@ -475,7 +566,7 @@ void Scene_edit_polyhedron_item::remesh() CGAL::Polygon_mesh_processing::isotropic_remeshing( roi_facets , target_length - , *polyhedron() + , *item->polyhedron() , CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter) .protect_constraints(false) .vertex_point_map(vpmap) @@ -483,9 +574,9 @@ void Scene_edit_polyhedron_item::remesh() std::cout << "done." << std::endl; //reset ROI from its outside border roi_border - clear_roi(); + item->clear_roi(); do{ - delete_ctrl_vertices_group(false); + item->delete_ctrl_vertices_group(false); } while(!ctrl_vertex_frame_map.empty()); @@ -501,38 +592,38 @@ void Scene_edit_polyhedron_item::remesh() compute_normals_and_vertices(); poly_item->invalidate_aabb_tree(); // invalidate the AABB tree - create_ctrl_vertices_group(); + item->create_ctrl_vertices_group(); - Q_EMIT itemChanged(); + Q_EMIT item->itemChanged(); } void Scene_edit_polyhedron_item::updateDeform() { - if(need_change) + if(d->need_change) { // just handle deformation - paint like selection is handled in eventFilter() invalidateOpenGLBuffers(); - if(!ui_widget->ActivatePivotingCheckBox->isChecked()) { + if(!d->ui_widget->ActivatePivotingCheckBox->isChecked()) { deform(); } else { Q_EMIT itemChanged(); // for redraw while Pivoting (since we close signals of manipulatedFrames while pivoting, // for now redraw with timer) } - need_change = 0; + d->need_change = 0; } } void Scene_edit_polyhedron_item::change() { - need_change = true; + d->need_change = true; QTimer::singleShot(0, this, SLOT(updateDeform())); } 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; + Mouse_keyboard_state_deformation old_state = d->state; ////////////////// TAKE EVENTS ///////////////////// // key events if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) @@ -540,35 +631,35 @@ bool Scene_edit_polyhedron_item::eventFilter(QObject* /*target*/, QEvent *event) QKeyEvent *keyEvent = static_cast(event); Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); - state.ctrl_pressing = modifiers.testFlag(Qt::ControlModifier); - state.shift_pressing = modifiers.testFlag(Qt::ShiftModifier); + d->state.ctrl_pressing = modifiers.testFlag(Qt::ControlModifier); + d->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; + d->state.left_button_pressing = event->type() == QEvent::MouseButtonPress; } if(mouse_event->button() == Qt::RightButton) { - state.right_button_pressing = event->type() == QEvent::MouseButtonPress; + d->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(!d->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; + bool ctrl_pressed_now = d->state.ctrl_pressing && !old_state.ctrl_pressing; + bool ctrl_released_now = !d->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 (!ui_widget->ActivatePivotingCheckBox->isChecked() && - ctrl_released_now && ui_widget->RemeshingCheckBox->isChecked()) + if (!d->ui_widget->ActivatePivotingCheckBox->isChecked() && + ctrl_released_now && d->ui_widget->RemeshingCheckBox->isChecked()) { remesh(); } @@ -581,26 +672,26 @@ bool Scene_edit_polyhedron_item::eventFilter(QObject* /*target*/, QEvent *event) #include "opengl_tools.h" void Scene_edit_polyhedron_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { - if(!are_buffers_filled) - initializeBuffers(viewer); - vaos[Edges]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); + if(!d->are_buffers_filled) + d->initializeBuffers(viewer); + vaos[Scene_edit_polyhedron_item_priv::Edges]->bind(); + d->program = getShaderProgram(PROGRAM_NO_SELECTION); attribBuffers(viewer,PROGRAM_NO_SELECTION); - program->bind(); - program->setAttributeValue("colors", QColor(0,0,0)); - viewer->glDrawElements(GL_LINES, (GLsizei) edges.size(), GL_UNSIGNED_INT, edges.data()); - program->release(); - vaos[Edges]->release(); + d->program->bind(); + d->program->setAttributeValue("colors", QColor(0,0,0)); + viewer->glDrawElements(GL_LINES, (GLsizei) d->edges.size(), GL_UNSIGNED_INT, d->edges.data()); + d->program->release(); + vaos[Scene_edit_polyhedron_item_priv::Edges]->release(); - vaos[Frame_plane]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); + vaos[Scene_edit_polyhedron_item_priv::Frame_plane]->bind(); + d->program = getShaderProgram(PROGRAM_NO_SELECTION); attribBuffers(viewer,PROGRAM_NO_SELECTION); - program->bind(); - program->setAttributeValue("colors", QColor(0,0,0)); - viewer->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei)pos_frame_plane.size()/3); - program->release(); - vaos[Frame_plane]->release(); + d->program->bind(); + d->program->setAttributeValue("colors", QColor(0,0,0)); + viewer->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei)d->pos_frame_plane.size()/3); + d->program->release(); + vaos[Scene_edit_polyhedron_item_priv::Frame_plane]->release(); if(rendering_mode == Wireframe) { @@ -608,17 +699,17 @@ void Scene_edit_polyhedron_item::drawEdges(CGAL::Three::Viewer_interface* viewer } } void Scene_edit_polyhedron_item::draw(CGAL::Three::Viewer_interface* viewer) const { - if(!are_buffers_filled) - initializeBuffers(viewer); - vaos[Facets]->bind(); - program = getShaderProgram(PROGRAM_WITH_LIGHT); + if(!d->are_buffers_filled) + d->initializeBuffers(viewer); + vaos[Scene_edit_polyhedron_item_priv::Facets]->bind(); + d->program = getShaderProgram(PROGRAM_WITH_LIGHT); attribBuffers(viewer,PROGRAM_WITH_LIGHT); - program->bind(); + d->program->bind(); QColor color = this->color(); - program->setAttributeValue("colors", color); - viewer->glDrawElements(GL_TRIANGLES, (GLsizei) tris.size(), GL_UNSIGNED_INT, tris.data()); - program->release(); - vaos[Facets]->release(); + d->program->setAttributeValue("colors", color); + viewer->glDrawElements(GL_TRIANGLES, (GLsizei) d->tris.size(), GL_UNSIGNED_INT, d->tris.data()); + d->program->release(); + vaos[Scene_edit_polyhedron_item_priv::Facets]->release(); drawEdges(viewer); draw_ROI_and_control_vertices(viewer); @@ -626,8 +717,8 @@ void Scene_edit_polyhedron_item::draw(CGAL::Three::Viewer_interface* viewer) con void Scene_edit_polyhedron_item::draw_frame_plane(QGLViewer* ) const { - pos_frame_plane.resize(15); - for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) + d->pos_frame_plane.resize(15); + for(Scene_edit_polyhedron_item_priv::Ctrl_vertices_group_data_list::const_iterator hgb_data = d->ctrl_vertex_frame_map.begin(); hgb_data != d->ctrl_vertex_frame_map.end(); ++hgb_data) { const double diag = scene_diag(); qglviewer::Vec base1(1,0,0); @@ -643,11 +734,11 @@ void Scene_edit_polyhedron_item::draw_frame_plane(QGLViewer* ) const qglviewer::Vec p3 = center + diag*base1 + diag*base2; qglviewer::Vec p4 = center - diag*base1 + diag*base2; - pos_frame_plane[0] = p1.x ; pos_frame_plane[1] = p1.y; pos_frame_plane[2] =p1.z ; - pos_frame_plane[3] = p2.x ; pos_frame_plane[4] = p2.y; pos_frame_plane[5] =p2.z ; - pos_frame_plane[6] = p3.x ; pos_frame_plane[7] = p3.y; pos_frame_plane[8] =p3.z ; - pos_frame_plane[9] = p4.x ; pos_frame_plane[10]= p4.y; pos_frame_plane[11] =p4.z ; - pos_frame_plane[12] = p1.x ; pos_frame_plane[13]= p1.y; pos_frame_plane[14] =p1.z ; + d->pos_frame_plane[0] = p1.x ; d->pos_frame_plane[1] = p1.y; d->pos_frame_plane[2] =p1.z ; + d->pos_frame_plane[3] = p2.x ; d->pos_frame_plane[4] = p2.y; d->pos_frame_plane[5] =p2.z ; + d->pos_frame_plane[6] = p3.x ; d->pos_frame_plane[7] = p3.y; d->pos_frame_plane[8] =p3.z ; + d->pos_frame_plane[9] = p4.x ; d->pos_frame_plane[10]= p4.y; d->pos_frame_plane[11] =p4.z ; + d->pos_frame_plane[12] = p1.x ; d->pos_frame_plane[13]= p1.y; d->pos_frame_plane[14] =p1.z ; } } @@ -656,37 +747,37 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View CGAL::GL::Point_size point_size; point_size.set_point_size(5); - if(ui_widget->ShowROICheckBox->isChecked()) { + if(d->ui_widget->ShowROICheckBox->isChecked()) { - if(!ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->extension_is_found) { + if(!d->ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->extension_is_found) { - vaos[Roi_points]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); + vaos[Scene_edit_polyhedron_item_priv::Roi_points]->bind(); + d->program = getShaderProgram(PROGRAM_NO_SELECTION); attribBuffers(viewer,PROGRAM_NO_SELECTION); - program->bind(); - program->setAttributeValue("colors", QColor(0,255,0)); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_ROI/3)); - program->release(); - vaos[Roi_points]->release(); + d->program->bind(); + d->program->setAttributeValue("colors", QColor(0,255,0)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(d->nb_ROI/3)); + d->program->release(); + vaos[Scene_edit_polyhedron_item_priv::Roi_points]->release(); } else{ Scene_group_item::draw(viewer); } } - if(!ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->extension_is_found) { - vaos[Control_points]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); + if(!d->ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->extension_is_found) { + vaos[Scene_edit_polyhedron_item_priv::Control_points]->bind(); + d->program = getShaderProgram(PROGRAM_NO_SELECTION); attribBuffers(viewer,PROGRAM_NO_SELECTION); - program->bind(); - program->setAttributeValue("colors", QColor(255,0,0)); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_control/3)); - program->release(); - vaos[Control_points]->release(); + d->program->bind(); + d->program->setAttributeValue("colors", QColor(255,0,0)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(d->nb_control/3)); + d->program->release(); + vaos[Scene_edit_polyhedron_item_priv::Control_points]->release(); } 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) + for(Scene_edit_polyhedron_item_priv::Ctrl_vertices_group_data_list::const_iterator hgb_data = d->ctrl_vertex_frame_map.begin(); hgb_data != d->ctrl_vertex_frame_map.end(); ++hgb_data) { if(hgb_data->frame == viewerB->manipulatedFrame()) { @@ -696,18 +787,18 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View QMatrix4x4 f_mat; for(int i=0; i<16; i++) f_mat.data()[i] = (float)f_matrix[i]; - vaos[Axis]->bind(); - program = getShaderProgram(PROGRAM_NO_SELECTION); + vaos[Scene_edit_polyhedron_item_priv::Axis]->bind(); + d->program = getShaderProgram(PROGRAM_NO_SELECTION); attribBuffers(viewer, PROGRAM_NO_SELECTION); - program->bind(); - program->setUniformValue("f_matrix", f_mat); - viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_axis/3)); - program->release(); - vaos[Axis]->release(); + d->program->bind(); + d->program->setUniformValue("f_matrix", f_mat); + viewer->glDrawArrays(GL_LINES, 0, static_cast(d->nb_axis/3)); + d->program->release(); + vaos[Scene_edit_polyhedron_item_priv::Axis]->release(); //QGLViewer::drawAxis(length_of_axis); // draw bbox - if(!ui_widget->ActivatePivotingCheckBox->isChecked()) + if(!d->ui_widget->ActivatePivotingCheckBox->isChecked()) { GLfloat f_matrix[16]; GLfloat trans[3]; @@ -734,16 +825,16 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View viewer->camera()->getModelViewProjectionMatrix(temp_mat); for(int i=0; i<16; i++) mvp_mat.data()[i] = (float)temp_mat[i]; - vaos[BBox]->bind(); - bbox_program.bind(); - bbox_program.setUniformValue("rotations", f_mat); - bbox_program.setUniformValue("translation", vec); - bbox_program.setUniformValue("translation_2", vec2); - bbox_program.setUniformValue("mvp_matrix", mvp_mat); - program->setAttributeValue("colors", QColor(255,0,0)); - viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_bbox/3)); - bbox_program.release(); - vaos[BBox]->release(); + vaos[Scene_edit_polyhedron_item_priv::BBox]->bind(); + d->bbox_program.bind(); + d->bbox_program.setUniformValue("rotations", f_mat); + d->bbox_program.setUniformValue("translation", vec); + d->bbox_program.setUniformValue("translation_2", vec2); + d->bbox_program.setUniformValue("mvp_matrix", mvp_mat); + d->program->setAttributeValue("colors", QColor(255,0,0)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(d->nb_bbox/3)); + d->bbox_program.release(); + vaos[Scene_edit_polyhedron_item_priv::BBox]->release(); } } } @@ -751,7 +842,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View } -void Scene_edit_polyhedron_item::compute_bbox(const CGAL::Three::Scene_interface::Bbox& bb){ +void Scene_edit_polyhedron_item_priv::compute_bbox(const CGAL::Three::Scene_interface::Bbox& bb){ pos_bbox.resize(24*3); pos_bbox[0]=bb.xmin(); pos_bbox[1]=bb.ymin(); pos_bbox[2]=bb.zmin(); @@ -788,31 +879,31 @@ void Scene_edit_polyhedron_item::compute_bbox(const CGAL::Three::Scene_interface void Scene_edit_polyhedron_item::invalidateOpenGLBuffers() { - if(spheres) - spheres->clear_spheres(); - compute_normals_and_vertices(); + if(d->spheres) + d->spheres->clear_spheres(); + d->compute_normals_and_vertices(); update_normals(); compute_bbox(); - are_buffers_filled = false; - if(spheres) - spheres->invalidateOpenGLBuffers(); + d->are_buffers_filled = false; + if(d->spheres) + d->spheres->invalidateOpenGLBuffers(); } 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; + Scene_polyhedron_item* poly_item_tmp = d->poly_item; + d->poly_item->set_color_vector_read_only(false); + d->own_poly_item=false; poly_item_tmp->invalidateOpenGLBuffers(); return poly_item_tmp; } Polyhedron* Scene_edit_polyhedron_item::polyhedron() -{ return poly_item->polyhedron(); } +{ return d->poly_item->polyhedron(); } const Polyhedron* Scene_edit_polyhedron_item::polyhedron() const -{ return poly_item->polyhedron(); } +{ return d->poly_item->polyhedron(); } QString Scene_edit_polyhedron_item::toolTip() const { - if(!poly_item->polyhedron()) + if(!d->poly_item->polyhedron()) return QString(); return QObject::tr("

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

" @@ -820,37 +911,37 @@ QString Scene_edit_polyhedron_item::toolTip() const "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(d->poly_item->polyhedron()->size_of_vertices()) + .arg(d->poly_item->polyhedron()->size_of_halfedges()/2) + .arg(d->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 d->poly_item->isEmpty(); } void Scene_edit_polyhedron_item::compute_bbox() const { - _bbox = poly_item->bbox(); + _bbox = d->poly_item->bbox(); } void Scene_edit_polyhedron_item::setVisible(bool b) { - poly_item->setVisible(b); + d->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); + d->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); + d->poly_item->setName(n); } void Scene_edit_polyhedron_item::setRenderingMode(RenderingMode m) { - poly_item->setRenderingMode(m); + d->poly_item->setRenderingMode(m); Scene_item::setRenderingMode(m); } Scene_edit_polyhedron_item* Scene_edit_polyhedron_item::clone() const { @@ -870,7 +961,7 @@ void Scene_edit_polyhedron_item::select( dir_x, dir_y, dir_z); - poly_item->select(orig_x, + d->poly_item->select(orig_x, orig_y, orig_z, dir_x, @@ -881,10 +972,10 @@ void Scene_edit_polyhedron_item::select( bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e) { //setting/unsetting rotation constraints - if (e->key()==Qt::Key_R && !state.ctrl_pressing) + if (e->key()==Qt::Key_R && !d->state.ctrl_pressing) { - is_rot_free = !is_rot_free; - rot_constraint.setRotationConstraintType( is_rot_free? + d->is_rot_free = !d->is_rot_free; + d->rot_constraint.setRotationConstraintType( d->is_rot_free? qglviewer::AxisPlaneConstraint::FREE: qglviewer::AxisPlaneConstraint::AXIS); return true; @@ -897,7 +988,7 @@ bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e) //#include "Scene_edit_polyhedron_item.moc" void Scene_edit_polyhedron_item::update_frame_plane() { - for(Ctrl_vertices_group_data_list::iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) + for(Ctrl_vertices_group_data_list::iterator hgb_data = d->ctrl_vertex_frame_map.begin(); hgb_data != d->ctrl_vertex_frame_map.end(); ++hgb_data) { hgb_data->refresh(); } @@ -905,22 +996,420 @@ void Scene_edit_polyhedron_item::update_frame_plane() void Scene_edit_polyhedron_item::ShowAsSphere(bool b) { - if(b && !spheres) + if(b && !d->spheres) { - spheres = new Scene_spheres_item(this, false); - spheres->setName("ROI & Control spheres"); - spheres->setRenderingMode(Gouraud); - connect(spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres())); + d->spheres = new Scene_spheres_item(this, false); + d->spheres->setName("ROI & Control spheres"); + d->spheres->setRenderingMode(Gouraud); + connect(d->spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres())); scene->setSelectedItem(scene->item_id(this)); - scene->addItem(spheres); - scene->changeGroup(spheres, this); - lockChild(spheres); + scene->addItem(d->spheres); + scene->changeGroup(d->spheres, this); + lockChild(d->spheres); invalidateOpenGLBuffers(); } - else if(!b && spheres!=0) + else if(!b && d->spheres!=0) { - unlockChild(spheres); - removeChild(spheres); - scene->erase(scene->item_id(spheres)); + unlockChild(d->spheres); + removeChild(d->spheres); + scene->erase(scene->item_id(d->spheres)); + } +} +bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices_group(Ctrl_vertices_group_data_list::iterator& hgb, Ctrl_vertices_group_data_list::iterator& hge) +{ + hgb = d->ctrl_vertex_frame_map.begin(); hge = d->ctrl_vertex_frame_map.end(); + return hgb != hge; +} +int Scene_edit_polyhedron_item::get_k_ring() { return d->k_ring_selector.k_ring; } +void Scene_edit_polyhedron_item::set_k_ring(int v) { d->k_ring_selector.k_ring = v; } + +void Scene_edit_polyhedron_item::reset_spheres() +{ + d->spheres = NULL; +} + +void Scene_edit_polyhedron_item::selected(const std::set& m) +{ + bool any_changes = false; + for(std::set::const_iterator it = m.begin(); it != m.end(); ++it) + { + vertex_descriptor vh = *it; + bool changed = false; + if(d->ui_widget->ROIRadioButton->isChecked()) { + if(d->ui_widget->InsertRadioButton->isChecked()) { changed = insert_roi_vertex(vh);} + else { changed = erase_roi_vertex(vh); } + } + else { + if(d->ui_widget->InsertRadioButton->isChecked()) { changed = insert_control_vertex(vh); } + else { changed = erase_control_vertex(vh); } + } + any_changes |= changed; + } + if(any_changes) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); } +} + +bool Scene_edit_polyhedron_item::insert_control_vertex(vertex_descriptor v) +{ + if(!is_there_any_ctrl_vertices_group()) { + print_message("There is no group of control vertices, create one!"); + return false; + } // no group of control vertices to insert + + bool inserted = d->deform_mesh->insert_control_vertex(v); + if(inserted) { + d->active_group->ctrl_vertices_group.push_back(v); + d->active_group->refresh(); + } + return inserted; +} + +bool Scene_edit_polyhedron_item::insert_roi_vertex(vertex_descriptor v) +{ + return d->deform_mesh->insert_roi_vertex(v); +} + +bool Scene_edit_polyhedron_item::erase_control_vertex(vertex_descriptor v) +{ + if(d->deform_mesh->erase_control_vertex(v)) // API should be safe enough to do that (without checking empty group of control vertices etc.) + { + refresh_all_group_centers(); // since we don't know which group of control vertices v is erased from, refresh all + return true; + } + + print_message("Selected vertex is not a control vertex!"); + return false; +} + +bool Scene_edit_polyhedron_item::erase_roi_vertex(vertex_descriptor v) +{ + erase_control_vertex(v); // erase control vertex + return d->deform_mesh->erase_roi_vertex(v); +} + +void Scene_edit_polyhedron_item::clear_roi() +{ + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { + delete it->frame; + } + d->ctrl_vertex_frame_map.clear(); + d->deform_mesh->clear_roi_vertices(); + + create_ctrl_vertices_group(); // create one new group of control vertices +} + +void Scene_edit_polyhedron_item::create_ctrl_vertices_group() +{ + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) { + if(it->ctrl_vertices_group.empty()) { + d->active_group = it; + return; + } + } + + // No empty group of control vertices + qglviewer::ManipulatedFrame* new_frame = new qglviewer::ManipulatedFrame(); + new_frame->setRotationSensitivity(2.0f); + connect(new_frame, SIGNAL(manipulated()), this, SLOT(change())); + + Control_vertices_data hgd(d->deform_mesh, new_frame); + d->ctrl_vertex_frame_map.push_back(hgd); + hgd.refresh(); + + d->active_group = --d->ctrl_vertex_frame_map.end(); + + invalidateOpenGLBuffers(); + Q_EMIT itemChanged(); + + print_message("A new empty group of control vertices is created."); +} + +void Scene_edit_polyhedron_item::delete_ctrl_vertices_group(bool create_new) +{ + if(!is_there_any_ctrl_vertices_group()) { + print_message("There is no group of control vertices to be deleted!"); + return; + } // no group of control vertices + + // delete group representative + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { + if(it == d->active_group) + { + delete it->frame; + for(std::vector::iterator v_it = it->ctrl_vertices_group.begin(); v_it != it->ctrl_vertices_group.end(); ++v_it) { + d->deform_mesh->erase_control_vertex(*v_it); + } + d->ctrl_vertex_frame_map.erase(it); + break; + } + } + + // assign another ctrl_vertices_group to active_group + Ctrl_vertices_group_data_list::iterator hgb, hge; + if( is_there_any_ctrl_vertices_group(hgb, hge) ) + { + d->active_group = hgb; + } // no group of control vertices + else if(create_new) + { + create_ctrl_vertices_group(); + } +} + +void Scene_edit_polyhedron_item::prev_ctrl_vertices_group() +{ + Ctrl_vertices_group_data_list::iterator hgb, hge; + if( !is_there_any_ctrl_vertices_group(hgb, hge) ) { + print_message("There is no group of control vertices to iterate on!"); + return; + } + // shift + if(hgb == d->active_group) { d->active_group = --hge; } + else {--d->active_group; } +} + +void Scene_edit_polyhedron_item::next_ctrl_vertices_group() +{ + Ctrl_vertices_group_data_list::iterator hgb, hge; + if( !is_there_any_ctrl_vertices_group(hgb, hge) ) { + print_message("There is no group of control vertices to iterate on!"); + return; + } + // shift + if(--hge == d->active_group) { d->active_group = hgb; } + else {++d->active_group; } +} + +void Scene_edit_polyhedron_item::pivoting_end() +{ + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { + //update constraint rotation vector, set only for the last group + it->rot_direction = it->frame->rotation().rotate( qglviewer::Vec(0.,0.,1.) ); + //translate center of the frame + qglviewer::Vec vec= it->frame->position(); + it->refresh(); + it->frame_initial_center = vec; + it->frame->setPosition(vec); + } + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { + it->frame->blockSignals(false); + } +} + +void Scene_edit_polyhedron_item::pivoting_begin() +{ + d->is_rot_free=true; + d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + d->rot_constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + + // just block signals to prevent deformation + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { + it->frame->blockSignals(true); + } +} + +void Scene_edit_polyhedron_item::save_roi(const char* file_name) const +{ + std::ofstream out(file_name); + // save roi + out << d->deform_mesh->roi_vertices().size() << std::endl; + BOOST_FOREACH(vertex_descriptor vd, d->deform_mesh->roi_vertices()) + { + out << vd->id() << " "; + } + out << std::endl; + // save control vertices + + out << d->ctrl_vertex_frame_map.size() << std::endl; // control vertices count + for(Ctrl_vertices_group_data_list::const_iterator hgb = d->ctrl_vertex_frame_map.begin(); hgb != d->ctrl_vertex_frame_map.end(); ++hgb) { + + out << hgb->ctrl_vertices_group.size() << std::endl; + for(std::vector::const_iterator hb = hgb->ctrl_vertices_group.begin(); hb != hgb->ctrl_vertices_group.end(); ++hb) + { + out << (*hb)->id() << " "; + } + out << std::endl; + } +} + +void Scene_edit_polyhedron_item::read_roi(const char* file_name) +{ + clear_roi(); + delete_ctrl_vertices_group(false); + + // put vertices to vector + std::vector all_vertices; + all_vertices.reserve(num_vertices(d->deform_mesh->halfedge_graph())); + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(d->deform_mesh->halfedge_graph()); vb != ve; ++vb) { + all_vertices.push_back(*vb); + } + // read roi + std::ifstream in(file_name); + int roi_size; + in >> roi_size; + while(roi_size-- > 0) + { + std::size_t v_id; + in >> v_id; + insert_roi_vertex(all_vertices[v_id]); + } + // read control vertices + int ctrl_vertices_group_size; + in >> ctrl_vertices_group_size; + while(ctrl_vertices_group_size-- > 0) + { + create_ctrl_vertices_group(); + int ctrl_size; + in >> ctrl_size; + while(ctrl_size-- > 0) + { + std::size_t v_id; + in >> v_id; + insert_control_vertex(all_vertices[v_id]); + } + } +} + +void Scene_edit_polyhedron_item::overwrite_deform_object() +{ + d->deform_mesh->overwrite_initial_geometry(); + + refresh_all_group_centers(); +} + +void Scene_edit_polyhedron_item::reset_deform_object() +{ + d->deform_mesh->reset(); + refresh_all_group_centers(); +} + + +boost::optional Scene_edit_polyhedron_item::get_minimum_isolated_component() { + Travel_isolated_components::Minimum_visitor visitor; + Travel_isolated_components().travel + (vertices(*polyhedron()).first, vertices(*polyhedron()).second, + polyhedron()->size_of_vertices(), Is_selected(d->deform_mesh), visitor); + return visitor.minimum; +} + + + +boost::optional Scene_edit_polyhedron_item::select_isolated_components(std::size_t threshold) { + typedef boost::function_output_iterator Output_iterator; + Output_iterator out(d->deform_mesh); + + Travel_isolated_components::Selection_visitor visitor(threshold, out); + Travel_isolated_components().travel + (vertices(*polyhedron()).first, vertices(*polyhedron()).second, + polyhedron()->size_of_vertices(), Is_selected(d->deform_mesh), visitor); + + if(visitor.any_inserted) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); } + return visitor.minimum_visitor.minimum; +} + +bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices_group(Ctrl_vertices_group_data_list::iterator& hgb, Ctrl_vertices_group_data_list::iterator& hge); + +bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices_group() +{ + Ctrl_vertices_group_data_list::iterator hgb, hge; + return is_there_any_ctrl_vertices_group(hgb, hge); +} + +bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices() +{ + Ctrl_vertices_group_data_list::iterator hgb, hge; + if(!is_there_any_ctrl_vertices_group(hgb, hge)) { return false; } // there isn't any group of control vertices + + for(; hgb != hge; ++hgb) // check inside groups of control vertices + { + if(!hgb->ctrl_vertices_group.empty()) { return true; } + } + return false; +} + +void Scene_edit_polyhedron_item::refresh_all_group_centers() +{ + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { it->refresh(); } +} + +bool Scene_edit_polyhedron_item::activate_closest_manipulated_frame(int x, int y) +{ + if(d->state.ctrl_pressing && (d->state.left_button_pressing || d->state.right_button_pressing) ) + { // user is deforming currently don't change the state + return false; + } + if(d->ctrl_vertex_frame_map.empty()) { return false; } + + d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + d->rot_constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + qglviewer::Camera* camera = viewer->camera(); + + if(!d->state.ctrl_pressing) + { + if(viewer->manipulatedFrame() == NULL) + { return false;} + viewer->setManipulatedFrame(NULL); + return true; + } + + // now find closest frame and make it active manipulated frame + Ctrl_vertices_group_data_list::iterator min_it = d->ctrl_vertex_frame_map.begin(); + const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(min_it->frame->position()); + float min_dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); + + for(Ctrl_vertices_group_data_list::iterator it = d->ctrl_vertex_frame_map.begin(); it != d->ctrl_vertex_frame_map.end(); ++it) + { + const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->frame->position()); + float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); + if(dist < min_dist) { + min_dist = dist; + min_it = it; + } + } + + //set rotation constraint for the manipulated frame + if (!d->is_rot_free){ + d->rot_constraint.setRotationConstraintDirection(min_it->rot_direction); + d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); + min_it->frame->setConstraint(&d->rot_constraint); + } + else + { + if( d->ui_widget->ActivateFixedPlaneCheckBox->isChecked()) + { + // the constraint is local to the frame + d->rot_constraint.setTranslationConstraint(qglviewer::AxisPlaneConstraint::PLANE,qglviewer::Vec(0,0,1)); + if(!d->ui_widget->ActivatePivotingCheckBox->isChecked()){ + d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FORBIDDEN); + } + min_it->frame->setConstraint(&d->rot_constraint); + } + } + + if(viewer->manipulatedFrame() == min_it->frame) + { return false; } + viewer->setManipulatedFrame(min_it->frame); + + return true; +} + +void Scene_edit_polyhedron_item::update_normals() { + BOOST_FOREACH(vertex_descriptor vd, d->deform_mesh->roi_vertices()) + { + std::size_t id = vd->id(); + const Polyhedron::Traits::Vector_3& n = + CGAL::Polygon_mesh_processing::compute_vertex_normal(vd, d->deform_mesh->halfedge_graph()); + d->normals[id*3] = n.x(); + d->normals[id*3+1] = n.y(); + d->normals[id*3+2] = n.z(); + } } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h index 50879e3877d..6bd2c008d56 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h @@ -33,9 +33,9 @@ #include -typedef Polyhedron::Vertex_handle Vertex_handle; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef Polyhedron::Vertex_handle Vertex_handle; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; typedef boost::graph_traits::face_descriptor face_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::edge_descriptor edge_descriptor; @@ -193,6 +193,8 @@ struct Mouse_keyboard_state_deformation { } }; +typedef std::list Ctrl_vertices_group_data_list; +struct Scene_edit_polyhedron_item_priv; // This class represents a polyhedron in the OpenGL scene class SCENE_EDIT_POLYHEDRON_ITEM_EXPORT Scene_edit_polyhedron_item : public CGAL::Three::Scene_group_item { @@ -242,8 +244,8 @@ public: void compute_bbox() const; Bbox bbox() const{return Scene_item::bbox();} - int get_k_ring() { return k_ring_selector.k_ring; } - void set_k_ring(int v) { k_ring_selector.k_ring = v; } + int get_k_ring(); + void set_k_ring(int v); // take mouse events from viewer, main-window does not work // take keyboard events from main-window, which is more stable @@ -252,34 +254,12 @@ public: void ShowAsSphere(bool b); public Q_SLOTS: - void reset_spheres() - { - spheres = NULL; - } - + void reset_spheres(); void updateDeform(); void change(); void invalidateOpenGLBuffers(); - void selected(const std::set& m) - { - bool any_changes = false; - for(std::set::const_iterator it = m.begin(); it != m.end(); ++it) - { - vertex_descriptor vh = *it; - bool changed = false; - if(ui_widget->ROIRadioButton->isChecked()) { - if(ui_widget->InsertRadioButton->isChecked()) { changed = insert_roi_vertex(vh);} - else { changed = erase_roi_vertex(vh); } - } - else { - if(ui_widget->InsertRadioButton->isChecked()) { changed = insert_control_vertex(vh); } - else { changed = erase_control_vertex(vh); } - } - any_changes |= changed; - } - if(any_changes) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); } - } + void selected(const std::set& m); void select(double orig_x, double orig_y, @@ -291,119 +271,20 @@ public Q_SLOTS: void deform(); // deform the mesh void remesh(); -// members -private: - Ui::DeformMesh* ui_widget; - Scene_polyhedron_item* poly_item; - bool need_change; - // For drawing - mutable std::vector positions; - mutable std::vector tris; - mutable std::vector edges; - mutable std::vector color_lines; - mutable std::vector color_bbox; - mutable std::vector ROI_points; - mutable std::vector control_points; - mutable std::vector ROI_color; - mutable std::vector control_color; - mutable std::vector normals; - mutable std::vector pos_bbox; - mutable std::vector pos_axis; - mutable std::vector pos_frame_plane; - mutable QOpenGLShaderProgram *program; - mutable QOpenGLShaderProgram bbox_program; - mutable std::size_t nb_ROI; - mutable std::size_t nb_control; - mutable std::size_t nb_axis; - mutable std::size_t nb_bbox; - mutable Scene_spheres_item* spheres; +protected: + friend struct Scene_edit_polyhedron_item_priv; + Scene_edit_polyhedron_item_priv* d; - enum Buffer - { - Facet_vertices =0, - Facet_normals, - Roi_vertices, - Control_vertices, - Bbox_vertices, - Axis_vertices, - Axis_colors, - Frame_vertices, - NumberOfBuffers - }; - enum Vao - { - Facets=0, - Roi_points, - Edges, - BBox, - Control_points, - Axis, - Frame_plane, - NumberOfVaos - }; - mutable QOpenGLBuffer *in_bu; - using CGAL::Three::Scene_item::initializeBuffers; - void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const; - void compute_normals_and_vertices(void); - void compute_bbox(const CGAL::Three::Scene_interface::Bbox&); - void reset_drawing_data(); - - Deform_mesh* deform_mesh; - typedef std::list Ctrl_vertices_group_data_list; - Ctrl_vertices_group_data_list::iterator active_group; - Ctrl_vertices_group_data_list ctrl_vertex_frame_map; // keep list of group of control vertices with assoc data - - double length_of_axis; // for drawing axis at a group of control vertices - - // by interleaving 'viewer's events (check constructor), keep followings: - Mouse_keyboard_state_deformation state; - - //For constraint rotation - qglviewer::LocalConstraint rot_constraint; - bool is_rot_free; - - bool own_poly_item; //indicates if the poly_item should be deleted by the destructor - Scene_polyhedron_item_k_ring_selection k_ring_selector; public: // Deformation related functions // - bool insert_control_vertex(vertex_descriptor v) - { - if(!is_there_any_ctrl_vertices_group()) { - print_message("There is no group of control vertices, create one!"); - return false; - } // no group of control vertices to insert + bool insert_control_vertex(vertex_descriptor v); - bool inserted = deform_mesh->insert_control_vertex(v); - if(inserted) { - active_group->ctrl_vertices_group.push_back(v); - active_group->refresh(); - } - return inserted; - } - - bool insert_roi_vertex(vertex_descriptor v) - { - return deform_mesh->insert_roi_vertex(v); - } + bool insert_roi_vertex(vertex_descriptor v); - bool erase_control_vertex(vertex_descriptor v) - { - if(deform_mesh->erase_control_vertex(v)) // API should be safe enough to do that (without checking empty group of control vertices etc.) - { - refresh_all_group_centers(); // since we don't know which group of control vertices v is erased from, refresh all - return true; - } + bool erase_control_vertex(vertex_descriptor v); - print_message("Selected vertex is not a control vertex!"); - return false; - } - - bool erase_roi_vertex(vertex_descriptor v) - { - erase_control_vertex(v); // erase control vertex - return deform_mesh->erase_roi_vertex(v); - } + bool erase_roi_vertex(vertex_descriptor v); void set_all_vertices_as_roi() { @@ -414,208 +295,23 @@ public: } } - void clear_roi() - { - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { - delete it->frame; - } - ctrl_vertex_frame_map.clear(); - deform_mesh->clear_roi_vertices(); + void clear_roi(); - create_ctrl_vertices_group(); // create one new group of control vertices - } + void create_ctrl_vertices_group(); - void create_ctrl_vertices_group() - { - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) { - if(it->ctrl_vertices_group.empty()) { - active_group = it; - return; - } - } + void delete_ctrl_vertices_group(bool create_new = true); - // No empty group of control vertices - qglviewer::ManipulatedFrame* new_frame = new qglviewer::ManipulatedFrame(); - new_frame->setRotationSensitivity(2.0f); - connect(new_frame, SIGNAL(manipulated()), this, SLOT(change())); + void prev_ctrl_vertices_group(); + void next_ctrl_vertices_group(); + void pivoting_end(); - Control_vertices_data hgd(deform_mesh, new_frame); - ctrl_vertex_frame_map.push_back(hgd); - hgd.refresh(); + void pivoting_begin(); - active_group = --ctrl_vertex_frame_map.end(); - - invalidateOpenGLBuffers(); - Q_EMIT itemChanged(); - - print_message("A new empty group of control vertices is created."); - } - - void delete_ctrl_vertices_group(bool create_new = true) - { - if(!is_there_any_ctrl_vertices_group()) { - print_message("There is no group of control vertices to be deleted!"); - return; - } // no group of control vertices - - // delete group representative - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { - if(it == active_group) - { - delete it->frame; - for(std::vector::iterator v_it = it->ctrl_vertices_group.begin(); v_it != it->ctrl_vertices_group.end(); ++v_it) { - deform_mesh->erase_control_vertex(*v_it); - } - ctrl_vertex_frame_map.erase(it); - break; - } - } - - // assign another ctrl_vertices_group to active_group - Ctrl_vertices_group_data_list::iterator hgb, hge; - if( is_there_any_ctrl_vertices_group(hgb, hge) ) - { - active_group = hgb; - } // no group of control vertices - else if(create_new) - { - create_ctrl_vertices_group(); - } - } - - void prev_ctrl_vertices_group() - { - Ctrl_vertices_group_data_list::iterator hgb, hge; - if( !is_there_any_ctrl_vertices_group(hgb, hge) ) { - print_message("There is no group of control vertices to iterate on!"); - return; - } - // shift - if(hgb == active_group) { active_group = --hge; } - else {--active_group; } - } - - void next_ctrl_vertices_group() - { - Ctrl_vertices_group_data_list::iterator hgb, hge; - if( !is_there_any_ctrl_vertices_group(hgb, hge) ) { - print_message("There is no group of control vertices to iterate on!"); - return; - } - // shift - if(--hge == active_group) { active_group = hgb; } - else {++active_group; } - } - - void pivoting_end() - { - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { - //update constraint rotation vector, set only for the last group - it->rot_direction = it->frame->rotation().rotate( qglviewer::Vec(0.,0.,1.) ); - //translate center of the frame - qglviewer::Vec vec= it->frame->position(); - it->refresh(); - it->frame_initial_center = vec; - it->frame->setPosition(vec); - } - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { - it->frame->blockSignals(false); - } - } - - void pivoting_begin() - { - is_rot_free=true; - rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - rot_constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - - // just block signals to prevent deformation - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { - it->frame->blockSignals(true); - } - } - - void save_roi(const char* file_name) const - { - std::ofstream out(file_name); - // save roi - out << deform_mesh->roi_vertices().size() << std::endl; - BOOST_FOREACH(vertex_descriptor vd, deform_mesh->roi_vertices()) - { - out << vd->id() << " "; - } - out << std::endl; - // save control vertices - - out << ctrl_vertex_frame_map.size() << std::endl; // control vertices count - for(Ctrl_vertices_group_data_list::const_iterator hgb = ctrl_vertex_frame_map.begin(); hgb != ctrl_vertex_frame_map.end(); ++hgb) { - - out << hgb->ctrl_vertices_group.size() << std::endl; - for(std::vector::const_iterator hb = hgb->ctrl_vertices_group.begin(); hb != hgb->ctrl_vertices_group.end(); ++hb) - { - out << (*hb)->id() << " "; - } - out << std::endl; - } - } - - void read_roi(const char* file_name) - { - clear_roi(); - delete_ctrl_vertices_group(false); - - // put vertices to vector - std::vector all_vertices; - all_vertices.reserve(num_vertices(deform_mesh->halfedge_graph())); - vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(deform_mesh->halfedge_graph()); vb != ve; ++vb) { - all_vertices.push_back(*vb); - } - // read roi - std::ifstream in(file_name); - int roi_size; - in >> roi_size; - while(roi_size-- > 0) - { - std::size_t v_id; - in >> v_id; - insert_roi_vertex(all_vertices[v_id]); - } - // read control vertices - int ctrl_vertices_group_size; - in >> ctrl_vertices_group_size; - while(ctrl_vertices_group_size-- > 0) - { - create_ctrl_vertices_group(); - int ctrl_size; - in >> ctrl_size; - while(ctrl_size-- > 0) - { - std::size_t v_id; - in >> v_id; - insert_control_vertex(all_vertices[v_id]); - } - } - } - - void overwrite_deform_object() - { - deform_mesh->overwrite_initial_geometry(); - - refresh_all_group_centers(); - } - - void reset_deform_object() - { - deform_mesh->reset(); - refresh_all_group_centers(); - } + void save_roi(const char* file_name) const; + void read_roi(const char* file_name); + void overwrite_deform_object(); + void reset_deform_object(); struct Is_selected { Deform_mesh* dm; Is_selected(Deform_mesh* dm) : dm(dm) {} @@ -624,14 +320,7 @@ public: } }; - boost::optional get_minimum_isolated_component() { - Travel_isolated_components::Minimum_visitor visitor; - Travel_isolated_components().travel - (vertices(*polyhedron()).first, vertices(*polyhedron()).second, - polyhedron()->size_of_vertices(), Is_selected(deform_mesh), visitor); - return visitor.minimum; - } - + boost::optional get_minimum_isolated_component(); struct Select_roi_output { Select_roi_output(Deform_mesh* dm) : dm(dm) { } void operator()(Vertex_handle vh) { @@ -640,18 +329,8 @@ public: Deform_mesh* dm; }; - boost::optional select_isolated_components(std::size_t threshold) { - typedef boost::function_output_iterator Output_iterator; - Output_iterator out(deform_mesh); + boost::optional select_isolated_components(std::size_t threshold) ; - Travel_isolated_components::Selection_visitor visitor(threshold, out); - Travel_isolated_components().travel - (vertices(*polyhedron()).first, vertices(*polyhedron()).second, - polyhedron()->size_of_vertices(), Is_selected(deform_mesh), visitor); - - if(visitor.any_inserted) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); } - return visitor.minimum_visitor.minimum; - } protected: // Deformation related functions // void print_message(const QString& /*message*/) @@ -659,113 +338,17 @@ protected: // std::cout << message.toStdString() << std::endl; } - bool is_there_any_ctrl_vertices_group(Ctrl_vertices_group_data_list::iterator& hgb, Ctrl_vertices_group_data_list::iterator& hge) - { - hgb = ctrl_vertex_frame_map.begin(); hge = ctrl_vertex_frame_map.end(); - return hgb != hge; - } + bool is_there_any_ctrl_vertices_group(Ctrl_vertices_group_data_list::iterator& hgb, Ctrl_vertices_group_data_list::iterator& hge); - bool is_there_any_ctrl_vertices_group() - { - Ctrl_vertices_group_data_list::iterator hgb, hge; - return is_there_any_ctrl_vertices_group(hgb, hge); - } + bool is_there_any_ctrl_vertices_group(); - bool is_there_any_ctrl_vertices() - { - Ctrl_vertices_group_data_list::iterator hgb, hge; - if(!is_there_any_ctrl_vertices_group(hgb, hge)) { return false; } // there isn't any group of control vertices - - for(; hgb != hge; ++hgb) // check inside groups of control vertices - { - if(!hgb->ctrl_vertices_group.empty()) { return true; } - } - return false; - } - - void refresh_all_group_centers() - { - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { it->refresh(); } - } - - bool activate_closest_manipulated_frame(int x, int y) - { - if(state.ctrl_pressing && (state.left_button_pressing || state.right_button_pressing) ) - { // user is deforming currently don't change the state - return false; - } - if(ctrl_vertex_frame_map.empty()) { return false; } - - rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - rot_constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); - - if(!state.ctrl_pressing) - { - if(viewer->manipulatedFrame() == NULL) - { return false;} - viewer->setManipulatedFrame(NULL); - return true; - } - - // now find closest frame and make it active manipulated frame - Ctrl_vertices_group_data_list::iterator min_it = ctrl_vertex_frame_map.begin(); - const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(min_it->frame->position()); - float min_dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); - - for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) - { - const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->frame->position()); - float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); - if(dist < min_dist) { - min_dist = dist; - min_it = it; - } - } - - //set rotation constraint for the manipulated frame - if (!is_rot_free){ - rot_constraint.setRotationConstraintDirection(min_it->rot_direction); - rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); - min_it->frame->setConstraint(&rot_constraint); - } - else - { - if( ui_widget->ActivateFixedPlaneCheckBox->isChecked()) - { - // the constraint is local to the frame - rot_constraint.setTranslationConstraint(qglviewer::AxisPlaneConstraint::PLANE,qglviewer::Vec(0,0,1)); - if(!ui_widget->ActivatePivotingCheckBox->isChecked()){ - rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FORBIDDEN); - } - min_it->frame->setConstraint(&rot_constraint); - } - } - - if(viewer->manipulatedFrame() == min_it->frame) - { return false; } - viewer->setManipulatedFrame(min_it->frame); - - return true; - } + bool is_there_any_ctrl_vertices(); + void refresh_all_group_centers(); + bool activate_closest_manipulated_frame(int x, int y); bool keyPressEvent(QKeyEvent* e); - void update_normals() { - BOOST_FOREACH(vertex_descriptor vd, deform_mesh->roi_vertices()) - { - std::size_t id = vd->id(); - const Polyhedron::Traits::Vector_3& n = - CGAL::Polygon_mesh_processing::compute_vertex_normal(vd, deform_mesh->halfedge_graph()); - normals[id*3] = n.x(); - normals[id*3+1] = n.y(); - normals[id*3+2] = n.z(); - - } - } + void update_normals(); double scene_diag() const { const double& xdelta = bbox().xmax() - bbox().xmin();