mirror of https://github.com/CGAL/cgal
425 lines
10 KiB
C++
425 lines
10 KiB
C++
#include "MainWindow.h"
|
|
#include "Scene.h"
|
|
#include <CGAL/Qt/debug.h>
|
|
|
|
#include <QDragEnterEvent>
|
|
#include <QDropEvent>
|
|
#include <QTextStream>
|
|
#include <QUrl>
|
|
#include <QFileDialog>
|
|
#include <QSettings>
|
|
#include <QHeaderView>
|
|
#include <QClipboard>
|
|
#include <QInputDialog>
|
|
|
|
#include "ui_MainWindow.h"
|
|
|
|
MainWindow::MainWindow(QWidget* parent)
|
|
: CGAL::Qt::DemosMainWindow(parent)
|
|
{
|
|
ui = new Ui::MainWindow;
|
|
ui->setupUi(this);
|
|
|
|
this->addAboutDemo(":/cgal/AABB_demo/about.html");
|
|
this->addAboutCGAL();
|
|
|
|
// saves some pointers from ui, for latter use.
|
|
m_pViewer = ui->viewer;
|
|
|
|
|
|
// accepts drop events
|
|
setAcceptDrops(true);
|
|
// setups scene
|
|
m_pScene = new Scene();
|
|
m_pViewer->setScene(m_pScene);
|
|
m_pViewer->setManipulatedFrame(m_pScene->manipulatedFrame());
|
|
|
|
// connects actionQuit (Ctrl+Q) and qApp->quit()
|
|
connect(ui->actionQuit, SIGNAL(triggered()),
|
|
this, SLOT(quit()));
|
|
|
|
this->addRecentFiles(ui->menuFile, ui->actionQuit);
|
|
connect(this, SIGNAL(openRecentFile(QString)),
|
|
this, SLOT(open(QString)));
|
|
|
|
readSettings();
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
m_pViewer->makeCurrent();
|
|
delete ui;
|
|
}
|
|
|
|
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
|
|
{
|
|
if (event->mimeData()->hasFormat("text/uri-list"))
|
|
event->acceptProposedAction();
|
|
}
|
|
|
|
void MainWindow::dropEvent(QDropEvent *event)
|
|
{
|
|
Q_FOREACH(QUrl url, event->mimeData()->urls()) {
|
|
QString filename = url.toLocalFile();
|
|
if(!filename.isEmpty()) {
|
|
QTextStream(stderr) << QString("dropEvent(\"%1\")\n").arg(filename);
|
|
open(filename);
|
|
}
|
|
}
|
|
event->acceptProposedAction();
|
|
}
|
|
|
|
void MainWindow::updateViewerBBox()
|
|
{
|
|
m_pScene->update_bbox();
|
|
const Scene::Bbox bbox = m_pScene->bbox();
|
|
const double xmin = bbox.xmin();
|
|
const double ymin = bbox.ymin();
|
|
const double zmin = bbox.zmin();
|
|
const double xmax = bbox.xmax();
|
|
const double ymax = bbox.ymax();
|
|
const double zmax = bbox.zmax();
|
|
CGAL::qglviewer::Vec
|
|
vec_min(xmin, ymin, zmin),
|
|
vec_max(xmax, ymax, zmax);
|
|
m_pViewer->setSceneBoundingBox(vec_min,vec_max);
|
|
m_pViewer->camera()->showEntireScene();
|
|
}
|
|
|
|
void MainWindow::open(QString filename)
|
|
{
|
|
QFileInfo fileinfo(filename);
|
|
if(fileinfo.isFile() && fileinfo.isReadable())
|
|
{
|
|
int index = m_pScene->open(filename);
|
|
if(index >= 0)
|
|
{
|
|
QSettings settings;
|
|
settings.setValue("OFF open directory",
|
|
fileinfo.absoluteDir().absolutePath());
|
|
this->addToRecentFiles(filename);
|
|
|
|
// update bbox
|
|
updateViewerBBox();
|
|
m_pViewer->update();
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::readSettings()
|
|
{
|
|
this->readState("MainWindow", Size|State);
|
|
}
|
|
|
|
void MainWindow::writeSettings()
|
|
{
|
|
this->writeState("MainWindow");
|
|
std::cerr << "Write setting... done.\n";
|
|
}
|
|
|
|
void MainWindow::quit()
|
|
{
|
|
writeSettings();
|
|
close();
|
|
}
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
{
|
|
writeSettings();
|
|
event->accept();
|
|
}
|
|
|
|
void MainWindow::on_actionLoadPolyhedron_triggered()
|
|
{
|
|
QSettings settings;
|
|
QString directory = settings.value("OFF open directory",
|
|
QDir::current().dirName()).toString();
|
|
QStringList filenames =
|
|
QFileDialog::getOpenFileNames(this,
|
|
tr("Load polyhedron..."),
|
|
directory,
|
|
tr("OFF files (*.off)\n"
|
|
"All files (*)"));
|
|
if(!filenames.isEmpty()) {
|
|
Q_FOREACH(QString filename, filenames) {
|
|
open(filename);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
|
|
{
|
|
m_pViewer->setAddKeyFrameKeyboardModifiers(m);
|
|
}
|
|
|
|
void MainWindow::on_actionInside_points_triggered()
|
|
{
|
|
bool ok;
|
|
|
|
const unsigned int nb_points = static_cast<unsigned>(QInputDialog::getInt(nullptr, "#Points",
|
|
"#Points:",10000,1,100000000,9,&ok));
|
|
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->generate_inside_points(nb_points);
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionPoints_in_interval_triggered()
|
|
{
|
|
bool ok;
|
|
|
|
const unsigned int nb_points = static_cast<unsigned>(QInputDialog::getInt(nullptr, "#Points",
|
|
"#Points:",10000,1,100000000,9,&ok));
|
|
|
|
if(!ok)
|
|
return;
|
|
|
|
const double min =
|
|
QInputDialog::getDouble(nullptr, "min",
|
|
"Min:",-0.1,-1000.0,1000.0,9,&ok);
|
|
if(!ok)
|
|
return;
|
|
const double max =
|
|
QInputDialog::getDouble(nullptr, "max",
|
|
"Max:",0.1,-1000.0,1000.0,9,&ok);
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->generate_points_in(nb_points,min,max);
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionBoundary_segments_triggered()
|
|
{
|
|
bool ok;
|
|
|
|
const unsigned int nb_slices = static_cast<unsigned>(QInputDialog::getInt(nullptr, "#Slices",
|
|
"Slices:",100,1,1000000,8,&ok));
|
|
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->generate_boundary_segments(nb_slices);
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionBoundary_points_triggered()
|
|
{
|
|
bool ok;
|
|
|
|
const unsigned int nb_points = static_cast<unsigned>(QInputDialog::getInt(nullptr, "#Points",
|
|
"Points:",1000,1,10000000,8,&ok));
|
|
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->generate_boundary_points(nb_points);
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionEdge_points_triggered()
|
|
{
|
|
bool ok;
|
|
|
|
const unsigned int nb_points = static_cast<unsigned>(QInputDialog::getInt(nullptr, "#Points",
|
|
"Points:",1000,1,10000000,8,&ok));
|
|
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->generate_edge_points(nb_points);
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionBench_distances_triggered()
|
|
{
|
|
bool ok;
|
|
const double duration = QInputDialog::getDouble(nullptr, "Duration",
|
|
"Duration (s):",1.0,0.01,1000,8,&ok);
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
std::cout << std::endl << "Benchmark distances" << std::endl;
|
|
m_pScene->benchmark_distances(duration);
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void MainWindow::on_actionBench_intersections_triggered()
|
|
{
|
|
bool ok;
|
|
const double duration = QInputDialog::getDouble(nullptr, "Duration",
|
|
"Duration (s):",1.0,0.01,1000.0,8,&ok);
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
std::cout << std::endl << "Benchmark intersections" << std::endl;
|
|
m_pScene->benchmark_intersections(duration);
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void MainWindow::on_actionUnsigned_distance_function_to_facets_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->activate_cutting_plane();
|
|
m_pScene->unsigned_distance_function();
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionUnsigned_distance_function_to_edges_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->activate_cutting_plane();
|
|
m_pScene->unsigned_distance_function_to_edges();
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionSigned_distance_function_to_facets_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->activate_cutting_plane();
|
|
m_pScene->signed_distance_function();
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionIntersection_cutting_plane_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->activate_cutting_plane();
|
|
m_pScene->cut_segment_plane();
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionCutting_plane_none_triggered()
|
|
{
|
|
m_pScene->clear_cutting_plane();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionView_polyhedron_triggered()
|
|
{
|
|
m_pScene->toggle_view_poyhedron();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionView_points_triggered()
|
|
{
|
|
m_pScene->toggle_view_points();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionView_segments_triggered()
|
|
{
|
|
m_pScene->toggle_view_segments();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionView_cutting_plane_triggered()
|
|
{
|
|
m_pScene->toggle_view_plane();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionClear_points_triggered()
|
|
{
|
|
m_pScene->clear_points();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionClear_segments_triggered()
|
|
{
|
|
m_pScene->clear_segments();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionClear_cutting_plane_triggered()
|
|
{
|
|
m_pScene->clear_cutting_plane();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionRefine_bisection_triggered()
|
|
{
|
|
bool ok;
|
|
const double max_len =
|
|
QInputDialog::getDouble(nullptr, "Max edge len",
|
|
"Max edge len:",0.1,0.001,100.0,9,&ok);
|
|
if(!ok)
|
|
return;
|
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->refine_bisection(max_len * max_len);
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionBench_memory_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->bench_memory();
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void MainWindow::on_actionBench_construction_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->bench_construction();
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void MainWindow::on_actionBench_intersections_vs_nbt_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->bench_intersections_vs_nbt();
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void MainWindow::on_actionBench_distances_vs_nbt_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->bench_distances_vs_nbt();
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void MainWindow::on_actionRefine_loop_triggered()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
m_pScene->refine_loop();
|
|
QApplication::restoreOverrideCursor();
|
|
m_pViewer->update();
|
|
}
|
|
|
|
void MainWindow::on_actionSave_snapshot_triggered()
|
|
{
|
|
return;
|
|
}
|
|
void MainWindow::on_actionCopy_snapshot_triggered()
|
|
{
|
|
// copy snapshot to clipboard
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
QClipboard *qb = QApplication::clipboard();
|
|
m_pViewer->makeCurrent();
|
|
m_pViewer->raise();
|
|
QImage snapshot = m_pViewer->grabFramebuffer();
|
|
qb->setImage(snapshot);
|
|
QApplication::restoreOverrideCursor();
|
|
}
|