Summary: | Layers manipulation is buggy | ||
---|---|---|---|
Product: | [Applications] krita | Reporter: | grum999 |
Component: | Scripting | Assignee: | Krita Bugs <krita-bugs-null> |
Status: | CONFIRMED --- | ||
Severity: | normal | CC: | tamtamy.tymona |
Priority: | NOR | ||
Version: | nightly build (please specify the git hash!) | ||
Target Milestone: | --- | ||
Platform: | Other | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: | Improved Python script showing all three cases |
Description
grum999
2020-09-09 19:51:08 UTC
I'm not sure about Component / Version to set (4.4.0 and 5.0.0 are not in version list) Grum999 It's technically a regression caused by making the Fill Layer multi-threaded, but I think just adding waitForDone() in the FillLayer.cpp should solve this. I haven't checked it yet though. (If you want @Grum check it, please see if adding waitForDone() instead of sleep() would make it work). d52e55f6cc0567ac75c8 In script example, I've replaced > sleep(sv) by > newDocument.waitForDone() There's no change in results, it's still incorrect Grum999 Created attachment 131537 [details]
Improved Python script showing all three cases
I attached an improved script that shows all three cases:
- using doc.waitForDone()
- using 1 ms sleep (not enough for Krita to finish generating)
- using 125 ms sleep (enough)
First two cases give bad results.
Steps to reproduce:
1. Open Krita.
2. Go to Tools -> Scripts -> Scripter.
3. Paste the script and execute.
I've made some other tests. On my side it seems that to get expected results, call to sleepOrWait() is needed only after: - a call to layer.setGenerator() - a call to layer.setBlendingMode() When other call to sleepOrWait() function are in comment, expected result is still OK. With this I can't affirm that problem doesn't occurs for mergeDown(), addChildNode() or other layer/document manipulation, but this tends to confirm that problem, as suspected bu @Tiar, is relative to fill layer. Grum999 Git commit 74dbabc3636fd5a1c18967d9fed105fb2ddaf7b2 by Dmitry Kazakov. Committed on 16/09/2020 at 11:37. Pushed by dkazakov into branch 'master'. Fix Python API for Node::addChildNode() The function should use the command, run it in a stroke and wait for it to finish. That ensures that 1) updates are issued; 2) undo item is created; 3) no threading issues arise. M +12 -4 libs/libkis/Node.cpp https://invent.kde.org/graphics/krita/commit/74dbabc3636fd5a1c18967d9fed105fb2ddaf7b2 Git commit 57dbf8a946d022a86855b95f278f1013f29d3148 by Dmitry Kazakov. Committed on 16/09/2020 at 11:37. Pushed by dkazakov into branch 'master'. Fix Python API for Node::setBlendingMode() The function should use the command, run it in a stroke and wait for it to finish. That ensures that 1) updates are issued; 2) undo item is created; 3) no threading issues arise. M +9 -1 libs/libkis/Node.cpp https://invent.kde.org/graphics/krita/commit/57dbf8a946d022a86855b95f278f1013f29d3148 Git commit 623c5114e009485391be9fbe943a1d9cd4da6bd3 by Dmitry Kazakov. Committed on 16/09/2020 at 11:37. Pushed by dkazakov into branch 'master'. Fix KisGeneratorLayer support KisDelayedUpdateNodeInterface It is needed to make sure the layer is updated when some synchronous non-gui provoked actions are requested. E.g. saving or changing via python API. The path also fixes FillLayer's Pythong API to be synchronous using this fix. M +15 -0 libs/image/generator/kis_generator_layer.cpp M +7 -1 libs/image/generator/kis_generator_layer.h M +6 -0 libs/libkis/FillLayer.cpp https://invent.kde.org/graphics/krita/commit/623c5114e009485391be9fbe943a1d9cd4da6bd3 After my patches the following script works fine: =========================================================== from krita import * from PyQt5.Qt import * from PyQt5 import QtCore from PyQt5.QtCore import ( QByteArray, QPoint ) from PyQt5.QtGui import ( QColor, QImage, QPixmap ) def buildQImage(color, w, h): """Generate a QImage to use for example""" img=QImage(w, h, QImage.Format_ARGB32_Premultiplied) img.fill(Qt.transparent) pxmTgt = QPixmap.fromImage(img) gradientb = QRadialGradient(QPointF(w/3, h/4), 2*w/3) gradientb.setColorAt(0, color) gradientb.setColorAt(1, Qt.black) gradientf = QRadialGradient(QPointF(w/3, h/4), 2*w/3) gradientf.setColorAt(0, Qt.white) gradientf.setColorAt(0.15, Qt.transparent) gradientf.setColorAt(1, Qt.transparent) canvas = QPainter() canvas.begin(pxmTgt) canvas.setRenderHint(QPainter.Antialiasing) canvas.setPen(Qt.NoPen) canvas.setBrush(gradientb) canvas.drawEllipse(QRect(20,20,w-40, h-40)); canvas.setBrush(gradientf) canvas.drawEllipse(QRect(20,20,w-40, h-40)); canvas.end() return pxmTgt.toImage() def setLayerFromQImage(layerNode, image): """Set QImage as layer content""" position = QPoint(0, 0) ptr = image.bits() ptr.setsize(image.byteCount()) layerNode.setPixelData(QByteArray(ptr.asstring()), position.x(), position.y(), image.width(), image.height()) def sleep(value): """Do a sleep of `value` milliseconds""" loop = QEventLoop() QTimer.singleShot(value, loop.quit) loop.exec() dWidth=500 dHeight=500 # Cyan, Magenta, Yellow: colors used to generate layers colors=[QColor(0,255,255), QColor(255,0,255), QColor(255,255,0)] sleepValues=[0, 125] image=buildQImage(QColor(255,0,0), dWidth, dHeight) newDocument = Krita.instance().createDocument(dWidth, dHeight, "Test", "RGBA", "U8", "", 300.0) Krita.instance().activeWindow().addView(newDocument) parentGroupLayer = newDocument.createGroupLayer('Group layer') newDocument.rootNode().addChildNode(parentGroupLayer, None) for i in range(len(colors)): # loop over colors and apply basics actions like plugin Newspaper (and Channel2Layers) does newPLayer = newDocument.createNode(f"PaintLayer{i}", 'paintlayer') setLayerFromQImage(newPLayer, image) parentGroupLayer.addChildNode(newPLayer, None) infoObject = InfoObject(); infoObject.setProperty("color", colors[i]) selection = Selection(); selection.select(0, 0, dWidth, dHeight, 255) newFLayer = newDocument.createFillLayer(f"Color{i}", "color", infoObject, selection) parentGroupLayer.addChildNode(newFLayer, newPLayer) # mandatory as when provided to createFillLayer(), infoObject is not applied # must also be applied after node has been added to parent... newFLayer.setGenerator("color", infoObject) newFLayer.setBlendingMode('add') newLayer = newFLayer.mergeDown() # returned layer from merge can't be used, so get the last one currentProcessedLayer = parentGroupLayer.childNodes()[-1] currentProcessedLayer.setBlendingMode('multiply') =========================================================== Though other methods of Python API still have the same problems Git commit 39bf729d88e70168e1e9ce58cac08fcb5f11f6f3 by Dmitry Kazakov. Committed on 16/09/2020 at 12:19. Pushed by dkazakov into branch 'krita/4.3'. Fix KisGeneratorLayer support KisDelayedUpdateNodeInterface It is needed to make sure the layer is updated when some synchronous non-gui provoked actions are requested. E.g. saving or changing via python API. The path also fixes FillLayer's Pythong API to be synchronous using this fix. # Conflicts: # libs/libkis/FillLayer.cpp M +15 -0 libs/image/generator/kis_generator_layer.cpp M +7 -1 libs/image/generator/kis_generator_layer.h M +7 -0 libs/libkis/FillLayer.cpp https://invent.kde.org/graphics/krita/commit/39bf729d88e70168e1e9ce58cac08fcb5f11f6f3 Git commit 7be91fc9922182bf02a3fc95feb9462ae8948f72 by Dmitry Kazakov. Committed on 16/09/2020 at 12:20. Pushed by dkazakov into branch 'krita/4.3'. Fix Python API for Node::setBlendingMode() The function should use the command, run it in a stroke and wait for it to finish. That ensures that 1) updates are issued; 2) undo item is created; 3) no threading issues arise. M +9 -1 libs/libkis/Node.cpp https://invent.kde.org/graphics/krita/commit/7be91fc9922182bf02a3fc95feb9462ae8948f72 Git commit 7013fef0227028316c8788e828e28a66f026c08d by Dmitry Kazakov. Committed on 16/09/2020 at 12:20. Pushed by dkazakov into branch 'krita/4.3'. Fix Python API for Node::addChildNode() The function should use the command, run it in a stroke and wait for it to finish. That ensures that 1) updates are issued; 2) undo item is created; 3) no threading issues arise. M +12 -4 libs/libkis/Node.cpp https://invent.kde.org/graphics/krita/commit/7013fef0227028316c8788e828e28a66f026c08d Now it is just a bug, not a regression Reassigning back to Amyspark :) |