WIP: integrate is_sharing in qglviewer

This commit is contained in:
Maxime Gimeno 2018-08-30 15:47:16 +02:00
parent e507fb2e28
commit daac3e124d
17 changed files with 728 additions and 110 deletions

View File

@ -1205,6 +1205,7 @@ protected:
qglviewer::Vec _offset;
//C o n t e x t
bool is_ogl_4_3;
bool is_sharing;
public:
//! Is used to know if the openGL context is 4.3 or ES 2.0.
//! @returns `true` if the context is 4.3.

View File

@ -129,6 +129,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND )
find_package(Boost COMPONENTS thread system filesystem)
qt5_wrap_ui( MainWindowUI_files MainWindow.ui)
qt5_wrap_ui( SubViewerUI_files SubViewer.ui)
qt5_wrap_ui( statisticsUI_FILES Statistics_on_item_dialog.ui)
qt5_wrap_ui( FileLoaderDialogUI_files FileLoaderDialog.ui )
qt5_wrap_ui( Show_point_dialogUI_FILES Show_point_dialog.ui )
@ -309,7 +310,8 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND )
Polyhedron_demo.cpp
File_loader_dialog_moc.cpp
${CGAL_Qt5_RESOURCE_FILES} ${CGAL_Qt5_MOC_FILES}
${FileLoaderDialogUI_files} ${MainWindowUI_files} ${PreferencesUI_FILES} ${statisticsUI_FILES})
${FileLoaderDialogUI_files} ${MainWindowUI_files} ${PreferencesUI_FILES}
${statisticsUI_FILES} ${SubViewerUI_files})
target_link_libraries(polyhedron_demo PUBLIC
demo_framework point_dialog Qt5::Gui Qt5::OpenGL Qt5::Widgets Qt5::Script)
add_executable ( Polyhedron_3 Polyhedron_3.cpp )

View File

@ -51,6 +51,7 @@
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
#include <CGAL/Three/Scene_item_with_properties.h>
#include "ui_SubViewer.h"
#include "ui_MainWindow.h"
#include "ui_Preferences.h"
#include "ui_Statistics_on_item_dialog.h"
@ -147,6 +148,7 @@ MainWindow::MainWindow(bool verbose, QWidget* parent)
// Save some pointers from ui, for latter use.
sceneView = ui->sceneView;
viewer = ui->viewer;
viewer->setObjectName("viewer");
// do not save the state of the viewer (anoying)
viewer->setStateFileName(QString::null);
@ -167,6 +169,12 @@ MainWindow::MainWindow(bool verbose, QWidget* parent)
connect(shortcut, SIGNAL(activated()),
this, SLOT(toggleFullScreen()));
}
setupViewer(viewer, 0);
viewer->setKeyDescription(Qt::Key_R + Qt::CTRL,
tr("Recenters the viewer under the cursor. "
"If the cursor is not over any viewer, "
"then all viewers are recentered."));
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(scene);
@ -206,7 +214,7 @@ MainWindow::MainWindow(bool verbose, QWidget* parent)
this, SLOT(removeManipulatedFrame(CGAL::Three::Scene_item*)));
connect(scene, SIGNAL(updated_bbox(bool)),
this, SLOT(updateViewerBBox(bool)));
this, SLOT(updateViewersBboxes(bool)));
connect(scene, SIGNAL(selectionChanged(int)),
this, SLOT(selectSceneItem(int)));
@ -806,7 +814,7 @@ void MainWindow::viewerShow(float xmin,
min_(xmin, ymin, zmin),
max_(xmax, ymax, zmax);
if(min_ == max_) return viewerShow(xmin, ymin, zmin);
if(min_ == max_) return viewerShow(viewer, xmin, ymin, zmin);
viewer->camera()->setPivotPoint((min_+max_)*0.5);
@ -818,18 +826,17 @@ void MainWindow::viewerShow(float xmin,
viewer->setVisualHintsMask(1);
}
void MainWindow::viewerShow(float x, float y, float z) {
// viewer->camera()->lookAt(CGAL::qglviewer::Vec(x, y, z));
void MainWindow::viewerShow(Viewer_interface* vi, float x, float y, float z) {
CGAL::qglviewer::ManipulatedCameraFrame backup_frame(*vi->camera()->frame());
vi->camera()->fitSphere(CGAL::qglviewer::Vec(x, y, z),
vi->camera()->sceneRadius()/100);
CGAL::qglviewer::ManipulatedCameraFrame new_frame(*vi->camera()->frame());
*vi->camera()->frame() = backup_frame;
vi->camera()->interpolateTo(new_frame, 1.f);
vi->setVisualHintsMask(1);
CGAL::qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame());
viewer->camera()->fitSphere(CGAL::qglviewer::Vec(x, y, z),
viewer->camera()->sceneRadius()/100);
CGAL::qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame());
*viewer->camera()->frame() = backup_frame;
viewer->camera()->interpolateTo(new_frame, 1.f);
viewer->setVisualHintsMask(1);
viewer->camera()->setPivotPoint(CGAL::qglviewer::Vec(x, y, z));
vi->camera()->setPivotPoint(CGAL::qglviewer::Vec(x, y, z));
}
void MainWindow::message(QString message, QString colorName, QString font) {
@ -860,10 +867,24 @@ void MainWindow::error(QString text) {
this->message("ERROR: " + text, "red");
}
void MainWindow::updateViewerBBox(bool recenter = true)
void MainWindow::updateViewersBboxes(bool recenter)
{
const Scene::Bbox bbox = scene->bbox();
CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint();
CGAL::qglviewer::Vec min, max;
computeViewerBBox(min, max);
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
{
if(v == NULL)
continue;
Viewer* vi = static_cast<Viewer*>(v);
updateViewerBbox(vi, recenter, min, max);
}
}
void MainWindow::computeViewerBBox(CGAL::qglviewer::Vec& min, CGAL::qglviewer::Vec& max)
{
const Scene::Bbox bbox = scene->visibleBbox();
const Scene::Bbox all_bbox = scene->bbox();
const double xmin = bbox.xmin();
const double ymin = bbox.ymin();
const double zmin = bbox.zmin();
@ -871,15 +892,26 @@ void MainWindow::updateViewerBBox(bool recenter = true)
const double ymax = bbox.ymax();
const double zmax = bbox.zmax();
const double axmin = all_bbox.xmin();
const double aymin = all_bbox.ymin();
const double azmin = all_bbox.zmin();
const double axmax = all_bbox.xmax();
const double aymax = all_bbox.ymax();
const double azmax = all_bbox.zmax();
min = CGAL::qglviewer::Vec(xmin, ymin, zmin);
max= CGAL::qglviewer::Vec(xmax, ymax, zmax);
CGAL::qglviewer::Vec abbox_center((axmin+axmax)/2, (aymin+aymax)/2, (azmin+azmax)/2),
bbox_center((xmin+xmax)/2, (ymin+ymax)/2, (zmin+zmax)/2);
CGAL::qglviewer::Vec
vec_min(xmin, ymin, zmin),
vec_max(xmax, ymax, zmax),
bbox_center((xmin+xmax)/2, (ymin+ymax)/2, (zmin+zmax)/2);
CGAL::qglviewer::Vec offset(0,0,0);
double l_dist = (std::max)((std::abs)(bbox_center.x - viewer->offset().x),
(std::max)((std::abs)(bbox_center.y - viewer->offset().y),
(std::abs)(bbox_center.z - viewer->offset().z)));
(std::max)((std::abs)(bbox_center.y - viewer->offset().y),
(std::abs)(bbox_center.z - viewer->offset().z)));
if((std::log2)(l_dist) > 13.0 )
for(int i=0; i<3; ++i)
{
@ -888,25 +920,20 @@ void MainWindow::updateViewerBBox(bool recenter = true)
}
if(offset != viewer->offset())
{
viewer->setOffset(offset);
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
{
if(v == NULL)
continue;
Viewer* vi = qobject_cast<Viewer*>(v);
vi->setOffset(offset);
}
for(int i=0; i<scene->numberOfEntries(); ++i)
{
// scene->item(i)->invalidate(Scene_item::GEOMETRY);
scene->item(i)->invalidateOpenGLBuffers();
scene->item(i)->itemChanged();
}
}
viewer->setSceneBoundingBox(vec_min,
vec_max);
if(recenter)
{
viewer->camera()->showEntireScene();
}
else
{
viewer->camera()->setPivotPoint(center);
}
}
void MainWindow::reloadItem() {
@ -1238,31 +1265,36 @@ void MainWindow::selectionChanged()
scene->setSelectedItemIndex(getSelectedSceneItemIndex());
scene->setSelectedItemsList(getSelectedSceneItemIndices());
CGAL::Three::Scene_item* item = scene->item(getSelectedSceneItemIndex());
if(item != NULL && item->manipulatable()) {
viewer->setManipulatedFrame(item->manipulatedFrame());
} else {
viewer->setManipulatedFrame(0);
}
if(viewer->manipulatedFrame() == 0) {
Q_FOREACH(CGAL::Three::Scene_item* item, scene->entries()) {
if(item->manipulatable() && item->manipulatedFrame() != 0) {
if(viewer->manipulatedFrame() != 0) {
// there are at least two possible frames
viewer->setManipulatedFrame(0);
break;
} else {
viewer->setManipulatedFrame(item->manipulatedFrame());
Q_FOREACH(CGAL::QGLViewer* vi, CGAL::QGLViewer::QGLViewerPool())
{
if(vi == NULL)
continue;
if(item != NULL && item->manipulatable()) {
vi->setManipulatedFrame(item->manipulatedFrame());
} else {
vi->setManipulatedFrame(0);
}
if(vi->manipulatedFrame() == 0) {
Q_FOREACH(CGAL::Three::Scene_item* item, scene->entries()) {
if(item->manipulatable() && item->manipulatedFrame() != 0) {
if(vi->manipulatedFrame() != 0) {
// there are at least two possible frames
vi->setManipulatedFrame(0);
break;
} else {
vi->setManipulatedFrame(item->manipulatedFrame());
}
}
}
}
if(vi->manipulatedFrame() != 0) {
connect(vi->manipulatedFrame(), SIGNAL(modified()),
this, SLOT(updateInfo()));
}
vi->update();
}
if(viewer->manipulatedFrame() != 0) {
connect(viewer->manipulatedFrame(), SIGNAL(modified()),
this, SLOT(updateInfo()));
}
viewer->update();
}
void MainWindow::contextMenuRequested(const QPoint& global_pos) {
int index = scene->mainSelectionIndex();
showSceneContextMenu(index, global_pos);
@ -1958,10 +1990,16 @@ void MainWindow::on_actionPreferences_triggered()
void MainWindow::setBackgroundColor()
{
QColor c = QColorDialog::getColor();
if(c.isValid()) {
viewer->setBackgroundColor(c);
viewer->update();
}
if(c.isValid()) {
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
{
if(v == NULL)
continue;
v->setBackgroundColor(c);
v->update();
}
}
}
void MainWindow::setLighting_triggered()
@ -1977,7 +2015,8 @@ void MainWindow::on_actionLookAt_triggered()
if( i == QDialog::Accepted &&
dialog.has_correct_coordinates() )
{
viewerShow((float)dialog.get_x()+viewer->offset().x,
viewerShow(viewer,
(float)dialog.get_x()+viewer->offset().x,
(float)dialog.get_y()+viewer->offset().y,
(float)dialog.get_z()+viewer->offset().z);
}
@ -1999,7 +2038,7 @@ void MainWindow::viewerShowObject()
max.x, max.y, max.z);
}
}
/* to check
QString MainWindow::cameraString() const
{
const CGAL::qglviewer::Vec pos = viewer->camera()->position() - viewer->offset();
@ -2013,21 +2052,26 @@ QString MainWindow::cameraString() const
.arg(q[1])
.arg(q[2])
.arg(q[3]);
}*/
QString MainWindow::cameraString(CGAL::Three::Viewer_interface* v) const
{
return v->dumpCameraCoordinates();
}
void MainWindow::on_actionDumpCamera_triggered()
{
//remove offset
information(QString("Camera: %1")
.arg(cameraString()));
.arg(cameraString(viewer)));
}
void MainWindow::on_actionCopyCamera_triggered()
{
//remove offset
qApp->clipboard()->setText(this->cameraString());
qApp->clipboard()->setText(this->cameraString(viewer));
}
/* to check
void MainWindow::on_actionPasteCamera_triggered()
{
//add offset
@ -2044,6 +2088,11 @@ void MainWindow::on_actionPasteCamera_triggered()
for(int i=0; i<7; ++i)
s.append(new_s[i]).append(" ");
viewer->moveCameraToCoordinates(s, 0.5f);
}*/
void MainWindow::on_actionPasteCamera_triggered()
{
QString s = qApp->clipboard()->text();
viewer->moveCameraToCoordinates(s, 0.5f);
}
void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
@ -2053,8 +2102,17 @@ void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
void MainWindow::on_actionRecenterScene_triggered()
{
updateViewerBBox();
viewer->camera()->interpolateToFitScene();
scene->computeBbox();
scene->computeVisibleBbox();
CGAL::qglviewer::Vec min, max;
computeViewerBBox(min, max);
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
{
if(v == NULL)
continue;
updateViewerBbox(static_cast<Viewer*>(v), true, min, max);
v->camera()->interpolateToFitScene();
}
}
void MainWindow::on_actionLoadPlugin_triggered()
@ -2368,6 +2426,7 @@ void MainWindow::propagate_action()
}
}
}
void MainWindow::setTransparencyPasses(int val)
{
viewer->setTotalPass(val);
@ -2406,3 +2465,271 @@ void MainWindow::setDefaultSaveDir()
QSettings settings;
settings.setValue("default_saveas_dir", def_save_dir);
}
void MainWindow::setupViewer(Viewer* viewer, SubViewer* subviewer=NULL)
{
// do not save the state of the viewer (anoying)
viewer->setStateFileName(QString::null);
viewer->textRenderer()->setScene(scene);
viewer->setScene(scene);
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
viewer, SLOT(update()));
connect(scene, SIGNAL(updated()),
viewer, SLOT(update()));
if(subviewer == NULL)
{
connect(ui->actionRecenterScene, SIGNAL(triggered()),
viewer, SLOT(update()));
connect(ui->actionRecenterScene, SIGNAL(triggered()),
this, SLOT(on_actionRecenterScene_triggered()));
connect(ui->actionLookAt, SIGNAL(triggered()),
this, SLOT(on_actionLookAt_triggered()));
connect(ui->actionSetBackgroundColor, SIGNAL(triggered()),
this, SLOT(on_actionSetBackgroundColor_triggered()));
connect(ui->actionDumpCamera, SIGNAL(triggered()),
this, SLOT(on_actionDumpCamera_triggered()));
connect(ui->actionCopyCamera, SIGNAL(triggered()),
this, SLOT(on_actionCopyCamera_triggered()));
connect(ui->actionPasteCamera, SIGNAL(triggered()),
this, SLOT(on_actionPasteCamera_triggered()));
connect(ui->actionAntiAliasing, SIGNAL(toggled(bool)),
viewer, SLOT(setAntiAliasing(bool)));
connect(ui->actionDrawTwoSides, SIGNAL(toggled(bool)),
viewer, SLOT(setTwoSides(bool)));
connect(ui->actionQuickCameraMode, SIGNAL(toggled(bool)),
viewer, SLOT(setFastDrawing(bool)));
connect(ui->actionSwitchProjection, SIGNAL(toggled(bool)),
viewer, SLOT(SetOrthoProjection(bool)));
connect(ui->actionSet_Transparency_Pass_Number, SIGNAL(triggered()),
viewer, SLOT(setTotalPass_clicked()));
}
else
{
QAction* action = subviewer->findChild<QAction*>("actionRecenter");
connect(action, SIGNAL(triggered()),
viewer, SLOT(update()));
connect(action, &QAction::triggered,
subviewer, &SubViewer::recenter);
action= subviewer->findChild<QAction*>("actionLookat");
connect(action, SIGNAL(triggered()),
subviewer, SLOT(lookat()));
action= subviewer->findChild<QAction*>("actionColor");
connect(action, &QAction::triggered,
subviewer, &SubViewer::color);
action= subviewer->findChild<QAction*>("actionDumpCamera");
connect(action, &QAction::triggered,
[this, viewer](){
information(QString("Camera: %1")
.arg(cameraString(viewer)));
});
action= subviewer->findChild<QAction*>("actionCopyCamera");
connect(action, &QAction::triggered,
[this, viewer](){
qApp->clipboard()->setText(cameraString(viewer));
});
action= subviewer->findChild<QAction*>("actionPasteCamera");
connect(action, &QAction::triggered,
this, [viewer](){
QString s = qApp->clipboard()->text();
viewer->moveCameraToCoordinates(s, 0.5f);
});
action= subviewer->findChild<QAction*>("actionAntiAliasing");
connect(action, SIGNAL(toggled(bool)),
viewer, SLOT(setAntiAliasing(bool)));
action= subviewer->findChild<QAction*>("actionDrawTwoSide");
connect(action, SIGNAL(toggled(bool)),
viewer, SLOT(setTwoSides(bool)));
action= subviewer->findChild<QAction*>("actionQuick");
connect(action, SIGNAL(toggled(bool)),
viewer, SLOT(setFastDrawing(bool)));
action= subviewer->findChild<QAction*>("actionOrtho");
connect(action, SIGNAL(toggled(bool)),
viewer, SLOT(SetOrthoProjection(bool)));
action= subviewer->findChild<QAction*>("actionTotalPass");
connect(action, &QAction::triggered,
viewer, &Viewer::setTotalPass_clicked);
}
connect(viewer, SIGNAL(requestContextMenu(QPoint)),
this, SLOT(contextMenuRequested(QPoint)));
connect(viewer, SIGNAL(selected(int)),
this, SLOT(selectSceneItem(int)));
connect(viewer, SIGNAL(selectedPoint(double, double, double)),
this, SLOT(showSelectedPoint(double, double, double)));
connect(viewer, SIGNAL(selectionRay(double, double, double,
double, double, double)),
scene, SIGNAL(selectionRay(double, double, double,
double, double, double)));
connect(viewer, SIGNAL(sendMessage(QString)),
this, SLOT(information(QString)));
}
void MainWindow::on_actionAdd_Viewer_triggered()
{
Viewer *viewer2 = new Viewer(ui->centralwidget, viewer);
viewer2->setManipulatedFrame(viewer->manipulatedFrame());
CGAL::qglviewer::Vec min, max;
computeViewerBBox(min, max);
updateViewerBbox(viewer2, true, min, max);
viewer2->camera()->interpolateToFitScene();
viewer2->setObjectName("viewer2");
connect(viewer2, SIGNAL(doneInitGL(CGAL::Three::Viewer_interface*)),
scene, SLOT(newViewer(CGAL::Three::Viewer_interface*)));
SubViewer* sub_viewer = new SubViewer(this, viewer2);
ui->viewerLayout->addWidget(sub_viewer);
setupViewer(viewer2, sub_viewer);
connect(sub_viewer->ui->exitButton, &QPushButton::clicked,
[this, sub_viewer](){
scene->removeViewer(sub_viewer->viewer);
sub_viewer->deleteLater();});
}
void MainWindow::recenterViewer()
{
scene->computeBbox();
scene->computeVisibleBbox();
CGAL::qglviewer::Vec min, max;
computeViewerBBox(min, max);
Viewer* target = qobject_cast<Viewer*>(childAt(cursor().pos()));
if(target)
{
scene->computeBbox();
updateViewerBbox(target, true, min, max);
target->camera()->interpolateToFitScene();
}
}
void MainWindow::updateViewerBbox(Viewer *vi, bool recenter,
CGAL::qglviewer::Vec min,
CGAL::qglviewer::Vec max){
CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint();
vi->setSceneBoundingBox(min,
max);
if(recenter)
{
vi->resetFov();
vi->camera()->showEntireScene();
}
else
{
vi->camera()->setPivotPoint(center);
}
}
QObject* MainWindow::getDirectChild(QObject* widget)
{
if(!widget->property("helpText").toString().isEmpty())
return widget;
return getDirectChild(widget->parent());
}
SubViewer::SubViewer(MainWindow* mw, Viewer* viewer)
:QWidget(mw),
mw(mw),
viewer(viewer),
viewMenu(new QMenu(this))
{
ui = new Ui::SubViewer;
ui->setupUi(this);
ui->mainLayout->addWidget(viewer, 1);
ui->menuButton->setMenu(viewMenu);
ui->menuButton->setProperty("helpText", QString("This is the view menu for this Viewer. \n"
"It holds independant display options."));
ui->exitButton->setProperty("helpText", QString("Click here to close this Viewer."));
QAction* actionRecenter = new QAction("Re&center Scene",this);
actionRecenter->setObjectName("actionRecenter");
viewMenu->addAction(actionRecenter);
QAction* actionLookat = new QAction("&Look at...",this);
actionLookat->setObjectName("actionLookat");
viewMenu->addAction(actionLookat);
QAction* actionColor = new QAction("Change &Background Color...",this);
actionColor->setObjectName("actionColor");
viewMenu->addAction(actionColor);
QAction* actionDumpCamera = new QAction("&Dump Camera Coordinates",this);
actionDumpCamera->setObjectName("actionDumpCamera");
QAction* actionCopyCamera = new QAction("&Copy Camera",this);
actionCopyCamera->setObjectName("actionCopyCamera");
QAction* actionPasteCamera = new QAction("&Paste Camera",this);
actionPasteCamera->setObjectName("actionPasteCamera");
QMenu* cameraMenu = new QMenu("Camera", mw);
cameraMenu->addAction(actionDumpCamera);
cameraMenu->addAction(actionCopyCamera);
cameraMenu->addAction(actionPasteCamera);
viewMenu->addMenu(cameraMenu);
QAction* actionAntiAliasing = new QAction("&Antialiasing",this);
actionAntiAliasing->setObjectName("actionAntiAliasing");
actionAntiAliasing->setCheckable(true);
actionAntiAliasing->setChecked(false);
viewMenu->addAction(actionAntiAliasing);
QAction* actionDrawTwoSide = new QAction("Draw &Two Sides",this);
actionDrawTwoSide->setObjectName("actionDrawTwoSide");
actionDrawTwoSide->setCheckable(true);
actionDrawTwoSide->setChecked(false);
viewMenu->addAction(actionDrawTwoSide);
QAction* actionQuick = new QAction("Quick Camera Mode",this);
actionQuick->setObjectName("actionQuick");
actionQuick->setCheckable(true);
actionQuick->setChecked(true);
viewMenu->addAction(actionQuick);
QAction* actionOrtho = new QAction("Orthographic Projection",this);
actionOrtho->setObjectName("actionOrtho");
actionOrtho->setCheckable(true);
actionOrtho->setChecked(false);
viewMenu->addAction(actionOrtho);
QAction* actionLight = new QAction("L&ighting...",this);
actionLight->setObjectName("actionLight");
viewMenu->addAction(actionLight);
QAction* actionTotalPass = new QAction("Set Transparency Pass &Number...",this);
actionTotalPass->setObjectName("actionTotalPass");
viewMenu->addAction(actionTotalPass);
}
SubViewer::~SubViewer()
{
delete ui;
viewer->deleteLater();
}
void SubViewer::recenter()
{
CGAL::qglviewer::Vec min, max;
mw->computeViewerBBox(min, max);
mw->updateViewerBbox(viewer, true, min, max);
viewer->camera()->interpolateToFitScene();
}
void SubViewer::lookat()
{
Show_point_dialog dialog(mw);
dialog.setWindowTitle(tr("Look at..."));
int i = dialog.exec();
if( i == QDialog::Accepted &&
dialog.has_correct_coordinates() )
{
mw->viewerShow(viewer,
(float)dialog.get_x(),
(float)dialog.get_y(),
(float)dialog.get_z());
}
}
void SubViewer::color()
{
QColor c = QColorDialog::getColor();
if(c.isValid()) {
viewer->setBackgroundColor(c);
viewer->update();
}
}

View File

@ -19,6 +19,7 @@
#include <QModelIndex>
class Scene;
class Viewer;
struct SubViewer;
class QTreeView;
class QMenu;
namespace CGAL {
@ -26,6 +27,10 @@ namespace Three{
class Polyhedron_demo_io_plugin_interface;
class Polyhedron_demo_plugin_interface;
class Scene_item;
class Viewer_interface;
}
namespace qglviewer{
class Vec;
}
}
@ -33,6 +38,7 @@ class QSortFilterProxyModel;
namespace Ui {
class MainWindow;
class SubViewer;
class Statistics_on_item_dialog;
}
@ -81,7 +87,7 @@ public:
* throws `std::logic_error` if loading does not succeed or
* `std::invalid_argument` if `fileinfo` specifies an invalid file*/
CGAL::Three::Scene_item* loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface*);
Q_SIGNALS:
//! Is emitted when the Application is closed.
void on_closure();
@ -96,7 +102,7 @@ public Q_SLOTS:
void makeNewGroup();
//! Re-computes the viewer's Bbox
//! If `b` is true, recenters the scene.
void updateViewerBBox(bool b);
void updateViewersBboxes(bool recenter);
//! Opens a script or a file with the default loader if there is.
void open(QString);
//! Is called when the up button is pressed.
@ -193,21 +199,21 @@ public Q_SLOTS:
void addAction(QString actionName,
QString actionText,
QString menuName);
/*!
* Sets the scene center to the target position and makes the
* scene slide to this new center. Also sets the pivotPoint of
* the camera to this position.
*/
void viewerShow(float, float, float);
/*!
* Sets the scene center to be the center of the target BBox.
* Also sets the pivotPoint of the camera to this position.
*/
void viewerShow(float, float, float, float, float, float);
/*!
* Centers the scene on the target object.
*/
void viewerShowObject();
/*! Sets the scene center to the target position and makes the
* scene slide to this new center. Also sets the pivotPoint of
* the camera to this position.
*/
void viewerShow(CGAL::Three::Viewer_interface *viewer, float, float, float);
/*!
* Sets the scene center to be the center of the target BBox.
* Also sets the pivotPoint of the camera to this position.
*/
void viewerShow(float, float, float, float, float, float);
/*!
* Centers the scene on the target object.
*/
void viewerShowObject();
/*!
* Displays a text preceded by the mention "INFO :".
*/
@ -335,7 +341,7 @@ protected Q_SLOTS:
*/
void on_actionLookAt_triggered();
//!Returns the position and orientation of the current camera frame.
QString cameraString() const;
QString cameraString(CGAL::Three::Viewer_interface *v) const;
/*! Prints the position and orientation of the current camera frame.
* @see cameraString()
*/
@ -383,7 +389,9 @@ protected:
//! Returns a list of the selected items in the Geometric Objects view.
QList<int> getSelectedSceneItemIndices() const;
private:
QObject* getDirectChild(QObject* widget);
void updateMenus();
void setupViewer(Viewer* viewer, SubViewer *subviewer);
bool load_plugin(QString names, bool blacklisted);
void recurseExpand(QModelIndex index);
QMap<QString, QMenu*> menu_map;
@ -438,6 +446,29 @@ private:
QLineEdit operationSearchBar;
QWidgetAction* searchAction;
QString def_save_dir;
void computeViewerBBox(CGAL::qglviewer::Vec &min, CGAL::qglviewer::Vec &max);
void updateViewerBbox(Viewer* vi, bool recenter, CGAL::qglviewer::Vec min,
CGAL::qglviewer::Vec max);
private Q_SLOTS:
void on_actionAdd_Viewer_triggered();
void recenterViewer();
};
struct SubViewer : public QWidget
{
Q_OBJECT
public:
MainWindow* mw;
Viewer* viewer;
Ui::SubViewer* ui;
QMenu* viewMenu;
SubViewer(MainWindow* mw, Viewer* viewer);
~SubViewer();
public Q_SLOTS:
void recenter();
void lookat();
void color();
};
#endif // ifndef MAINWINDOW_H

View File

@ -20,14 +20,18 @@
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="Viewer" name="viewer" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
<layout class="QHBoxLayout" name="viewerLayout">
<item>
<widget class="Viewer" name="viewer" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
@ -95,6 +99,7 @@
<addaction name="actionLookAt"/>
<addaction name="actionDrawTwoSides"/>
<addaction name="actionSwitchProjection"/>
<addaction name="actionAdd_Viewer"/>
<addaction name="menuDockWindows"/>
<addaction name="menuCamera"/>
<addaction name="separator"/>
@ -492,12 +497,18 @@
<string>Set Different Colors for Selected Items</string>
</property>
</action>
<action name="actionAdd_Viewer">
<property name="text">
<string>Add &amp;Viewer</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Viewer</class>
<extends>QWidget</extends>
<header>Viewer.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>

View File

@ -435,10 +435,10 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer)
vbo[1].create();
viewer->makeCurrent();
vao = new QOpenGLVertexArrayObject();
vao->create();
vaos[viewer] = new QOpenGLVertexArrayObject();
vaos[viewer]->create();
program.bind();
vao->bind();
vaos[viewer]->bind();
vbo[0].bind();
vbo[0].allocate(points, 18 * sizeof(float));
program.enableAttributeArray("vertex");
@ -450,7 +450,7 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer)
program.enableAttributeArray("v_texCoord");
program.setAttributeArray("v_texCoord", GL_FLOAT, 0, 2);
vbo[1].release();
vao->release();
vaos[viewer]->release();
program.release();
gl_init = true;
}
@ -778,7 +778,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
//blending
program.bind();
vao->bind();
vaos[viewer]->bind();
viewer->glClearColor(background.redF(),
background.greenF(),
background.blueF(),
@ -802,7 +802,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
}
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
vao->release();
vaos[viewer]->release();
program.release();
}
@ -1201,6 +1201,7 @@ void Scene::itemVisibilityChanged(CGAL::Three::Scene_item* item)
&& !item->isEmpty())
{
//does not recenter
computeVisibleBbox();
Q_EMIT updated_bbox(false);
}
}
@ -1662,3 +1663,75 @@ void Scene::adjustIds(Item_id removed_id)
m_entries[i]->setId(i-1);//the signal is emitted before m_entries is amputed from the item, so new id is current id -1.
}
}
void Scene::computeVisibleBbox()
{
if(m_entries.empty())
{
last_visible_bbox = Bbox(0,0,0,0,0,0);
return;
}
bool bbox_initialized = false;
Bbox bbox = Bbox(0,0,0,0,0,0);
Q_FOREACH(CGAL::Three::Scene_item* item, m_entries)
{
if(item->isFinite() && !item->isEmpty() && item->visible()) {
if(bbox_initialized) {
bbox = bbox + item->bbox();
}
else {
bbox = item->bbox();
bbox_initialized = true;
}
}
}
last_visible_bbox = bbox;
}
void Scene::computeBbox()
{
if(m_entries.empty())
{
last_bbox = Bbox(0,0,0,0,0,0);
return;
}
bool bbox_initialized = false;
Bbox bbox = Bbox(0,0,0,0,0,0);
Q_FOREACH(CGAL::Three::Scene_item* item, m_entries)
{
if(item->isFinite() && !item->isEmpty() ) {
if(bbox_initialized) {
bbox = bbox + item->bbox();
}
else {
bbox = item->bbox();
bbox_initialized = true;
}
}
}
last_bbox = bbox;
}
void Scene::removeViewer(Viewer_interface *viewer)
{
vaos[viewer]->destroy();
vaos[viewer]->deleteLater();
vaos.remove(viewer);
Q_FOREACH(Scene_item* item, m_entries)
{
item->removeViewer(viewer);
}
}
Scene::Bbox Scene::visibleBbox() const
{
return last_visible_bbox;
}

View File

@ -93,6 +93,9 @@ public:
void updatePrimitiveIds(Viewer_interface *, Scene_item *item) Q_DECL_OVERRIDE;
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer) Q_DECL_OVERRIDE;
Bbox bbox() const Q_DECL_OVERRIDE;
Bbox visibleBbox() const ;
void computeBbox();
void computeVisibleBbox();
double len_diagonal() const Q_DECL_OVERRIDE
{
Bbox box = bbox();
@ -278,9 +281,12 @@ private:
float points[18];
float uvs[12];
QOpenGLShaderProgram program;
QOpenGLVertexArrayObject* vao;
QMap<CGAL::Three::Viewer_interface*, QOpenGLVertexArrayObject*> vaos;
mutable QOpenGLBuffer vbo[2];
Bbox last_bbox;
Bbox last_visible_bbox;
public:
void removeViewer(CGAL::Three::Viewer_interface*);
}; // end class Scene
class QAbstractProxyModel;
@ -316,6 +322,7 @@ private:
QAbstractProxyModel *proxy;
Scene *scene;
mutable int size;
}; // end class SceneDelegate
#endif // SCENE_H

View File

@ -15,8 +15,7 @@ Scene_group_item::Scene_group_item(QString name, int nb_vbos, int nb_vaos )
bool Scene_group_item::isFinite() const
{
Q_FOREACH(Scene_interface::Item_id id, children)
if(!getChild(id)->isFinite()){
return false;
if(!getChild(id)->isFinite()){ return false;
}
return true;
}
@ -246,3 +245,5 @@ void Scene_group_item::setAlpha(int )
}
}
void Scene_group_item::removeViewer(CGAL::Three::Viewer_interface*)
{}

View File

@ -242,3 +242,19 @@ void Scene_item_rendering_helper::setBuffersInit(Viewer_interface* viewer, bool
{
priv->buffers_init[viewer] = val;
}
void Scene_item_rendering_helper::removeViewer(Viewer_interface *viewer)
{
Q_FOREACH(Triangle_container* tc, priv->triangle_containers)
{
tc->removeViewer(viewer);
}
Q_FOREACH(Edge_container* ec, priv->edge_containers)
{
ec->removeViewer(viewer);
}
Q_FOREACH(Point_container* pc, priv->point_containers)
{
pc->removeViewer(viewer);
}
}

View File

@ -152,6 +152,7 @@ public:
const Polygons& polygons() const;
const Edges& non_manifold_edges() const;
void removeViewer(CGAL::Three::Viewer_interface*)Q_DECL_OVERRIDE{}
public Q_SLOTS:
void shuffle_orientations();
bool orient();

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SubViewer</class>
<widget class="QWidget" name="SubViewer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>240</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0">
<item>
<layout class="QVBoxLayout" name="mainLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="menuButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="Polyhedron_3.qrc">
<normaloff>:/cgal/icons/menu</normaloff>:/cgal/icons/menu</iconset>
</property>
<property name="iconSize">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="exitButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="Polyhedron_3.qrc">
<normaloff>:/cgal/icons/exit</normaloff>:/cgal/icons/exit</iconset>
</property>
<property name="iconSize">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="Polyhedron_3.qrc"/>
<include location="Polyhedron_3.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -23,12 +23,13 @@
#include <QByteArray>
#include <QBuffer>
#endif
#define ORIGINAL_FOV 0.94853805396568136
class Viewer_impl {
public:
CGAL::Three::Scene_draw_interface* scene;
Viewer *viewer;
Viewer *shareViewer;
bool antialiasing;
bool twosides;
bool macro_mode;
@ -97,9 +98,13 @@ public:
void clearDistancedisplay();
void draw_aux(bool with_names, Viewer*);
//! Contains all the programs for the item rendering.
mutable std::vector<QOpenGLShaderProgram*> shader_programs;
static std::vector<QOpenGLShaderProgram*> shader_programs;
QMatrix4x4 projectionMatrix;
void sendSnapshotToClipboard(Viewer*);
std::vector<QOpenGLShaderProgram*>& shaderPrograms()
{
return shader_programs;
}
};
class LightingDialog :
@ -211,10 +216,10 @@ private:
QColorDialog spec_dial;
};
Viewer::Viewer(QWidget* parent, bool antialiasing)
: CGAL::Three::Viewer_interface(parent)
std::vector<QOpenGLShaderProgram*> Viewer_impl::shader_programs =
std::vector<QOpenGLShaderProgram*>(Viewer::NB_OF_PROGRAMS);
void Viewer::doBindings()
{
d = new Viewer_impl;
QSettings viewer_settings;
// enable anti-aliasing
QString cam_pos = viewer_settings.value("cam_pos", QString("0.0,0.0,1.0")).toString();
@ -245,7 +250,6 @@ Viewer::Viewer(QWidget* parent, bool antialiasing)
d->scene = 0;
d->projection_is_ortho = false;
d->initialized = false;
d->antialiasing = antialiasing;
d->twosides = false;
this->setProperty("draw_two_sides", false);
d->macro_mode = false;
@ -306,6 +310,32 @@ Viewer::Viewer(QWidget* parent, bool antialiasing)
setTextIsEnabled(true);
}
Viewer::Viewer(QWidget* parent, bool antialiasing)
: CGAL::Three::Viewer_interface(parent)
{
d = new Viewer_impl;
d->antialiasing = antialiasing;
doBindings();
}
Viewer::Viewer(QWidget* parent,
Viewer* sharedWidget,
bool antialiasing)
: CGAL::Three::Viewer_interface(parent, sharedWidget)
{
d = new Viewer_impl;
d->viewer = this;
d->shareViewer = sharedWidget;
is_sharing = true;
d->antialiasing = antialiasing;
this->setProperty("draw_two_sides", false);
this->setProperty("helpText", QString("This is a sub-viewer. It displays the scene "
"from another point of view. \n "));
is_ogl_4_3 = sharedWidget->is_ogl_4_3;
d->_recentFunctions = sharedWidget->d->_recentFunctions;
doBindings();
}
Viewer::~Viewer()
{
QSettings viewer_settings;
@ -1639,5 +1669,10 @@ void Viewer::setGlPointSize(const GLfloat &p) { d->gl_point_size = p; }
const GLfloat& Viewer::getGlPointSize() const { return d->gl_point_size; }
void Viewer::resetFov()
{
camera()->setHorizontalFieldOfView(ORIGINAL_FOV);
}
#include "Viewer.moc"

View File

@ -16,6 +16,10 @@
#include <CGAL/Three/TextRenderer.h>
// forward declarations
class QWidget;
class QMouseEvent;
class QKeyEvent;
class QContextMenuEvent;
class Viewer_impl;
namespace CGAL{
namespace Three{
class Scene_draw_interface;
@ -34,6 +38,7 @@ class VIEWER_EXPORT Viewer : public CGAL::Three::Viewer_interface {
public:
Viewer(QWidget * parent, bool antialiasing = false);
Viewer(QWidget * parent, Viewer *sharedWidget, bool antialiasing = false);
~Viewer();
bool testDisplayId(double, double, double)Q_DECL_OVERRIDE;
void updateIds(CGAL::Three::Scene_item *)Q_DECL_OVERRIDE;
@ -85,9 +90,10 @@ public:
const QImage& staticImage() const Q_DECL_OVERRIDE;
//!Set total number of depth peeling passes.
void setTotalPass(int);
void resetFov();
Q_SIGNALS:
void sendMessage(QString);
void doneInitGL(CGAL::Three::Viewer_interface*);
public Q_SLOTS:
//! Sets the antialiasing to true or false.
void setAntiAliasing(bool b) Q_DECL_OVERRIDE;
@ -122,6 +128,7 @@ public Q_SLOTS:
void setLighting();
void messageLogged(QOpenGLDebugMessage);
void initializeGL()Q_DECL_OVERRIDE;
protected:
void paintEvent(QPaintEvent *)Q_DECL_OVERRIDE;
@ -142,6 +149,7 @@ protected:
friend class Viewer_impl;
Viewer_impl* d;
double prev_radius;
void doBindings();
public:
QOpenGLFunctions_4_3_Core* openGL_4_3_functions() Q_DECL_OVERRIDE;

View File

@ -237,7 +237,7 @@ public :
void moveUp(int);
//!Moves a child down in the list.
void moveDown(int);
void removeViewer(CGAL::Three::Viewer_interface* )Q_DECL_OVERRIDE;
public Q_SLOTS:
//!\brief Redraws children.
//!

View File

@ -301,6 +301,12 @@ public:
//!Contains the number of group and subgroups containing this item.
int has_group;
//!
//! \brief removeViewer removes the Vaos fo `viewer`.
//!
//! Must be overriden;
//!
virtual void removeViewer(CGAL::Three::Viewer_interface* viewer) = 0;
public Q_SLOTS:

View File

@ -190,6 +190,9 @@ public:
//! @returns the item's bounding box's diagonal length.
//! @todo must replace the one from Scene_item eventually
virtual double diagonalBbox() const Q_DECL_OVERRIDE;
//! \brief removeViewer removes the Vaos for `viewer`.
//! \param viewer the viewer to be removed.
void removeViewer(Viewer_interface *viewer) Q_DECL_OVERRIDE;
protected:

View File

@ -107,6 +107,14 @@ public:
//! Creates a valid context for OpenGL ES 2.0.
//! \param parent the parent widget. It usually is the MainWindow.
Viewer_interface(QWidget* parent) : CGAL::QGLViewer(parent) {}
//!
//! \brief Constructor for the secondary viewers.
//!
//! \param parent the parent widget. It usually is the MainWindow.
//! \param sharedWidget the main viewer of the Application. This will share the
//! context and allow synchronized rendering of multiple views.
//!
Viewer_interface(QWidget* parent, QWidget*) : QGLViewer(parent){}
virtual ~Viewer_interface() {}
//! \brief Sets the scene for the viewer.