1 #include <CGAL/Three/Polyhedron_demo_plugin_interface.h> 2 #include <QApplication> 3 #include <QObject> 4 #include <QAction> 5 #include <QMainWindow> 6 #include <QMessageBox> 7 #include <QInputDialog> 8 #include "Messages_interface.h" 9 #include <CGAL/Three/Three.h> 10 #include "Scene_surface_mesh_item.h" 11 #include "Scene_movable_sm_item.h" 12 #include <CGAL/Three/Scene_item_rendering_helper.h> 13 #include <CGAL/Three/Triangle_container.h> 14 #include <CGAL/Three/Edge_container.h> 15 #include <CGAL/Three/Point_container.h> 16 #include <CGAL/Rigid_triangle_mesh_collision_detection.h> 17 #include "Scene.h" 18 19 class DoTreesIntersectplugin: 20 public QObject, 21 public CGAL::Three::Polyhedron_demo_plugin_interface 22 { 23 Q_OBJECT 24 Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) 25 Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") 26 public: 27 eventFilter(QObject *,QEvent * event)28 bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE 29 { 30 if(event->type() != QEvent::KeyPress) 31 return false; 32 QKeyEvent * e = static_cast<QKeyEvent*>(event); 33 if (e->key()==Qt::Key_W){ 34 do_transparency = !do_transparency; 35 change_display(); 36 return true; 37 } 38 return false; 39 } 40 applicable(QAction *) const41 bool applicable(QAction*) const Q_DECL_OVERRIDE 42 { 43 if(scene->selectionIndices().size() <2) 44 return false; 45 Q_FOREACH(Scene::Item_id i, scene->selectionIndices()) 46 { 47 if(! qobject_cast<Scene_surface_mesh_item*>(scene->item(i))) 48 return false; 49 } 50 return (! group_item); 51 } 52 actions() const53 QList<QAction*> actions() const Q_DECL_OVERRIDE 54 { 55 return _actions; 56 } 57 58 init(QMainWindow * mw,CGAL::Three::Scene_interface * sc,Messages_interface * mi)59 void init(QMainWindow* mw, CGAL::Three::Scene_interface* sc, Messages_interface* mi) Q_DECL_OVERRIDE 60 { 61 this->messageInterface = mi; 62 this->scene = sc; 63 this->mw = mw; 64 QAction *actionCreateTrees= new QAction(QString("Collision Detection"), mw); 65 actionCreateTrees->setProperty("subMenuName", "Polygon Mesh Processing"); 66 actionCreateTrees->setProperty("submenuName", "AABB_tree"); 67 if(actionCreateTrees) { 68 connect(actionCreateTrees, SIGNAL(triggered()), 69 this, SLOT(start())); 70 _actions << actionCreateTrees; 71 } 72 do_transparency = false; 73 group_item = nullptr; 74 } 75 private Q_SLOTS: start()76 void start() 77 { 78 QApplication::setOverrideCursor(Qt::WaitCursor); 79 Q_FOREACH(Scene::Item_id i, scene->selectionIndices()) 80 { 81 Scene_surface_mesh_item* item=qobject_cast<Scene_surface_mesh_item*>(scene->item(i)); 82 if (!CGAL::is_triangle_mesh(*item->face_graph())) 83 { 84 QApplication::restoreOverrideCursor(); 85 QMessageBox::warning(mw, "Error", QString("%1 is not pure triangle. Aborting.").arg(item->name())); 86 return; 87 } 88 } 89 group_item = new Scene_group_item("Test Items"); 90 connect(group_item, &Scene_group_item::aboutToBeDestroyed, 91 this, [this](){ 92 items.clear(); 93 if(col_det) 94 delete col_det; 95 col_det = nullptr; 96 group_item = nullptr;}); 97 98 scene->addItem(group_item); 99 Q_FOREACH(Scene::Item_id i, scene->selectionIndices()) 100 { 101 Scene_surface_mesh_item* item=qobject_cast<Scene_surface_mesh_item*>(scene->item(i)); 102 connect(item, &Scene_surface_mesh_item::aboutToBeDestroyed, 103 this, &DoTreesIntersectplugin::cleanup); 104 105 CGAL::qglviewer::Vec pos(((item->bbox().min)(0) + (item->bbox().max)(0))/2.0, 106 ((item->bbox().min)(1) + (item->bbox().max)(1))/2.0, 107 ((item->bbox().min)(2) + (item->bbox().max)(2))/2.0); 108 109 Scene_movable_sm_item* mov_item = new Scene_movable_sm_item(pos,item->face_graph(),""); 110 connect(mov_item->manipulatedFrame(), &CGAL::qglviewer::ManipulatedFrame::modified, 111 this, &DoTreesIntersectplugin::update_trees); 112 mov_item->setName(item->name()); 113 if(do_transparency) 114 { 115 mov_item->setRenderingMode(Flat); 116 mov_item->setAlpha(120); 117 } 118 else 119 { 120 mov_item->setRenderingMode(Wireframe); 121 } 122 item->setVisible(false); 123 items.push_back(mov_item); 124 scene->addItem(mov_item); 125 scene->changeGroup(mov_item, group_item); 126 group_item->lockChild(mov_item); 127 mov_item->redraw(); 128 } 129 scene->setSelectedItem(group_item->getChildren().last()); 130 connect(static_cast<Scene*>(scene), &Scene::itemIndexSelected, 131 this, &DoTreesIntersectplugin::update_trees); 132 col_det = new CGAL::Rigid_triangle_mesh_collision_detection<SMesh>(); 133 col_det->reserve(items.size()); 134 Q_FOREACH(Scene_movable_sm_item* item, items) 135 { 136 col_det->add_mesh(*item->getFaceGraph()); 137 } 138 init_trees(); 139 static_cast<CGAL::Three::Viewer_interface*>( 140 CGAL::QGLViewer::QGLViewerPool().first())->installEventFilter(this); 141 QApplication::restoreOverrideCursor(); 142 CGAL::Three::Three::information("Press `W` to switch between Wireframe and Transparency mode."); 143 } 144 145 public Q_SLOTS: init_trees()146 void init_trees() 147 { 148 if(items.empty()) 149 return; 150 Q_FOREACH(Scene_movable_sm_item* item, items) 151 item->setColor(QColor(Qt::green)); 152 153 CGAL::Three::Viewer_interface* viewer = static_cast<CGAL::Three::Viewer_interface*>( 154 CGAL::QGLViewer::QGLViewerPool().first()); 155 Scene_movable_sm_item* sel_item = qobject_cast<Scene_movable_sm_item*>(scene->item(scene->mainSelectionIndex())); 156 if(!sel_item) 157 return; 158 159 std::size_t mesh_id = 0; 160 std::size_t sel_id = 0; 161 Q_FOREACH(Scene_movable_sm_item* item, items) 162 { 163 if(item == sel_item) 164 { 165 sel_id = mesh_id; 166 break; 167 } 168 ++mesh_id; 169 } 170 mesh_id = 0; 171 Q_FOREACH(Scene_movable_sm_item* item, items) 172 { 173 if(mesh_id == sel_id) 174 { 175 ++mesh_id; 176 item->setColor(QColor(255,184,61)); 177 prev_ids.push_back(sel_id); 178 continue; 179 } 180 const double* matrix = item->manipulatedFrame()->matrix(); 181 item->setFMatrix(matrix); 182 EPICK::Aff_transformation_3 translation(CGAL::TRANSLATION, -EPICK::Vector_3(item->center().x, 183 item->center().y, 184 item->center().z)); 185 EPICK::Aff_transformation_3 rota( 186 matrix[0], matrix[4], matrix[8],matrix[12], 187 matrix[1], matrix[5], matrix[9],matrix[13], 188 matrix[2], matrix[6], matrix[10],matrix[14]); 189 EPICK::Aff_transformation_3 transfo = 190 rota*translation; 191 192 col_det->set_transformation(mesh_id++, transfo); 193 194 if(do_transparency) 195 { 196 item->setRenderingMode(Flat); 197 item->setAlpha(120); 198 } 199 else 200 { 201 item->setRenderingMode(Wireframe); 202 } 203 item->itemChanged(); 204 } 205 const double* matrix = sel_item->manipulatedFrame()->matrix(); 206 sel_item->setFMatrix(matrix); 207 EPICK::Aff_transformation_3 translation(CGAL::TRANSLATION, -EPICK::Vector_3(sel_item->center().x, 208 sel_item->center().y, 209 sel_item->center().z)); 210 EPICK::Aff_transformation_3 rota( 211 matrix[0], matrix[4], matrix[8],matrix[12], 212 matrix[1], matrix[5], matrix[9],matrix[13], 213 matrix[2], matrix[6], matrix[10],matrix[14]); 214 EPICK::Aff_transformation_3 transfo = 215 rota*translation; 216 col_det->set_transformation(sel_id, transfo); 217 std::vector<std::pair<std::size_t, bool> > inter_and_incl 218 = col_det->get_all_intersections_and_inclusions(sel_id); 219 for(std::size_t i=0; i<inter_and_incl.size(); ++i) 220 { 221 std::size_t id = inter_and_incl[i].first; 222 bool including = inter_and_incl[i].second; 223 if(including) 224 items[id]->setColor(QColor(Qt::blue)); 225 else 226 items[id]->setColor(QColor(Qt::red)); 227 prev_ids.push_back(id); 228 } 229 if(do_transparency) 230 { 231 sel_item->setRenderingMode(Flat); 232 sel_item->setAlpha(120); 233 } 234 else 235 { 236 sel_item->setRenderingMode(Wireframe); 237 } 238 sel_item->itemChanged(); 239 viewer->update(); 240 } 241 update_trees()242 void update_trees() 243 { 244 if(items.empty()) 245 return; 246 CGAL::Three::Viewer_interface* viewer = static_cast<CGAL::Three::Viewer_interface*>( 247 CGAL::QGLViewer::QGLViewerPool().first()); 248 Scene_movable_sm_item* sel_item = qobject_cast<Scene_movable_sm_item*>(scene->item(scene->mainSelectionIndex())); 249 if(!sel_item) 250 return; 251 252 std::size_t mesh_id = 0; 253 std::size_t sel_id = 0; 254 Q_FOREACH(Scene_movable_sm_item* item, items) 255 { 256 if(item == sel_item) 257 { 258 sel_id = mesh_id; 259 ++mesh_id; 260 item->setColor(QColor(255,184,61)); 261 break; 262 } 263 ++mesh_id; 264 } 265 for(std::size_t i = 0; i< prev_ids.size(); ++i) 266 { 267 std::size_t id = prev_ids[i]; 268 if(id == sel_id) 269 { 270 continue; 271 } 272 Scene_movable_sm_item* item = items[id]; 273 item->setColor(QColor(Qt::green)); 274 item->itemChanged(); 275 } 276 prev_ids.clear(); 277 const double* matrix = sel_item->manipulatedFrame()->matrix(); 278 sel_item->setFMatrix(matrix); 279 280 EPICK::Aff_transformation_3 translation(CGAL::TRANSLATION, -EPICK::Vector_3(sel_item->center().x, 281 sel_item->center().y, 282 sel_item->center().z)); 283 EPICK::Aff_transformation_3 rota( 284 matrix[0], matrix[4], matrix[8],matrix[12], 285 matrix[1], matrix[5], matrix[9],matrix[13], 286 matrix[2], matrix[6], matrix[10],matrix[14]); 287 EPICK::Aff_transformation_3 transfo = 288 rota*translation; 289 col_det->set_transformation(sel_id, transfo); 290 std::vector<std::pair<std::size_t, bool> > inter_and_incl 291 = col_det->get_all_intersections_and_inclusions(sel_id); 292 for(std::size_t i=0; i<inter_and_incl.size(); ++i) 293 { 294 std::size_t id = inter_and_incl[i].first; 295 bool including = inter_and_incl[i].second; 296 if(including) 297 items[id]->setColor(QColor(Qt::blue)); 298 else 299 items[id]->setColor(QColor(Qt::red)); 300 prev_ids.push_back(id); 301 } 302 prev_ids.push_back(sel_id); 303 sel_item->itemChanged(); 304 viewer->update(); 305 } 306 cleanup()307 void cleanup() 308 { 309 if(!group_item) 310 return; 311 scene->erase(scene->item_id(group_item)); 312 group_item = nullptr; 313 items.clear(); 314 prev_ids.clear(); 315 delete col_det; 316 col_det = nullptr; 317 } 318 319 //switch transparent/wireframe. change_display()320 void change_display() 321 { 322 for(Scene_movable_sm_item* item : items) 323 { 324 if(do_transparency) 325 { 326 item->setRenderingMode(Flat); 327 item->setAlpha(120); 328 } 329 else 330 { 331 item->setRenderingMode(Wireframe); 332 } 333 } 334 } 335 336 private: 337 QList<QAction*> _actions; 338 Messages_interface* messageInterface; 339 CGAL::Three::Scene_interface* scene; 340 QMainWindow* mw; 341 CGAL::Rigid_triangle_mesh_collision_detection<SMesh> *col_det; 342 std::vector<Scene_movable_sm_item*> items; 343 std::vector<std::size_t> prev_ids; 344 Scene_group_item* group_item; 345 bool do_transparency; 346 }; 347 #include "Do_trees_intersect_plugin.moc" 348