From 6f5122c4a1b5a7a653ffb42e709567d01f5b0302 Mon Sep 17 00:00:00 2001 From: iyaz Date: Sun, 26 May 2013 16:04:36 +0300 Subject: [PATCH] Demo updates, (I added a "paint-like smoothing" feature but I am going to remove it since real-time smoothing is not efficient due to AABB reconstruction. --- .../Polyhedron_demo_hole_filling_plugin.cpp | 31 ++- ...lyhedron_demo_smoothing_fairing_plugin.cpp | 217 +++++++++++++----- .../Scene_polyhedron_item_decorator.cpp | 8 +- .../Scene_polyhedron_item_decorator.h | 4 +- .../Polyhedron/Smoothing_fairing_widget.ui | 179 +++++++++------ 5 files changed, 304 insertions(+), 135 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp index 218a69fa6e8..3eccd1b8a56 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp @@ -39,6 +39,7 @@ public slots: void on_Create_polyline_item_button(); void on_Fill_and_update_button(); void on_Fill_all_holes_button(); + private: QMainWindow* mw; Scene_interface* scene; @@ -158,15 +159,23 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_all_holes_button() { if(it->is_border()){ any_changes = true; - if(ui_widget->Scale_dependent_weight_radio_button->isChecked()) - CGAL::fill(poly, it, refine, alpha, fair, - CGAL::internal::Fairing_weight_selector::weight_calculator()); - if(ui_widget->Uniform_weight_radio_button->isChecked()) - CGAL::fill(poly, it, refine, alpha, fair, - CGAL::internal::Fairing_weight_selector::weight_calculator()); - else - CGAL::fill(poly, it, refine, alpha, fair, - CGAL::internal::Fairing_weight_selector::weight_calculator()); + if(!fair && !refine) { + CGAL::triangulate_hole(poly, it); + } + else if(!fair) { + CGAL::triangulate_and_refine_hole(poly, it, NULL, alpha); + } + else { + if(ui_widget->Scale_dependent_weight_radio_button->isChecked()) + CGAL::triangulate_refine_and_fair_hole(poly, it, NULL, alpha, + CGAL::Fairing_scale_dependent_weight()); + if(ui_widget->Uniform_weight_radio_button->isChecked()) + CGAL::triangulate_refine_and_fair_hole(poly, it, NULL, alpha, + CGAL::Fairing_uniform_weight()); + else + CGAL::triangulate_refine_and_fair_hole(poly, it, NULL, alpha, + CGAL::Fairing_cotangent_weight()); + } it = poly.halfedges_begin(); continue; @@ -220,8 +229,8 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_and_update_button() { // new_item->setName(tr("%1-Filled-%2-(alpha:%3)").arg(poly_item->name()).arg(param_exp).arg(alpha)); //} - CGAL::fill(*poly_item->polyhedron(), it->second.second, refine, alpha, fair); - scene->itemChanged(poly_item); + //CGAL::fill(*poly_item->polyhedron(), it->second.second, refine, alpha, fair); + // scene->itemChanged(poly_item); //if(create_new) { // using std::swap; // swap(*poly_item->polyhedron(), *new_item->polyhedron()); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_smoothing_fairing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_smoothing_fairing_plugin.cpp index ac177023683..4bbc1a231e2 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_smoothing_fairing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_smoothing_fairing_plugin.cpp @@ -8,6 +8,7 @@ //#include #include +#include #include #include @@ -17,11 +18,14 @@ #include #include #include +#include #include #include #include +#include + #include #include "opengl_tools.h" @@ -39,6 +43,12 @@ public: QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); + // assign id's to vertices (save roi, load roi) + std::size_t idx = 0; + for(Polyhedron::Vertex_iterator it = polyhedron()->vertices_begin(); + it != polyhedron()->vertices_end(); ++it, ++idx) { + it->id() = idx; + } } void draw_edges() const { @@ -48,7 +58,7 @@ public: } } void draw() const { - poly_item->draw(); + poly_item->direct_draw(); draw_ROI(); } void draw_ROI() const { @@ -70,6 +80,44 @@ public: } } + void save_roi(const char* file_name) const { + std::ofstream out(file_name); + // save roi + for(std::set::iterator it = selected_vertices.begin(); + it != selected_vertices.end(); ++it) { + out << (*it)->id() << " "; + } + out.close(); + } + void load_roi(const char* file_name) { + // put vertices to vector + std::vector all_vertices; + all_vertices.reserve(polyhedron()->size_of_vertices()); + Polyhedron::Vertex_iterator vb(polyhedron()->vertices_begin()), ve(polyhedron()->vertices_end()); + for( ;vb != ve; ++vb) { + all_vertices.push_back(vb); + } + // read roi + std::ifstream in(file_name); + std::size_t idx; + while(in >> idx) { + selected_vertices.insert(all_vertices[idx]); + } + in.close(); + } + + void changed_with_poly_item() { + poly_item->changed(); + emit itemChanged(); + } +private: + // for transform iterator + struct Get_key { + typedef Vertex_handle result_type; + Vertex_handle operator()(const std::pair& map_pair) const + { return map_pair.first; } + }; + public slots: void changed() { // do not use decorator function, which calls changed on poly_item which cause deletion of AABB @@ -79,23 +127,33 @@ public slots: // get vertex descriptor Get_vertex_handle get_vertex_handle; get_vertex_handle.vertex_ptr = static_cast(void_ptr); - poly_item->polyhedron()->delegate(get_vertex_handle); + polyhedron()->delegate(get_vertex_handle); Vertex_handle clicked_vertex = get_vertex_handle.vh; // use clicked_vertex, do what you want bool is_insert = ui_widget->Insertion_radio_button->isChecked(); + bool is_paint_like_smooth = ui_widget->Paint_like_smooth_radio_button->isChecked(); + int k_ring = ui_widget->Brush_size_spin_box->value(); - std::map selection = extract_k_ring(*poly_item->polyhedron(), clicked_vertex, k_ring); - bool any_change = false; - if(is_insert) { - for(std::map::iterator it = selection.begin(); it != selection.end(); ++it) { - any_change |= selected_vertices.insert(it->first).second; - } - }else { - for(std::map::iterator it = selection.begin(); it != selection.end(); ++it) { - any_change |= selected_vertices.erase(it->first) != 0; + std::map selection = extract_k_ring(*polyhedron(), clicked_vertex, k_ring); + if(!is_paint_like_smooth) + { + bool any_change = false; + if(is_insert) { + for(std::map::iterator it = selection.begin(); it != selection.end(); ++it) { + any_change |= selected_vertices.insert(it->first).second; + } + }else { + for(std::map::iterator it = selection.begin(); it != selection.end(); ++it) { + any_change |= selected_vertices.erase(it->first) != 0; + } } + if(any_change) { emit itemChanged(); } + } + else { + CGAL::smooth(*polyhedron(), boost::make_transform_iterator(selection.begin(), Get_key()), + boost::make_transform_iterator(selection.end(), Get_key())); + changed_with_poly_item(); } - if(any_change) { emit itemChanged(); } } protected: @@ -164,11 +222,8 @@ protected: // structs struct Mouse_keyboard_state { - bool shift_pressing; - bool left_button_pressing; - - Mouse_keyboard_state() - : shift_pressing(false), left_button_pressing(false) { } + bool shift_pressing, left_button_pressing; + Mouse_keyboard_state() : shift_pressing(false), left_button_pressing(false) { } }; struct Get_vertex_handle : public CGAL::Modifier_base @@ -198,18 +253,32 @@ public: bool applicable() const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } void print_message(QString message) { messages->information(message);} QList actions() const { return QList() << actionSmoothingFairing; } + Scene_polyhedron_selectable_item* get_selected_item() { + int item_id = scene->mainSelectionIndex(); + Scene_polyhedron_selectable_item* selectable_item = qobject_cast(scene->item(item_id)); + if(!selectable_item) { + print_message("Error: there is no selected polyhedron item!"); + return NULL; + } + return selectable_item; + } void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* m); Scene_polyhedron_selectable_item* convert_to_selectable_polyhedron(Scene_interface::Item_id i, Scene_polyhedron_item* poly_item); Scene_polyhedron_item* convert_to_plain_polyhedron(Scene_interface::Item_id i, Scene_polyhedron_selectable_item* selectable_poly); - + public slots: void smoothing_fairing_action(); void dock_widget_visibility_changed(bool visible); void on_Fair_button_clicked(); + void on_Smooth_button_clicked(); void on_Set_all_vertices_button_clicked(); void on_Clear_ROI_button_clicked(); void on_Show_ROI_check_box_stateChanged(int state); + void on_Save_ROI_button_clicked(); + void on_Load_ROI_button_clicked(); + void new_item_created(int item_id); + private: typedef Scene_interface::Item_id Item_id; @@ -243,9 +312,15 @@ void Polyhedron_demo_smoothing_fairing_plugin::init(QMainWindow* mw, connect(dock_widget, SIGNAL(visibilityChanged(bool)), this, SLOT(dock_widget_visibility_changed(bool)) ); connect(ui_widget->Fair_button, SIGNAL(clicked()), this, SLOT(on_Fair_button_clicked())); + connect(ui_widget->Smooth_button, SIGNAL(clicked()), this, SLOT(on_Smooth_button_clicked())); connect(ui_widget->Set_all_vertices_button, SIGNAL(clicked()), this, SLOT(on_Set_all_vertices_button_clicked())); connect(ui_widget->Clear_ROI_button, SIGNAL(clicked()), this, SLOT(on_Clear_ROI_button_clicked())); connect(ui_widget->Show_ROI_check_box, SIGNAL(stateChanged(int)), this, SLOT(on_Show_ROI_check_box_stateChanged(int))); + connect(ui_widget->Save_ROI_button, SIGNAL(clicked()), this, SLOT(on_Save_ROI_button_clicked())); + connect(ui_widget->Load_ROI_button, SIGNAL(clicked()), this, SLOT(on_Load_ROI_button_clicked())); + + QObject* scene = dynamic_cast(scene_interface); + if(scene) { connect(scene, SIGNAL(newItem(int)), this, SLOT(new_item_created(int))); } } void Polyhedron_demo_smoothing_fairing_plugin::smoothing_fairing_action(){ @@ -254,58 +329,94 @@ void Polyhedron_demo_smoothing_fairing_plugin::smoothing_fairing_action(){ } } void Polyhedron_demo_smoothing_fairing_plugin::on_Set_all_vertices_button_clicked() { - int item_id = scene->mainSelectionIndex(); - Scene_polyhedron_selectable_item* poly_item = qobject_cast(scene->item(item_id)); - if(!poly_item) { - print_message("Error: there is no selected polyhedron item!"); - return; - } - Polyhedron::Vertex_iterator vb(poly_item->polyhedron()->vertices_begin()), ve(poly_item->polyhedron()->vertices_end()); + Scene_polyhedron_selectable_item* selectable_item = get_selected_item(); + if(!selectable_item) { return; } + + Polyhedron::Vertex_iterator vb(selectable_item->polyhedron()->vertices_begin()), ve(selectable_item->polyhedron()->vertices_end()); for( ;vb != ve; ++vb) { - poly_item->selected_vertices.insert(vb); + selectable_item->selected_vertices.insert(vb); } + scene->itemChanged(selectable_item); } void Polyhedron_demo_smoothing_fairing_plugin::on_Clear_ROI_button_clicked() { - int item_id = scene->mainSelectionIndex(); - Scene_polyhedron_selectable_item* poly_item = qobject_cast(scene->item(item_id)); - if(!poly_item) { - print_message("Error: there is no selected polyhedron item!"); - return; - } - poly_item->selected_vertices.clear(); + Scene_polyhedron_selectable_item* selectable_item = get_selected_item(); + if(!selectable_item) { return; } + selectable_item->selected_vertices.clear(); + + scene->itemChanged(selectable_item); } void Polyhedron_demo_smoothing_fairing_plugin::on_Show_ROI_check_box_stateChanged(int /*state*/) { for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) { - Scene_polyhedron_selectable_item* poly_item = qobject_cast(scene->item(i)); - if(!poly_item) { continue; } + Scene_polyhedron_selectable_item* selectable_item = qobject_cast(scene->item(i)); + if(!selectable_item) { continue; } - scene->itemChanged(poly_item); // just for redraw + scene->itemChanged(selectable_item); // just for redraw } } +void Polyhedron_demo_smoothing_fairing_plugin::on_Save_ROI_button_clicked() +{ + Scene_polyhedron_selectable_item* selectable_item = get_selected_item(); + if(!selectable_item) { return; } -void Polyhedron_demo_smoothing_fairing_plugin::on_Fair_button_clicked() { + QString fileName = QFileDialog::getSaveFileName(mw, "Save", + selectable_item->name() + ".txt", "Text (*.txt)"); + if(fileName.isNull()) { return; } - int item_id = scene->mainSelectionIndex(); - Scene_polyhedron_selectable_item* poly_item = qobject_cast(scene->item(item_id)); - if(!poly_item) { - print_message("Error: there is no selected polyhedron item!"); - return; + selectable_item->save_roi(fileName.toLocal8Bit().data()); +} +void Polyhedron_demo_smoothing_fairing_plugin::on_Load_ROI_button_clicked() +{ + Scene_polyhedron_selectable_item* selectable_item = get_selected_item(); + if(!selectable_item) { return; } + + QString fileName = QFileDialog::getOpenFileName(mw, "Read", + selectable_item->name() + ".txt", "Text (*.txt)"); + if(fileName.isNull()) { return; } + + selectable_item->load_roi(fileName.toLocal8Bit().data()); + scene->itemChanged(selectable_item); +} +void Polyhedron_demo_smoothing_fairing_plugin::new_item_created(int item_id) +{ + if(dock_widget->isVisible()) { + Scene_polyhedron_item* poly_item = + qobject_cast(scene->item(item_id)); + if(poly_item) { + convert_to_selectable_polyhedron(item_id, poly_item); + } } - - if(ui_widget->Scale_dependent_weight_radio_button->isChecked()) - CGAL::fair(*poly_item->polyhedron(), poly_item->selected_vertices, - CGAL::internal::Fairing_weight_selector::weight_calculator()); - if(ui_widget->Uniform_weight_radio_button->isChecked()) - CGAL::fair(*poly_item->polyhedron(), poly_item->selected_vertices, - CGAL::internal::Fairing_weight_selector::weight_calculator()); - else - CGAL::fair(*poly_item->polyhedron(), poly_item->selected_vertices, - CGAL::internal::Fairing_weight_selector::weight_calculator()); - poly_item->changed(); } +void Polyhedron_demo_smoothing_fairing_plugin::on_Fair_button_clicked() +{ + Scene_polyhedron_selectable_item* selectable_item = get_selected_item(); + if(!selectable_item) { return; } + + if(ui_widget->Scale_dependent_weight_radio_button->isChecked()) + CGAL::fair(*selectable_item->polyhedron(), selectable_item->selected_vertices, + CGAL::Fairing_scale_dependent_weight()); + if(ui_widget->Uniform_weight_radio_button->isChecked()) + CGAL::fair(*selectable_item->polyhedron(), selectable_item->selected_vertices, + CGAL::Fairing_uniform_weight()); + else + CGAL::fair(*selectable_item->polyhedron(), selectable_item->selected_vertices, + CGAL::Fairing_cotangent_weight()); + selectable_item->changed_with_poly_item(); +} + +void Polyhedron_demo_smoothing_fairing_plugin::on_Smooth_button_clicked() +{ + Scene_polyhedron_selectable_item* selectable_item = get_selected_item(); + if(!selectable_item) { return; } + + CGAL::smooth(*selectable_item->polyhedron(), + selectable_item->selected_vertices.begin(), + selectable_item->selected_vertices.end()); + + selectable_item->changed_with_poly_item(); +} Scene_polyhedron_selectable_item* Polyhedron_demo_smoothing_fairing_plugin::convert_to_selectable_polyhedron(Item_id i, Scene_polyhedron_item* poly_item) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp index ae68b9f90ff..6d63ddf71bd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp @@ -6,7 +6,7 @@ Scene_polyhedron_item_decorator::Scene_polyhedron_item_decorator(Scene_polyhedro { } Scene_polyhedron_item_decorator::~Scene_polyhedron_item_decorator() -{ } +{ delete poly_item; } Scene_polyhedron_item_decorator* Scene_polyhedron_item_decorator::clone() const { @@ -88,8 +88,10 @@ Scene_polyhedron_item_decorator::select(double orig_x, dir_z); } -Scene_polyhedron_item* Scene_polyhedron_item_decorator::to_polyhedron_item() const { - return poly_item; +Scene_polyhedron_item* Scene_polyhedron_item_decorator::to_polyhedron_item() { + Scene_polyhedron_item* tmp = poly_item; + poly_item = NULL; + return tmp; } #include "Scene_polyhedron_item_decorator.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h index e06517b4cb4..d92bfc83816 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h @@ -38,9 +38,9 @@ public: const Polyhedron* polyhedron() const; - /// Returns a Scene_polyhedron_item from the decorator item + /// Transfers the ownership of Scene_polyhedron_item, and sets NULL /// The item 'this' must be destroy just after a call to this function. - Scene_polyhedron_item* to_polyhedron_item() const; + Scene_polyhedron_item* to_polyhedron_item(); // Get dimensions bool isFinite() const { return true; } diff --git a/Polyhedron/demo/Polyhedron/Smoothing_fairing_widget.ui b/Polyhedron/demo/Polyhedron/Smoothing_fairing_widget.ui index 61d73c21e7c..f1ac9172aeb 100644 --- a/Polyhedron/demo/Polyhedron/Smoothing_fairing_widget.ui +++ b/Polyhedron/demo/Polyhedron/Smoothing_fairing_widget.ui @@ -6,8 +6,8 @@ 0 0 - 237 - 320 + 274 + 407 @@ -28,76 +28,105 @@ - - - - - - - - - Insertion - - - true - - - - - - - Removal - - - - - - - - - Brush size: - - - - - - - - - - - - - - Set All Vertices as ROI - - - - - - - Clear ROI - - - - - - - - - - - Show ROI - - - true + + + ROI Parameters + + + + + + + + + + + Insertion + + + true + + + + + + + Removal + + + + + + + Paint-like smooth + + + + + + + + + Brush size: + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + Set All Vertices as ROI + + + + + + + Clear ROI + + + + + + + + + + + Show ROI + + + true + + + + - Fair Parameters + Weighting Parameters @@ -130,6 +159,24 @@ + + + + + + Save ROI + + + + + + + Load ROI + + + + +