From 8af1edec81f2a6dab7087c23f213968fe761ef58 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 10 Aug 2016 15:33:49 +0200 Subject: [PATCH 1/3] Implement a snapshot to clipboard. Bind it to Ctrl+Print Screen. --- Polyhedron/demo/Polyhedron/MainWindow.ui | 3 - Polyhedron/demo/Polyhedron/Viewer.cpp | 138 ++++++++++++++--------- Polyhedron/demo/Polyhedron/Viewer.h | 1 + 3 files changed, 83 insertions(+), 59 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.ui b/Polyhedron/demo/Polyhedron/MainWindow.ui index 0b35485062d..ddbb3bd9010 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.ui +++ b/Polyhedron/demo/Polyhedron/MainWindow.ui @@ -578,9 +578,6 @@ Re&center Scene - - Ctrl+C - diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index 67e2fb3b668..4171b2cbd75 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -30,6 +30,8 @@ public: mutable std::vector shader_programs; QMatrix4x4 projectionMatrix; void setFrustum(double l, double r, double t, double b, double n, double f); + QImage* takeSnapshot(Viewer* viewer, int quality, int background_color, QSize size, double oversampling, bool expand); + void sendSnapshotToClibboard(Viewer*); }; Viewer::Viewer(QWidget* parent, bool antialiasing) : CGAL::Three::Viewer_interface(parent) @@ -402,7 +404,19 @@ void Viewer::keyPressEvent(QKeyEvent* e) else if(e->key() == Qt::Key_I && e->modifiers() & Qt::ControlModifier){ d->scene->printPrimitiveIds(this); update(); + return; } + + else if(e->key() == Qt::Key_C && e->modifiers() & Qt::ControlModifier){ + d->sendSnapshotToClibboard(this); + return; + } + + else if(e->key() == Qt::Key_S && e->modifiers() & Qt::ControlModifier){ + saveSnapshot(true); + return; + } + //forward the event to the scene (item handling of the event) if (! d->scene->keyPressEvent(e) ) QGLViewer::keyPressEvent(e); @@ -1522,7 +1536,6 @@ private Q_SLOTS: void Viewer::saveSnapshot(bool, bool) { - GLfloat alpha = 1.0; qreal aspectRatio = width() / static_cast(height()); static ImageInterface* imageInterface = NULL; @@ -1531,83 +1544,86 @@ void Viewer::saveSnapshot(bool, bool) imageInterface->imgWidth->setValue(width()); imageInterface->imgHeight->setValue(height()); - imageInterface->imgQuality->setValue(snapshotQuality()); if (imageInterface->exec() == QDialog::Rejected) return; - - setSnapshotQuality(imageInterface->imgQuality->value()); - - QColor previousBGColor = backgroundColor(); - switch(imageInterface->color_comboBox->currentIndex()) - { - case 0: - break; - case 1: - this->setBackgroundColor(QColor(Qt::transparent)); - alpha = 0.0; - break; - case 2: - QColor c = QColorDialog::getColor(); - if(c.isValid()) { - setBackgroundColor(c); - this->setBackgroundColor(c); - } - else return; - break; - - } QSize finalSize(imageInterface->imgWidth->value(), imageInterface->imgHeight->value()); - - qreal oversampling = imageInterface->oversampling->value(); - QSize subSize(int(this->width()/oversampling), int(this->height()/oversampling)); - - + bool expand = imageInterface->expandFrustum->isChecked(); QString fileName = QFileDialog::getSaveFileName(this, tr("Save Snapshot"), "", tr("Image Files (*.png *.jpg *.bmp)")); if(fileName.isEmpty()) { - setBackgroundColor(previousBGColor); return; } + QImage* image= d->takeSnapshot(this, imageInterface->imgQuality->value(), imageInterface->color_comboBox->currentIndex(), + finalSize, imageInterface->oversampling->value(), expand); + if(image) + { + image->save(fileName); + delete image; + } - QSize size=QSize(width(), height()); +} +//copy a snapshot with transparent background with arbitrary quality values. +QImage* Viewer_impl::takeSnapshot(Viewer *viewer, int quality, int background_color, QSize finalSize, double oversampling, bool expand) +{ + qreal aspectRatio = viewer->width() / static_cast(viewer->height()); + viewer->setSnapshotQuality(quality); + GLfloat alpha = 1.0f; + QColor previousBGColor = viewer->backgroundColor(); + switch(background_color) + { + case 0: + break; + case 1: + viewer->setBackgroundColor(QColor(Qt::transparent)); + alpha = 0.0f; + break; + case 2: + QColor c = QColorDialog::getColor(); + if(c.isValid()) { + viewer->setBackgroundColor(c); + } + else + return NULL; + break; + } + + + QSize subSize(int(viewer->width()/oversampling), int(viewer->height()/oversampling)); + QSize size=QSize(viewer->width(), viewer->height()); qreal newAspectRatio = finalSize.width() / static_cast(finalSize.height()); - qreal zNear = camera()->zNear(); - qreal zFar = camera()->zFar(); + qreal zNear = viewer->camera()->zNear(); + qreal zFar = viewer->camera()->zFar(); qreal xMin, yMin; - bool expand = imageInterface->expandFrustum->isChecked(); if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatiofieldOfView() / 2.0); + yMin = zNear * tan(viewer->camera()->fieldOfView() / 2.0); xMin = newAspectRatio * yMin; } else { - xMin = zNear * tan(camera()->fieldOfView() / 2.0) * aspectRatio; + xMin = zNear * tan(viewer->camera()->fieldOfView() / 2.0) * aspectRatio; yMin = xMin / newAspectRatio; } - QImage image(finalSize.width(), finalSize.height(), QImage::Format_ARGB32); + QImage *image = new QImage(finalSize.width(), finalSize.height(), QImage::Format_ARGB32); - if (image.isNull()) + if (image->isNull()) { - QMessageBox::warning(this, "Image saving error", + QMessageBox::warning(viewer, "Image saving error", "Unable to create resulting image", QMessageBox::Ok, QMessageBox::NoButton); - setBackgroundColor(previousBGColor); - return; + viewer->setBackgroundColor(previousBGColor); + return NULL; } - // ProgressDialog disabled since it interfers with the screen grabing mecanism on some platforms. Too bad. - // ProgressDialog::showProgressDialog(this); - image.fill(qRgba(0,0,0,0)); qreal scaleX = subSize.width() / static_cast(finalSize.width()); qreal scaleY = subSize.height() / static_cast(finalSize.height()); @@ -1622,18 +1638,19 @@ void Viewer::saveSnapshot(bool, bool) nbX++; if (nbY * subSize.height() < finalSize.height()) nbY++; + QOpenGLFramebufferObject* fbo = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::CombinedDepthStencil); - makeCurrent(); + viewer->makeCurrent(); int count=0; for (int i=0; isetFrustum(-xMin + i*deltaX, -xMin + (i+1)*deltaX, yMin - j*deltaY, yMin - (j+1)*deltaY, zNear, zFar); + setFrustum(-xMin + i*deltaX, -xMin + (i+1)*deltaX, yMin - j*deltaY, yMin - (j+1)*deltaY, zNear, zFar); fbo->bind(); - glClearColor(backgroundColor().redF(), backgroundColor().greenF(), backgroundColor().blueF(), alpha); - preDraw(); - draw(); - postDraw(); + viewer->glClearColor(viewer->backgroundColor().redF(), viewer->backgroundColor().greenF(), viewer->backgroundColor().blueF(), alpha); + viewer->preDraw(); + viewer->draw(); + viewer->postDraw(); fbo->release(); QImage snapshot = fbo->toImage(); @@ -1642,21 +1659,30 @@ void Viewer::saveSnapshot(bool, bool) for (int ii=0; iiwidth()) break; for (int jj=0; jjheight()) break; - image.setPixel(fi, fj, subImage.pixel(ii,jj)); + image->setPixel(fi, fj, subImage.pixel(ii,jj)); } } count++; } - - image.save(fileName); - setBackgroundColor(previousBGColor); + if(background_color !=0) + viewer->setBackgroundColor(previousBGColor); + return image; +} +void Viewer_impl::sendSnapshotToClibboard(Viewer *viewer) +{ + QImage * snap = takeSnapshot(viewer, 95, 1, 2*viewer->size(), 1, true); + if(snap) + { + QApplication::clipboard()->setImage(*snap); + delete snap; + } } #include "Viewer.moc" diff --git a/Polyhedron/demo/Polyhedron/Viewer.h b/Polyhedron/demo/Polyhedron/Viewer.h index 1491db2242e..eb6a9a4e979 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.h +++ b/Polyhedron/demo/Polyhedron/Viewer.h @@ -161,6 +161,7 @@ protected: bool is_d_pressed; protected: + friend class Viewer_impl; Viewer_impl* d; double prev_radius; From d9e7a4c46adfde1fb439d58acd8a2ca724ee7c10 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 11 Aug 2016 15:20:28 +0200 Subject: [PATCH 2/3] Fix the shortcuts for saveSnapshot() and sendSnapshotToClipBoard. --- Polyhedron/demo/Polyhedron/Viewer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index 4171b2cbd75..d0a2d649256 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -405,7 +405,7 @@ void Viewer::keyPressEvent(QKeyEvent* e) d->scene->printPrimitiveIds(this); update(); return; - } + } else if(e->key() == Qt::Key_C && e->modifiers() & Qt::ControlModifier){ d->sendSnapshotToClibboard(this); @@ -413,7 +413,7 @@ void Viewer::keyPressEvent(QKeyEvent* e) } else if(e->key() == Qt::Key_S && e->modifiers() & Qt::ControlModifier){ - saveSnapshot(true); + this->saveSnapshot(true,true); return; } From 141517fbc864f9eb3e98e13264ba2835222ffec9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 12 Aug 2016 09:23:58 +0200 Subject: [PATCH 3/3] Set the 'Recenter Scene' shortcut to Ctrl+R. --- Polyhedron/demo/Polyhedron/MainWindow.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.ui b/Polyhedron/demo/Polyhedron/MainWindow.ui index ddbb3bd9010..b49869d2820 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.ui +++ b/Polyhedron/demo/Polyhedron/MainWindow.ui @@ -578,6 +578,9 @@ Re&center Scene + + Ctrl+R +