From 66961f56f6cb4e3fc331efb521c2468845d9e9a8 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 14 Nov 2018 11:48:03 +0100 Subject: [PATCH] Add a way to ignore dataChanged() calls of the Scene to optimize big selection manipulation. Use it to make the visibility change of a selection of items instant instead of possibly very long. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 97 +++++++++++++--------- Polyhedron/demo/Polyhedron/MainWindow.h | 2 + Polyhedron/demo/Polyhedron/Scene.cpp | 12 ++- Polyhedron/demo/Polyhedron/Scene.h | 9 +- Three/include/CGAL/Three/Scene_interface.h | 13 ++- 5 files changed, 89 insertions(+), 44 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index c7bffa69bd3..551f8376fe4 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -134,6 +134,7 @@ MainWindow::~MainWindow() MainWindow::MainWindow(bool verbose, QWidget* parent) : CGAL::Qt::DemosMainWindow(parent) { + bbox_need_update = true; ui = new Ui::MainWindow; ui->setupUi(this); menuBar()->setNativeMenuBar(false); @@ -207,7 +208,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(invalidate_bbox())); connect(scene, SIGNAL(selectionChanged(int)), this, SLOT(selectSceneItem(int))); @@ -863,50 +864,54 @@ void MainWindow::error(QString text) { void MainWindow::updateViewerBBox(bool recenter = true) { - const Scene::Bbox bbox = scene->bbox(); + if(bbox_need_update) + { + const Scene::Bbox bbox = scene->bbox(); CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint(); - 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), - 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))); - if((std::log2)(l_dist) > 13.0 ) - for(int i=0; i<3; ++i) + 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), + 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))); + if((std::log2)(l_dist) > 13.0 ) + for(int i=0; i<3; ++i) + { + offset[i] = -bbox_center[i]; + + } + if(offset != viewer->offset()) { - offset[i] = -bbox_center[i]; - + viewer->setOffset(offset); + for(int i=0; inumberOfEntries(); ++i) + { + scene->item(i)->invalidateOpenGLBuffers(); + scene->item(i)->itemChanged(); + } } - if(offset != viewer->offset()) - { - viewer->setOffset(offset); - for(int i=0; inumberOfEntries(); ++i) + + + viewer->setSceneBoundingBox(vec_min, + vec_max); + if(recenter) { - scene->item(i)->invalidateOpenGLBuffers(); - scene->item(i)->itemChanged(); + viewer->camera()->showEntireScene(); } - } - - - viewer->setSceneBoundingBox(vec_min, - vec_max); - if(recenter) - { - viewer->camera()->showEntireScene(); - } - else - { - viewer->camera()->setPivotPoint(center); + else + { + viewer->camera()->setPivotPoint(center); + } + bbox_need_update = false; } } @@ -1644,6 +1649,7 @@ void MainWindow::on_actionLoad_triggered() scene->item(scene->numberOfEntries()-1)->setColor(colors_[++nb_item]); } } + updateViewerBBox(true); } void MainWindow::on_actionSaveAs_triggered() @@ -1817,13 +1823,17 @@ void MainWindow::on_actionDuplicate_triggered() void MainWindow::on_actionShowHide_triggered() { + scene->cutDataUpdate(true); Q_FOREACH(QModelIndex index, sceneView->selectionModel()->selectedRows()) { int i = scene->getIdFromModelIndex(proxyModel->mapToSource(index)); CGAL::Three::Scene_item* item = scene->item(i); item->setVisible(!item->visible()); - scene->itemChanged(i); + item->redraw(); } + scene->cutDataUpdate(false); + scene->allItemsChanged(); + updateViewerBBox(false); } void MainWindow::on_actionSetPolyhedronA_triggered() @@ -2407,3 +2417,8 @@ void MainWindow::setDefaultSaveDir() QSettings settings; settings.setValue("default_saveas_dir", def_save_dir); } + +void MainWindow::invalidate_bbox() +{ + bbox_need_update = true; +} diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h index cc543525563..0f5757030bf 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.h +++ b/Polyhedron/demo/Polyhedron/MainWindow.h @@ -436,11 +436,13 @@ public: public Q_SLOTS: void toggleFullScreen(); void setDefaultSaveDir(); + void invalidate_bbox(); private: QList visibleDockWidgets; QLineEdit operationSearchBar; QWidgetAction* searchAction; QString def_save_dir; + bool bbox_need_update; }; #endif // ifndef MAINWINDOW_H diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 7e4e0fcf240..6cc9803391d 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -42,6 +42,7 @@ Scene::Scene(QObject* parent) this, SLOT(adjustIds(Scene_interface::Item_id))); picked = false; gl_init = false; + dont_emit_changes = false; } Scene::Item_id @@ -1175,6 +1176,8 @@ void Scene::itemChanged() void Scene::itemChanged(Item_id i) { + if(dont_emit_changes) + return; if(i < 0 || i >= m_entries.size()) return; @@ -1182,7 +1185,14 @@ void Scene::itemChanged(Item_id i) this->createIndex(i, LastColumn)); } -void Scene::itemChanged(CGAL::Three::Scene_item*) +void Scene::itemChanged(CGAL::Three::Scene_item*item ) +{ + if(dont_emit_changes) + return; + itemChanged(item_id(item)); +} + +void Scene::allItemsChanged() { Q_EMIT dataChanged(this->createIndex(0, 0), this->createIndex(m_entries.size() - 1, LastColumn)); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index aa778970fb7..a605bef1b74 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -136,7 +136,11 @@ public: void zoomToPosition(QPoint point, CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE; - + void cutDataUpdate(bool b) Q_DECL_OVERRIDE + { + dont_emit_changes = b; + } + public Q_SLOTS: //!Specifies a group as Expanded for the Geometric Objects view void setExpanded(QModelIndex); @@ -146,6 +150,7 @@ public Q_SLOTS: void itemChanged(); void itemChanged(int i) Q_DECL_OVERRIDE; void itemChanged(CGAL::Three::Scene_item*) Q_DECL_OVERRIDE; + void allItemsChanged() Q_DECL_OVERRIDE; //!Transmits a CGAL::Three::Scene_item::itemVisibilityChanged() signal to the scene. void itemVisibilityChanged(); void itemVisibilityChanged(CGAL::Three::Scene_item*) Q_DECL_OVERRIDE; @@ -280,6 +285,8 @@ private: QOpenGLShaderProgram program; QOpenGLVertexArrayObject* vao; mutable QOpenGLBuffer vbo[2]; + //the scene will ignore the itemChanged() signals while this is true. + bool dont_emit_changes; }; // end class Scene diff --git a/Three/include/CGAL/Three/Scene_interface.h b/Three/include/CGAL/Three/Scene_interface.h index b6e39f9feb6..7dae3452615 100644 --- a/Three/include/CGAL/Three/Scene_interface.h +++ b/Three/include/CGAL/Three/Scene_interface.h @@ -144,11 +144,22 @@ public: //! Updates the information about `item` in the //! Geometric Objects list and redraws the scene. virtual void itemChanged(CGAL::Three::Scene_item* item) = 0; + //! + //! \brief Updates all the items in the SceneView. + //! + virtual void allItemsChanged() = 0; //! Re computes the scene Bbox without recentering it. virtual void itemVisibilityChanged(CGAL::Three::Scene_item*) = 0; //! Clears the current selection then sets the selected item to the target index. //! Used to update the selection in the Geometric Objects view. - virtual void setSelectedItem(Item_id) = 0; + virtual void setSelectedItem(Item_id) = 0; + //! \brief ignore data updating. + //! + //! This will ignore all the individual calls to `itemChanged()` until + //! `cutDataUpdate()` is called whith `b` being `false`. + //! Activate this when you know you will call allItemsChanged() after a loop. + //! + virtual void cutDataUpdate(bool b) =0; }; // end interface Scene_interface } }