From e88b07fd02290e030931c8a928f373d9674e63f0 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 13 Aug 2010 14:49:39 +0000 Subject: [PATCH] Added a Qt4 based 2D Alpha Shape demo --- .gitattributes | 3 + .../demo/Alpha_shapes_2/Alpha_shapes_2.cpp | 311 ++++++++++++++++++ .../demo/Alpha_shapes_2/Alpha_shapes_2.qrc | 6 + .../demo/Alpha_shapes_2/Alpha_shapes_2.ui | 216 ++++++++++++ .../Alpha_shapes_2/about_Alpha_shapes_2.html | 10 + 5 files changed, 546 insertions(+) create mode 100644 GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.cpp create mode 100644 GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.qrc create mode 100644 GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.ui create mode 100755 GraphicsView/demo/Alpha_shapes_2/about_Alpha_shapes_2.html diff --git a/.gitattributes b/.gitattributes index 735173f08dc..e73b16a8423 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1413,6 +1413,9 @@ Geomview/demo/Geomview/CMakeLists.txt -text Geomview/doc_tex/Geomview/geomview.gif -text GraphicsView/GraphicsView.odp -text GraphicsView/TODO -text +GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.qrc -text +GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.ui -text +GraphicsView/demo/Alpha_shapes_2/about_Alpha_shapes_2.html svneol=native#text/html GraphicsView/demo/Bounding_volumes/Bounding_volumes.qrc -text GraphicsView/demo/Bounding_volumes/Bounding_volumes.ui -text GraphicsView/demo/Bounding_volumes/about_Bounding_volumes.html svneol=native#text/html diff --git a/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.cpp b/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.cpp new file mode 100644 index 00000000000..f61f353e3bc --- /dev/null +++ b/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.cpp @@ -0,0 +1,311 @@ +#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_shape_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; + 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); + + 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" + +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 libCGALQt4. + // See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE + Q_INIT_RESOURCE(File); + Q_INIT_RESOURCE(Triangulation_2); + Q_INIT_RESOURCE(Input); + Q_INIT_RESOURCE(CGAL); + + MainWindow mainWindow; + mainWindow.show(); + return app.exec(); +} diff --git a/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.qrc b/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.qrc new file mode 100644 index 00000000000..6c412d3ab8c --- /dev/null +++ b/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.qrc @@ -0,0 +1,6 @@ + + + ../resources/about_CGAL.html + about_Alpha_shapes_2.html + + diff --git a/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.ui b/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.ui new file mode 100644 index 00000000000..63457a4cabd --- /dev/null +++ b/GraphicsView/demo/Alpha_shapes_2/Alpha_shapes_2.ui @@ -0,0 +1,216 @@ + + + GeometryFactory + Alpha_shapes_2 + + + + 0 + 0 + 800 + 600 + + + + CGAL Alpha Shape + + + + :/cgal/logos/cgal_icon:/cgal/logos/cgal_icon + + + + + + + + + &Alpha: + + + alphaBox + + + + + + + % + + + 100 + + + + + + + 100 + + + Qt::Horizontal + + + + + + + + + Qt::StrongFocus + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOn + + + QGraphicsView::NoAnchor + + + + + + + + + File Tools + + + TopToolBarArea + + + false + + + + + + + Visualization Tools + + + TopToolBarArea + + + false + + + + + + + + + 0 + 0 + 800 + 26 + + + + + &File + + + + + + + + + + &Edit + + + + + + &Tools + + + + + + + + + + + &About + + + + + About &CGAL + + + + + &Quit + + + Ctrl+Q + + + + + + :/cgal/fileToolbar/fileNew.png:/cgal/fileToolbar/fileNew.png + + + &Clear + + + Ctrl+C + + + + + + :/cgal/fileToolbar/fileOpen.png:/cgal/fileToolbar/fileOpen.png + + + &Load Points... + + + Ctrl+L + + + + + + :/cgal/Input/zoom-best-fit:/cgal/Input/zoom-best-fit + + + Re&center the viewport + + + Ctrl+R + + + + + Insert Random Points + + + + + + :/cgal/Input/inputPoint.png:/cgal/Input/inputPoint.png + + + Insert Point + + + + + + + + + + + + diff --git a/GraphicsView/demo/Alpha_shapes_2/about_Alpha_shapes_2.html b/GraphicsView/demo/Alpha_shapes_2/about_Alpha_shapes_2.html new file mode 100755 index 00000000000..f9d21ee7663 --- /dev/null +++ b/GraphicsView/demo/Alpha_shapes_2/about_Alpha_shapes_2.html @@ -0,0 +1,10 @@ + + +

Alpha Shapes

+

Copyright © 2010 GeometryFactory

+

This application illustrates the 2D Alpha Shapes + of CGAL.

+

See also the online + manual.

+ +