#include // CGAL headers #include #include #include #include // Qt headers #include #include #include #include #include // GraphicsView items and event filters (input classes) #include #include // for viewportsBbox #include // the two base classes #include "ui_Alpha_shapes_2.h" #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_2 Point_2; typedef K::Iso_rectangle_2 Iso_rectangle_2; typedef CGAL::Alpha_shape_vertex_base_2 Vb; typedef CGAL::Alpha_shape_face_base_2 Fb; typedef CGAL::Triangulation_data_structure_2 Tds; typedef CGAL::Delaunay_triangulation_2 Delaunay; typedef CGAL::Alpha_shape_2 Alpha_shape_2; typedef Alpha_shape_2::Alpha_iterator Alpha_iterator; class MainWindow : public CGAL::Qt::DemosMainWindow, public Ui::Alpha_shapes_2 { Q_OBJECT private: double alpha; std::vector points; Alpha_shape_2 as; QGraphicsScene scene; CGAL::Qt::AlphaShapeGraphicsItem * agi; CGAL::Qt::GraphicsViewPolylineInput * pi; public: MainWindow(); public slots: void processInput(CGAL::Object o); void alphaChanged(int i); void on_actionInsertRandomPoints_triggered(); void on_actionLoadPoints_triggered(); void on_actionClear_triggered(); void on_actionRecenter_triggered(); void open(QString fileName); signals: void changed(); }; MainWindow::MainWindow() : DemosMainWindow() { setupUi(this); this->graphicsView->setAcceptDrops(false); // Add a GraphicItem for the alpha shape agi = new CGAL::Qt::AlphaShapeGraphicsItem(&as); QObject::connect(this, SIGNAL(changed()), agi, SLOT(modelChanged())); agi->setVerticesPen(QPen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); agi->setEdgesPen(QPen(Qt::lightGray, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); agi->setRegularEdgesPen(QPen(Qt::blue, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); agi->setSingularEdgesPen(QPen(Qt::cyan, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); agi->setRegularFacesBrush(QBrush(Qt::cyan)); scene.addItem(agi); // // Manual handling of actions // QObject::connect(this->alphaSlider, SIGNAL(valueChanged(int)), this, SLOT(alphaChanged(int))); QObject::connect(this->alphaBox, SIGNAL(valueChanged(int)), this, SLOT(alphaChanged(int))); QObject::connect(this->alphaSlider, SIGNAL(valueChanged(int)), this->alphaBox, SLOT(setValue(int))); QObject::connect(this->alphaBox, SIGNAL(valueChanged(int)), this->alphaSlider, SLOT(setValue(int))); QObject::connect(this->actionQuit, SIGNAL(triggered()), this, SLOT(close())); pi = new CGAL::Qt::GraphicsViewPolylineInput(this, &scene, 1, false); // inputs a list with one point QObject::connect(pi, SIGNAL(generate(CGAL::Object)), this, SLOT(processInput(CGAL::Object))); scene.installEventFilter(pi); //this->actionShowAlphaShape->setChecked(true); // // Setup the scene and the view // scene.setItemIndexMethod(QGraphicsScene::NoIndex); scene.setSceneRect(-100, -100, 100, 100); this->graphicsView->setScene(&scene); this->graphicsView->setMouseTracking(true); // Turn the vertical axis upside down this->graphicsView->matrix().scale(1, -1); // The navigation adds zooming and translation functionality to the // QGraphicsView this->addNavigation(this->graphicsView); this->setupStatusBar(); this->setupOptionsMenu(); this->addAboutDemo(":/cgal/help/about_Alpha_shapes_2.html"); this->addAboutCGAL(); this->addRecentFiles(this->menuFile, this->actionQuit); connect(this, SIGNAL(openRecentFile(QString)), this, SLOT(open(QString))); } void MainWindow::processInput(CGAL::Object o) { std::list input; if(CGAL::assign(input, o)){ if(input.size() == 1) { points.push_back(input.front()); as.make_alpha_shape(points.begin(), points.end()); as.set_alpha(alpha); } emit(changed()); } } void MainWindow::alphaChanged(int i) { if (as.number_of_alphas() > 0){ if(i < 100){ int n = static_cast((i * as.number_of_alphas())/ 100); if(n == 0) n++; alpha = as.get_nth_alpha(n); as.set_alpha(alpha); } else { Alpha_iterator alpha_end_it = as.alpha_end(); alpha = (*(--alpha_end_it))+1; as.set_alpha(alpha); } } else { alpha = 0; as.set_alpha(0); } emit (changed()); } /* * Qt Automatic Connections * http://doc.trolltech.com/4.4/designer-using-a-component.html#automatic-connections * * setupUi(this) generates connections to the slots named * "on__" */ void MainWindow::on_actionClear_triggered() { as.clear(); points.clear(); emit(changed()); } void MainWindow::on_actionInsertRandomPoints_triggered() { QRectF rect = CGAL::Qt::viewportsBbox(&scene); CGAL::Qt::Converter convert; Iso_rectangle_2 isor = convert(rect); CGAL::Random_points_in_iso_rectangle_2 pg((isor.min)(), (isor.max)()); bool ok = false; #if QT_VERSION >= 0x050000 const int number_of_points = QInputDialog::getInt(this, tr("Number of random points"), tr("Enter number of random points"), 100, 0, (std::numeric_limits::max)(), 1, &ok); #else const int number_of_points = QInputDialog::getInteger(this, tr("Number of random points"), tr("Enter number of random points"), 100, 0, (std::numeric_limits::max)(), 1, &ok); #endif if(!ok) { return; } // wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); points.reserve(points.size() + number_of_points); for(int i = 0; i < number_of_points; ++i){ points.push_back(*pg++); } as.make_alpha_shape(points.begin(), points.end()); as.set_alpha(alpha); // default cursor QApplication::restoreOverrideCursor(); emit(changed()); } void MainWindow::on_actionLoadPoints_triggered() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open Points file"), "."); if(! fileName.isEmpty()){ open(fileName); } } void MainWindow::open(QString fileName) { std::cerr << "open " << std::endl; std::cerr << qPrintable(fileName) << std::endl; // wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); std::ifstream ifs(qPrintable(fileName)); K::Point_2 p; while(ifs >> p) { points.push_back(p); } as.make_alpha_shape(points.begin(), points.end()); as.set_alpha(alpha); // default cursor QApplication::restoreOverrideCursor(); this->addToRecentFiles(fileName); actionRecenter->trigger(); emit(changed()); } void MainWindow::on_actionRecenter_triggered() { this->graphicsView->setSceneRect(agi->boundingRect()); this->graphicsView->fitInView(agi->boundingRect(), Qt::KeepAspectRatio); } #include "Alpha_shapes_2.moc" #include int main(int argc, char **argv) { QApplication app(argc, argv); app.setOrganizationDomain("geometryfactory.com"); app.setOrganizationName("GeometryFactory"); app.setApplicationName("Alpha_shape_2 demo"); // Import resources from libCGAL (Qt4 or Qt5). // See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE CGAL_QT_INIT_RESOURCES;//New for Qt5 version ! MainWindow mainWindow; mainWindow.show(); return app.exec(); }