From aa7d8001a238a0bc97acc74b055b4b26eed35f93 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Tue, 28 Sep 2021 20:08:46 +0200 Subject: [PATCH] Sketcher: Improve the performance of showing/hiding constraints =============================================================== Forum test and comments: https://forum.freecadweb.org/viewtopic.php?p=536445#p536390 What? Showing/hidding a large amount of constraints is very time consuming Why? Because SketchObject Constraints property was being set for each individual constraint Solution is to use the new setVirtualSpace overload taking a list or a tuple, so that all the constraints are set in a single operation. In a Debug system with the test of the forum the time taken by the operation is reduced from 7 minutes to around 2-3 seconds. --- .../Sketcher/Gui/TaskSketcherConstrains.cpp | 146 +++++++++++------- 1 file changed, 89 insertions(+), 57 deletions(-) diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp index 128585777c..b9234cc4a7 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp @@ -715,11 +715,9 @@ void TaskSketcherConstrains::changeFilteredVisibility(bool show, ActionTarget ta assert(sketchView); const Sketcher::SketchObject * sketch = sketchView->getSketchObject(); - bool doCommit = false; - auto selecteditems = ui->listWidgetConstraints->selectedItems(); - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); + std::vector constrIds; for(int i = 0; i < ui->listWidgetConstraints->count(); ++i) { @@ -745,28 +743,44 @@ void TaskSketcherConstrains::changeFilteredVisibility(bool show, ActionTarget ta if((it->isInVirtualSpace() == sketchView->getIsShownVirtualSpace() && !show) || (it->isInVirtualSpace() != sketchView->getIsShownVirtualSpace() && show)) { - - try { - Gui::cmdAppObjectArgs(sketch, "setVirtualSpace(%d, %s)", - it->ConstraintNbr, - show?"False":"True"); - - doCommit = true; - } - catch (const Base::Exception & e) { - Gui::Command::abortCommand(); - - QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), - QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); - - return; - } + constrIds.push_back(it->ConstraintNbr); } } } - if(doCommit) + if(!constrIds.empty()) { + + Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); + + std::stringstream stream; + + stream << '['; + + for(size_t i = 0; i < constrIds.size()-1; i++) { + stream << constrIds[i] << ","; + } + stream << constrIds[constrIds.size()-1] << ']'; + + std::string constrIdList = stream.str(); + + try { + Gui::cmdAppObjectArgs(sketch, "setVirtualSpace(%s, %s)", + constrIdList, + show?"False":"True"); + + } + catch (const Base::Exception & e) { + Gui::Command::abortCommand(); + + QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), + QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); + + return; + } + Gui::Command::commitCommand(); + } + } void TaskSketcherConstrains::on_showAllButton_clicked(bool) @@ -982,9 +996,8 @@ void TaskSketcherConstrains::change3DViewVisibilityToTrackFilter() const Sketcher::SketchObject * sketch = sketchView->getSketchObject(); const std::vector< Sketcher::Constraint * > &vals = sketch->Constraints.getValues(); - bool doCommit = false; - - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); + std::vector constrIdsToVirtualSpace; + std::vector constrIdsToCurrentSpace; for(std::size_t i = 0; i < vals.size(); ++i) { ConstraintItem * it = static_cast(ui->listWidgetConstraints->item(i)); @@ -993,45 +1006,64 @@ void TaskSketcherConstrains::change3DViewVisibilityToTrackFilter() // If the constraint is filteredout and it was previously shown in 3D view if( !visible && it->isInVirtualSpace() == sketchView->getIsShownVirtualSpace()) { - try { - Gui::cmdAppObjectArgs(sketch, "setVirtualSpace(%d, %s)", - it->ConstraintNbr, - "True"); - - doCommit = true; - - } - catch (const Base::Exception & e) { - Gui::Command::abortCommand(); - - QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), - QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); - - return; - } + constrIdsToVirtualSpace.push_back(it->ConstraintNbr); } else if( visible && it->isInVirtualSpace() != sketchView->getIsShownVirtualSpace() ) { - try { - Gui::cmdAppObjectArgs(sketch, "setVirtualSpace(%d, %s)", - it->ConstraintNbr, - "False"); - - doCommit = true; - - } - catch (const Base::Exception & e) { - Gui::Command::abortCommand(); - - QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), - QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); - - return; - } + constrIdsToCurrentSpace.push_back(it->ConstraintNbr); } } - if(doCommit) - Gui::Command::commitCommand(); + if(!constrIdsToVirtualSpace.empty() || !constrIdsToCurrentSpace.empty()) { + + Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space")); + + auto doSetVirtualSpace = [&sketch](const std::vector & constrIds, bool isvirtualspace) { + std::stringstream stream; + + stream << '['; + + for(size_t i = 0; i < constrIds.size()-1; i++) { + stream << constrIds[i] << ","; + } + stream << constrIds[constrIds.size()-1] << ']'; + + std::string constrIdList = stream.str(); + + try { + Gui::cmdAppObjectArgs(sketch, "setVirtualSpace(%s, %s)", + constrIdList, + isvirtualspace?"True":"False"); + + } + catch (const Base::Exception & e) { + Gui::Command::abortCommand(); + + QMessageBox::critical(Gui::MainWindow::getInstance(), tr("Error"), + QString::fromLatin1("Impossible to update visibility tracking: ") + QString::fromLatin1(e.what()), QMessageBox::Ok, QMessageBox::Ok); + + return false; + } + + return true; + }; + + + if(!constrIdsToVirtualSpace.empty()) { + bool ret = doSetVirtualSpace(constrIdsToVirtualSpace, true); + if(!ret) + return; + } + + if(!constrIdsToCurrentSpace.empty()) { + bool ret = doSetVirtualSpace(constrIdsToCurrentSpace, false); + + if(!ret) + return; + } + + Gui::Command::commitCommand(); + + } }