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.
This commit is contained in:
Maxime Gimeno 2018-11-14 11:48:03 +01:00
parent 66e6a5575c
commit 66961f56f6
5 changed files with 89 additions and 44 deletions

View File

@ -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,6 +864,8 @@ void MainWindow::error(QString text) {
void MainWindow::updateViewerBBox(bool recenter = true)
{
if(bbox_need_update)
{
const Scene::Bbox bbox = scene->bbox();
CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint();
const double xmin = bbox.xmin();
@ -908,6 +911,8 @@ void MainWindow::updateViewerBBox(bool recenter = true)
{
viewer->camera()->setPivotPoint(center);
}
bbox_need_update = false;
}
}
void MainWindow::reloadItem() {
@ -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;
}

View File

@ -436,11 +436,13 @@ public:
public Q_SLOTS:
void toggleFullScreen();
void setDefaultSaveDir();
void invalidate_bbox();
private:
QList<QDockWidget *> visibleDockWidgets;
QLineEdit operationSearchBar;
QWidgetAction* searchAction;
QString def_save_dir;
bool bbox_need_update;
};
#endif // ifndef MAINWINDOW_H

View File

@ -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));

View File

@ -136,6 +136,10 @@ 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
@ -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

View File

@ -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;
//! \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
}
}