1 2 #include <QtCore/qglobal.h> 3 4 #include <CGAL/Three/Polyhedron_demo_plugin_interface.h> 5 6 #include "Scene_surface_mesh_item.h" 7 #include "Scene_polyhedron_selection_item.h" 8 9 #include <CGAL/iterator.h> 10 #include <CGAL/boost/graph/graph_traits_Polyhedron_3.h> 11 #include <CGAL/boost/graph/properties_Polyhedron_3.h> 12 #include <CGAL/utility.h> 13 14 #include <CGAL/Polygon_mesh_processing/random_perturbation.h> 15 16 #include <boost/graph/graph_traits.hpp> 17 #include <CGAL/property_map.h> 18 19 #include <QElapsedTimer> 20 #include <QAction> 21 #include <QMainWindow> 22 #include <QApplication> 23 #include <QString> 24 #include <QInputDialog> 25 #include <QtPlugin> 26 #include <QMessageBox> 27 28 #include "ui_Random_perturbation_dialog.h" 29 30 using namespace CGAL::Three; 31 class Polyhedron_demo_random_perturbation_plugin : 32 public QObject, 33 public Polyhedron_demo_plugin_interface 34 { 35 Q_OBJECT 36 Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) 37 Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "random_perturbation_plugin.json") 38 39 public: init(QMainWindow * mainWindow,Scene_interface * scene_interface,Messages_interface *)40 void init(QMainWindow* mainWindow, 41 Scene_interface* scene_interface, 42 Messages_interface*) 43 { 44 this->scene = scene_interface; 45 this->mw = mainWindow; 46 47 actionRandomPerturbation_ = new QAction("Random perturbation", mw); 48 actionRandomPerturbation_->setProperty("subMenuName", "Polygon Mesh Processing"); 49 if (actionRandomPerturbation_) { 50 connect(actionRandomPerturbation_, SIGNAL(triggered()), 51 this, SLOT(random_perturb())); 52 } 53 } 54 actions() const55 QList<QAction*> actions() const { 56 return QList<QAction*>() << actionRandomPerturbation_; 57 } 58 applicable(QAction *) const59 bool applicable(QAction*) const 60 { 61 const Scene_interface::Item_id index = scene->mainSelectionIndex(); 62 if (qobject_cast<Scene_surface_mesh_item*>(scene->item(index))) 63 return true; 64 else if (qobject_cast<Scene_polyhedron_selection_item*>(scene->item(index))) 65 return true; 66 else 67 return false; 68 } 69 70 public Q_SLOTS: random_perturb()71 void random_perturb() 72 { 73 const Scene_interface::Item_id index = scene->mainSelectionIndex(); 74 Scene_surface_mesh_item* poly_item = 75 qobject_cast<Scene_surface_mesh_item*>(scene->item(index)); 76 Scene_polyhedron_selection_item* selection_item = 77 qobject_cast<Scene_polyhedron_selection_item*>(scene->item(index)); 78 79 //Create dialog box 80 QDialog dialog(mw); 81 Ui::Random_perturbation_dialog ui 82 = perturb_dialog(&dialog, poly_item, selection_item); 83 84 //Get values 85 int i = dialog.exec(); 86 if (i == QDialog::Rejected) 87 { 88 std::cout << "Perturbation aborted" << std::endl; 89 return; 90 } 91 92 double max_move = ui.moveSize_dspinbox->value(); 93 bool project = ui.project_checkbox->isChecked(); 94 95 // wait cursor 96 QApplication::setOverrideCursor(Qt::WaitCursor); 97 QElapsedTimer time; 98 time.start(); 99 100 std::cout << "Perturbation..." << std::endl; 101 102 namespace PMP = CGAL::Polygon_mesh_processing; 103 104 if (poly_item) 105 { 106 SMesh& pmesh = *poly_item->face_graph(); 107 if(ui.deterministic_checkbox->isChecked()) 108 { 109 unsigned int seed = static_cast<unsigned int>(ui.seed_spinbox->value()); 110 PMP::random_perturbation(pmesh, max_move, 111 PMP::parameters::do_project(project) 112 .random_seed(seed)); 113 } 114 else 115 { 116 PMP::random_perturbation(pmesh, max_move, 117 PMP::parameters::do_project(project)); 118 } 119 120 poly_item->invalidateOpenGLBuffers(); 121 poly_item->itemChanged(); 122 } 123 else if (selection_item) 124 { 125 if (selection_item->selected_vertices.empty()) 126 { 127 QMessageBox msg(QMessageBox::Warning, 128 QString("Empty selection"), 129 QString("Selection of vertices is empty.\nPerturbation aborted."), 130 QMessageBox::Ok, 131 this->mw); 132 msg.exec(); 133 QApplication::restoreOverrideCursor(); 134 return; 135 } 136 SMesh& pmesh = *selection_item->polyhedron(); 137 if (ui.deterministic_checkbox->isChecked()) 138 { 139 unsigned int seed = static_cast<unsigned int>(ui.seed_spinbox->value()); 140 PMP::random_perturbation( 141 selection_item->selected_vertices, 142 pmesh, 143 max_move, 144 PMP::parameters::do_project(project) 145 .random_seed(seed)); 146 } 147 else 148 { 149 std::cout << "selection_item->selected_vertices : " 150 << selection_item->selected_vertices.size() << std::endl; 151 PMP::random_perturbation( 152 selection_item->selected_vertices, 153 pmesh, 154 max_move, 155 PMP::parameters::do_project(project)); 156 } 157 158 selection_item->invalidateOpenGLBuffers(); 159 Q_EMIT selection_item->itemChanged(); 160 selection_item->polyhedron_item()->invalidateOpenGLBuffers(); 161 Q_EMIT selection_item->polyhedron_item()->itemChanged(); 162 } 163 else 164 std::cerr << "Can't perturb that type of item" << std::endl; 165 166 std::cout << " ok (" << time.elapsed() << " ms)" << std::endl; 167 168 // default cursor 169 QApplication::restoreOverrideCursor(); 170 } 171 172 Ui::Random_perturbation_dialog perturb_dialog(QDialog * dialog,Scene_surface_mesh_item * poly_item,Scene_polyhedron_selection_item * selection_item)173 perturb_dialog(QDialog* dialog, 174 Scene_surface_mesh_item* poly_item, 175 Scene_polyhedron_selection_item* selection_item) 176 { 177 Ui::Random_perturbation_dialog ui; 178 ui.setupUi(dialog); 179 connect(ui.buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); 180 connect(ui.buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); 181 182 //Set default parameters 183 Scene_interface::Bbox bbox = poly_item != NULL ? poly_item->bbox() 184 : (selection_item != NULL ? selection_item->bbox() 185 : scene->bbox()); 186 ui.objectName->setText(poly_item != NULL ? poly_item->name() 187 : (selection_item != NULL ? selection_item->name() 188 : QString("Remeshing parameters"))); 189 190 ui.objectNameSize->setText( 191 tr("Object bbox size (w,h,d): <b>%1</b>, <b>%2</b>, <b>%3</b>") 192 .arg(bbox.xmax() - bbox.xmin(), 0, 'g', 3) 193 .arg(bbox.ymax() - bbox.ymin(), 0, 'g', 3) 194 .arg(bbox.zmax() - bbox.zmin(), 0, 'g', 3)); 195 196 double diago_length = CGAL::sqrt((bbox.xmax() - bbox.xmin())*(bbox.xmax() - bbox.xmin()) 197 + (bbox.ymax() - bbox.ymin())*(bbox.ymax() - bbox.ymin()) 198 + (bbox.zmax() - bbox.zmin())*(bbox.zmax() - bbox.zmin())); 199 200 //parameters 201 ui.moveSize_dspinbox->setRange(0., diago_length); 202 ui.moveSize_dspinbox->setValue(0.05 * diago_length); 203 204 ui.project_checkbox->setChecked(true); 205 206 //advanced 207 ui.deterministic_checkbox->setChecked(false); 208 ui.seed_spinbox->setEnabled(false); 209 ui.seed_label->setEnabled(false); 210 ui.seed_spinbox->setValue(0); 211 ui.seed_spinbox->setMinimum(0); 212 213 connect(ui.deterministic_checkbox, SIGNAL(toggled(bool)), 214 ui.seed_spinbox, SLOT(setEnabled(bool))); 215 connect(ui.deterministic_checkbox, SIGNAL(toggled(bool)), 216 ui.seed_label, SLOT(setEnabled(bool))); 217 218 return ui; 219 } 220 221 private: 222 Scene_interface *scene; 223 QMainWindow* mw; 224 QAction* actionRandomPerturbation_; 225 226 }; // end Polyhedron_demo_random_perturbation_plugin 227 228 229 #include "Random_perturbation_plugin.moc" 230