Summary: | Document.refreshProjection()/.waitForDone() doesn't wait for transform masks to complete | ||
---|---|---|---|
Product: | [Applications] krita | Reporter: | code |
Component: | Scripting | Assignee: | Krita Bugs <krita-bugs-null> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | NOR | ||
Version: | 5.2.2 | ||
Target Milestone: | --- | ||
Platform: | Homebrew (macOS) | ||
OS: | macOS | ||
Latest Commit: | https://invent.kde.org/graphics/krita/-/commit/d78219863dc37ec7ddd5af6d051bc9cdbf0c78fa | Version Fixed In: | |
Sentry Crash Report: | |||
Attachments: | example repro script |
After digging through the source code online, it looks like this could be fixed with a call to `KisLayerUtils::forceAllDelayedNodesUpdate` in `Document::waitForDone()`. I would test this myself, but I'm having difficulty setting up the krita dev environment. A possibly relevant merge request was started @ https://invent.kde.org/graphics/krita/-/merge_requests/2110 Git commit d78219863dc37ec7ddd5af6d051bc9cdbf0c78fa by Dmitry Kazakov, on behalf of Agata Cacko. Committed on 08/04/2024 at 11:29. Pushed by dkazakov into branch 'master'. Fix waitForDone() not waiting for transform mask update Before this commit, if you had a very slow transform mask in an image and you used a script to enable it, then running waitForDone() wasn't enough to ensure that the transform mask stopped updating before running any other code. This commit ensures that it does wait until all the updates are done. Test file can be just a simple document with one transform mask attached to a paint layer with a scribble. The transform mask should heavily use Liquify transform, since it is the slowest one at the moment. Steps to reproduce: 1. Create test file 2. Disable the transform mask (so there will be some updates) 3. Run the script Example test script (use in Scripter): (comes from the bug report) ''' from krita import * doc = Krita.instance().activeDocument() doc.activeNode().setVisible(True) #doc.refreshProjection() doc.activeNode().setBlendingMode(doc.activeNode().blendingMode()) doc.waitForDone() try: doc.setBatchmode(True) exportParameters = InfoObject() exportParameters.setProperty("alpha", True) exportParameters.setProperty("compression", 6) # 0-9 exportParameters.setProperty("indexed", False) if not doc.exportImage('/path/to/file/test485053.png', exportParameters): dialog = QMessageBox() dialog.setText("Error exporting") dialog.exec() finally: doc.setBatchmode(False) ''' M +1 -0 libs/libkis/Document.cpp https://invent.kde.org/graphics/krita/-/commit/d78219863dc37ec7ddd5af6d051bc9cdbf0c78fa |
Created attachment 168159 [details] example repro script SUMMARY When showing/hiding a transform mask or transform masked layer, there is often a significant delay before the mask is fully applied. Until then, a lower quality version is used. From my testing both `Document.refreshProjection()` and `Document.waitForDone()` ignore this and return the moment the low quality is available. If afterward you immediately trigger an export, the exported file will use the low quality version. STEPS TO REPRODUCE 1. Create a medium-sized document 2. Import a much larger image as a new layer 3. Add a transform mask and scale the layer down to fit/fill the canvas 4. Manually hide the transformed layer 5. Programmatically set the transformed layer to visible, call `.refreshProjection()`, and export the document (example script attached) - optionally use `layer.setBlendingMode(layer.blendingMode())` together with `doc.waitForDone()` instead of `.refreshProjection()` OBSERVED RESULT The exported file contains the low-quality "preview" output from the transform mask EXPECTED RESULT Both `.refreshProjection()` and `.waitForDone()` should wait for the transform mask to fully apply, and the resulting exported file should use the full-quality transform mask output. If the 2-3 second delay includes artificial debouncing, that delay should be skipped. SOFTWARE/OS VERSIONS macOS: 13.5.1 (22G90)