diff --git a/Polyhedron/demo/Polyhedron/Deform_mesh.ui b/Polyhedron/demo/Polyhedron/Deform_mesh.ui index 5fb37ffe116..63970588ea0 100644 --- a/Polyhedron/demo/Polyhedron/Deform_mesh.ui +++ b/Polyhedron/demo/Polyhedron/Deform_mesh.ui @@ -7,7 +7,7 @@ 0 0 317 - 369 + 409 @@ -177,6 +177,43 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Override + + + + + + + + + Qt::Horizontal + + + @@ -236,6 +273,12 @@ + + + 0 + 0 + + Apply and Close diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp index ebdf529d57d..f4421ec49ef 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp @@ -50,6 +50,7 @@ public slots: void on_ShowROICheckBox_stateChanged(int state); void on_ShowAsSphereCheckBox_stateChanged(int state); void on_ActivatePivotingCheckBox_stateChanged(int state); + void on_OverridePushButton_clicked(); void on_SaveROIPushButton_clicked(); void on_ReadROIPushButton_clicked(); void dock_widget_visibility_changed(bool visible); @@ -122,6 +123,8 @@ void Polyhedron_demo_edit_polyhedron_plugin::init(QMainWindow* mainWindow, Scene connect(ui_widget->ShowROICheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ShowROICheckBox_stateChanged(int))); connect(ui_widget->ShowAsSphereCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ShowAsSphereCheckBox_stateChanged(int))); connect(ui_widget->ActivatePivotingCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ActivatePivotingCheckBox_stateChanged(int))); + connect(ui_widget->OverridePushButton, SIGNAL(clicked()), this, SLOT(on_OverridePushButton_clicked())); + connect(ui_widget->SaveROIPushButton, SIGNAL(clicked()), this, SLOT(on_SaveROIPushButton_clicked())); connect(ui_widget->ReadROIPushButton, SIGNAL(clicked()), this, SLOT(on_ReadROIPushButton_clicked())); connect(dock_widget, SIGNAL(visibilityChanged(bool)), this, SLOT(dock_widget_visibility_changed(bool)) ); @@ -234,6 +237,14 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_ActivatePivotingCheckBox_stateCh scene->itemChanged(edit_item); } } +void Polyhedron_demo_edit_polyhedron_plugin::on_OverridePushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->override_deform_object(); +} void Polyhedron_demo_edit_polyhedron_plugin::on_SaveROIPushButton_clicked() { diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp index 7493ec0d972..610d8334012 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp @@ -190,8 +190,8 @@ bool Scene_edit_polyhedron_item::eventFilter(QObject *target, QEvent *event) void Scene_edit_polyhedron_item::draw() const { poly_item->direct_draw(); CGAL::GL::Color color; - //color.set_rgb_color(0.f, 0.f, 0.f); - //poly_item->direct_draw_edges(); + color.set_rgb_color(0.f, 0.f, 0.f); + poly_item->direct_draw_edges(); CGAL::GL::Point_size point_size; point_size.set_point_size(5); color.set_rgb_color(0, 1.f, 0); diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index 9e3b7d3af03..c4b23b02fdd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -402,6 +402,30 @@ public: bool show_as_sphere() const { return ui_widget->ShowAsSphereCheckBox->isChecked(); } + void override_deform_object() + { + deform_mesh.override_halfedge_graph(); + + Deform_mesh::Roi_iterator rb, re; + for(boost::tie(rb, re) = deform_mesh.roi_vertices(); rb != re; ++rb) + { + original_positions[(*rb)->id()] = (*rb)->point(); + } + + for(Handle_group_data_list::iterator it = handle_frame_map.begin(); it != handle_frame_map.end(); ++it) + { + it->frame_initial_center = calculate_original_center(it->handle_group); + + it->frame->blockSignals(true); + it->frame->setOrientation(qglviewer::Quaternion()); + it->frame->setPosition(it->frame_initial_center); + it->frame->blockSignals(false); + + it->bbox = calculate_bbox(it->handle_group); + } + } + + protected: // Deformation related functions // void print_message(const QString& message) @@ -439,7 +463,7 @@ protected: void process_selection(vertex_descriptor v, int k_ring, bool is_roi, bool is_insert, bool use_euclidean) { - std::cout << "Process k-ring: " << k_ring << " roi: " << is_roi << " insert: " << is_insert << std::endl; + // std::cout << "Process k-ring: " << k_ring << " roi: " << is_roi << " insert: " << is_insert << std::endl; std::map neighs = use_euclidean ? extract_k_ring_with_distance(*polyhedron(), v, k_ring) : diff --git a/Surface_modeling/include/CGAL/Deform_mesh.h b/Surface_modeling/include/CGAL/Deform_mesh.h index 4880d1a2fd3..348f42c8505 100644 --- a/Surface_modeling/include/CGAL/Deform_mesh.h +++ b/Surface_modeling/include/CGAL/Deform_mesh.h @@ -165,6 +165,7 @@ private: bool last_preprocess_successful; ///< stores the result of last call to preprocess() Handle_group_container handle_group_list; ///< user specified handles + Weight_calculator weight_calculator; private: Deform_mesh(const Self& s) { } @@ -190,7 +191,8 @@ public: double tolerance = 1e-4, Weight_calculator weight_calculator = Weight_calculator()) : polyhedron(polyhedron), vertex_index_map(vertex_index_map), edge_index_map(edge_index_map), - iterations(iterations), tolerance(tolerance), need_preprocess(true), last_preprocess_successful(false), + iterations(iterations), tolerance(tolerance), weight_calculator(weight_calculator), + need_preprocess(true), last_preprocess_successful(false), is_roi_map(std::vector(boost::num_vertices(polyhedron), false)), is_hdl_map(std::vector(boost::num_vertices(polyhedron), false)), ros_id_map(std::vector(boost::num_vertices(polyhedron), -1)) @@ -214,7 +216,7 @@ public: edge_weight.reserve(boost::num_edges(polyhedron)); for(boost::tie(eb, ee) = boost::edges(polyhedron); eb != ee; ++eb) { - edge_weight.push_back(weight_calculator(*eb, polyhedron)); + edge_weight.push_back(this->weight_calculator(*eb, polyhedron)); } } @@ -547,7 +549,6 @@ public: */ void deform(unsigned int iterations, double tolerance) { - // CGAL_precondition(!need_preprocess || !"preprocess() need to be called before deforming!"); if(need_preprocess) { preprocess(); } if(!last_preprocess_successful) { @@ -637,6 +638,50 @@ public: */ const Polyhedron& halfedge_graph() const { return polyhedron; } + + /** + * Makes current positions as original positions. Effect of calling this funtion is equal to creating a new deformation + * object with current polyhedron and transfering region-of-interest and handles. + * \note There should not be any need for preprocess when this function is called, otherwise it just returns. + */ + void override_halfedge_graph() + { + if(roi.empty()) { return; } // no ROI to override + + if(need_preprocess) { preprocess(); } // the roi should be preprocessed since we are using original_position vec + + Roi_iterator rb, re; + for(boost::tie(rb, re) = roi_vertices(); rb != re; ++rb) + { + original[ros_id(*rb)] = (*rb)->point(); + } + + // now I need to compute weights for edges incident to roi vertices + std::vector is_weight_computed(boost::num_edges(polyhedron), false); + for(boost::tie(rb, re) = roi_vertices(); rb != re; ++rb) + { + in_edge_iterator e, e_end; + for (boost::tie(e,e_end) = boost::in_edges(*rb, polyhedron); e != e_end; e++) + { + std::size_t id_e = id(*e); + if(is_weight_computed[id_e]) { continue; } + + edge_weight[id_e] = weight_calculator(*e, polyhedron); + is_weight_computed[id_e] = true; + + edge_descriptor e_opp = CGAL::opposite_edge(*e, polyhedron); + std::size_t id_e_opp = id(e_opp); + + edge_weight[id_e_opp] = weight_calculator(e_opp, polyhedron); + is_weight_computed[id_e_opp] = true; + } + } + + // also set rotation matrix to identity + std::fill(rot_mtr.begin(), rot_mtr.end(), Eigen::Matrix3d().setIdentity()); + + need_preprocess = true; // now we need reprocess + } /// @} Utilities