Add ability of setting curve points as "corners"
This MR adds a new feature to the curves that allow to set individual points as "corners" (aka making the curve sharp at those points). The method replicates the way Photoshop handles this in the layer effects curves, instead of coming up with some new way of doing it. I find this method is better because it is just an extension of the current 1D cubic spline and it does not add new complex ways of manipulating the curve.
Changes explained by commit:
-
Change KisCubicCurve to use a new solve method based on Eigen: This commit changes the way the cubic spline is computed, using Eigen instead of a custom made solver. This makes it easier knowing what is going on and allows making changes easier (like adding the new feature). The computed cubic segments have a little error with respect of the old method, I guess due to floating point and order of operations (maybe). But that the maximum error I could get by testing was around 8.0e-16, so it is pretty negligible. The tests ran fine. Nevertheless, I added a new test that compares the old method with the new one, by computing the spline with both and then sampling them, and make it fail if they disagree within a 0.0000001 tolerance.
-
Add "set point as corner" feature to KisCubicCurve and refactor where needed: This modifies the new solver to take into account if the points are marked as "corners". It is a pretty simple change. An in-depth explanation can be read here (that is part of my research on PS blending options and layer styles). I had to change multiple files to accommodate for the changes
KisCubicCurve
, although those where simple changes. My main concern is with MyPaint engine because I don't know if the "corner" option should be stored. I leave it as before, storing only the position. The fact that curves in MyPaint are piece-wise linear confused me even more. The format for the string representation was also changed to include the new feature. If none of the points is set as corner then the string should be the same as before. I added the expected format specification as a comment:// Curve string format: a semi-colon separated list of point entries. // Previous point entry format: a pair of numbers, separated by a comma, // that represent the x and y coordinates of the point, in that order. // Examples: identity "0.0,0.0;1.0,1.0;" // U-shaped curve "0.0,1.0;0.5,0.0;1.0,1.0" // New point entry format: a list of comma separated point properties. The // first and second properties are required and should be numbers // that represent the x and y coordinates of the point, in that order. // After those, some optional properties/flags may be present or not. // If there are no optional properties for any point entry, then the // format of the string is identical to the old one. // Currently, only the "is_corner" flag is supported. All other // present optional properties are ignored. // Examples: identity "0.0,0.0;1.0,1.0;" // V-shaped curve "0.0,1.0;0.5,0.0,is_corner;1.0,1.0"
-
Add basic input for the "set point as corner" feature in KisCurveWidget: This adds 2 ways of toggling the points as corners: by selecting a point and pressing S. I chose this because there was already a functionality activated with A, but, as the comment there says, it would be better having this configurable. The other method is by presing Ctrl when clicking. If one clicks on a existing point then its corner status is toggled. If there are no point where clicked then a new one is added as expected, but set as corner.
Test Plan
I checked that the curves behave as expected in the curve filters, the brush mask fade option, the sensor curves. Everything seems to work, including saving/loading. But I think this is the main area that needs to be stressed before merging.
Formalities Checklist
-
I confirmed this builds. -
I confirmed Krita ran and the relevant functions work. -
I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!) -
I made sure my commits build individually and have good descriptions as per KDE guidelines. -
I made sure my code conforms to the standards set in the HACKING file. -
I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy. -
Does the patch add a user-visible feature? If yes, is there a documentation MR ready for it at Krita Documentation Repository?
Reminder: the reviewer is responsible for merging the patch, this is to ensure at the least two people can build the patch. In case a patch breaks the build, both the author and the reviewer should be contacted to fix the build. If this is not possible, the commits shall be reverted, and a notification with the reasoning and any relevant logs shall be sent to the mailing list, kimageshop@kde.org.