Refresh of the Painting Assistant Tool and Painting Assistants
Open, WishlistPublic

Description

This task is a collection of notes for several small to medium problems and possible solutions regarding painting assistants and the painting assistant tool. The idea is the consolidate all the necessary changes into a refreshed assistant tool. I feel like this is better than peppering small tweaks every minor release, and it would be a good look to have for the release of v5 :) Also perhaps it could lay the groundwork for more ambitious projects and improvements on painting assistants as a whole (eg T11345, T6543, Assistant Layers, Python API?, Animation?, etc)

The motivation for this is to make Krita's assistants more useful, particularly in the perspective drawing department.

My hope is for a refresh to achieve the following:

  • Encourage users who didn't use assistants to start using them
  • Encourage current users of assistants to use assistants more often than they already do
  • Help frequent users get more work done with assistants than they already do

These notes are based on the current stable release of Krita, v4.3 5.0.2 (a January 2022 revision by Tiar)

The Good

Functionally, most of the assistants are perfectly usable already. These assistants probably won't receive any user-visible changes

  • Ruler assistants and Spline assistants
  • Elliptical assistants
  • Vanishing Point assistant

The Bad

  • There ought to be some way to limit the area of effect for assistants, this will be very helpful for comic authors
  • Users want more assistants for various linear perspective drawing workflows
  • Assistant control panels hiding each other and other assistants' handles https://bugs.kde.org/show_bug.cgi?id=396979
    • [tiar] should be possible to do with the "editor position" in a variable instead of calculated; but it needs some smart thinking on the UI side (dragging the control panels by some recognizable icon)
  • No useful right-click menu unique to assistant tool -> but what should be there? [tiar 21.02.22]
  • No Shift-snapping during assistant creation https://bugs.kde.org/show_bug.cgi?id=406204
  • No mechanism to make assistants aware of each other / stitched together / aligned to each other / etc
    • Will be necessary for to align 2PP and 3PP assistants together
    • Necessary to align Perspective assistant with VP assistant
  • Assistant preview doesn't follow where the painting is happening on the canvas <- I don't understand what that means, so maybe it's already fixed/implemented. There is only a problem for non-painting tools. [tiar 21.02.22]
  • Can't select multiple assistants and operate on several at once
  • Ugly/confusing Tool Options, especially for local assistants
  • 4 pixel straight line at the beginning of the painting (visible with the ellipse assistant and the spline assistant)

Sumup and tasks (21.02.22):

  • Shift-snapping during assistant creation - https://invent.kde.org/graphics/krita/-/merge_requests/414
  • Make all assistants local-ized ???
  • Add 3pp assistant based on 2pp one (+ local, of course), and maybe even 1pp assistant
  • Movable control panels for assisstants
  • Assistants aware of each other/snapping to each other (can be turned on and off), esp. perspective + 2pp/vp
  • Tool Options needs to be divided into options for the currently selected assistants and for the assistant to be created. -> needs design
  • Select multiple assistants (with Shift, I guess?)
  • Local etc. options should work for existing assistants too (if possible)
  • Improved system/refactoring so there is no 4 pixels straight line at the beginning - https://phabricator.kde.org/T15304

The Ugly

Proposed Changes

Popup Palette / RMB menu

TODO (needs design, what is even needed there?)

Alternate actions

Assuming the configured alternate action key is Shift, we want specific helpful and documented things to happen when the user does the following when the assistant tool is active:

  • Shift-LMB-click: TODO
  • Shift-LMB-drag: TODO
  • Shift-LMB-move: TODO

https://invent.kde.org/graphics/krita/-/merge_requests/414 <- accepted MR that implemented some Shift behaviour, needs to be designed thoughtfully with that in mind

Suggestion: we need a way to select multiple assistants, snapping and shift-painting (like creating assistants perfectly horizontally)

Tool Options changes

Needs design.

Needs to separate options for currently selected assistants and options for the new assistant (the one that will be created when the user clicks on the canvas).

On-canvas editor widget changes

Worth refreshing the look of the editor widget, what with Krita on android and assistant undo now being a thing,

  • Assistants can only be selected by clicking one of their handles, if the user accidentally click-drags, they can just undo it
  • Only show widget for currently selected assistant
  • Fade out widgets for unselected assistants, but keep snapping status of the assistant (the middle button) visible
  • Make buttons bigger
  • Handles and side-handles will get displayed over faded-out widgets that belong to other assistants
  • Somehow make sure that you can actually click on handles when there is a control widget over it - maybe move the control widget? - better that than automatic... (tiar 21.02.22)
  • Alternate action: shift-click on snapping button causes all other assistants to disable snapping, if they haven't already
  • Alternate action: shift-click on deletes all other assistants
  • Alternate action: shift-drag on moving button drags a duplicate of the assistant

More linear perspective grid/drawing assistants

The Vanishing Point assistant is incredibly useful and handy on its own already, so there's little to be gained by having a dedicated "2 Point" assistant or a "3 Point" assistant that doesn't amount to anything more than just placing 3 normal vanishing point assistants.

So what I'm interested in introducing is a new set of "strict" perspective assistants that support a different kind of painting assistant workflow, where the user will be periodically tweaking the same assistant depending on what they are drawing. This workflow is in contrast to the usual one-and-done workflow where the assistant remains stationery for the rest of its useful existence.

These assistants will be "strict" in the sense that the tweaks the user makes to it isn't necessarily free-form, but follows very specific rules to maintain its own coherency:

  • 2PP Assistant: (done already)
    • Dragging either VP will cause the opposite VP to move in order to maintain the relative distortion levels around the center of vision
    • Dragging the center of vision is restricted to the horizon. Dragging it is also not advised
    • https://invent.kde.org/graphics/krita/-/merge_requests/390
    • https://www.geogebra.org/m/bqt5ghfn
    • Alternate action: Shift-drag vanishing point handle: reduce or increase size of "cone of vision", ie make VP handles closer or farther away from each other.
    • Alternate action: Shift-drag center of vision handle: automagically convert 2PP assistant to 3PP assistant when shift-dragging center of vision up/down
    • Tool Option: Toggle display of top plane / bottom plane
    • Tool Option: Toggle snapping towards each XYZ direction
    • Maybe put those toggles in RMB menu or editor widget?
  • 3PP Assistant:
    • https://www.geogebra.org/m/pcjdtny8
    • Tiar 21.02.22: I'm frankly not sure what to make out of it. What else do we need except for the exact same actions as 2pp + one vanishing point? (needs talking to windragon)
    • TODO

Rework Perspective assistant and clean it out of the assistant tool and assistant class

I think the Perspective assistant has a very specific use-case where it is incredibly useful, and that is when you're painting a landscape and need your grass brush to resize depending on where on the assistant it is being painted on is.

  • Remove ability to "drag out" another Perspective assistant from the "side handles"
  • Consolidate as much of the Perspective assistant logic out of the assistant tool and parent assistant class and into its own assistant class
  • Fix the weird lagginess
  • Allow user to adjust how many grid squares gets drawn
  • Allow user to drag out side handles to enlarge the grid while keeping VPs the same

Implement framework for "grouping" assistants or making complex assistants out of simple ones

Option 0: Brute Force

  • List out every possible combination of assistants that are genuinely useful for a specific use-case or workflow
  • Then literally just implement a dedicated frankenstien assistant that groups those more "primitive" assistants together
  • This seems to be the option used in Krita since there is already a 1pp assistant (Tiar 21.02.22)

Examples:

  • 2 VPs + 1 Parallel Ruler => 2PP Assistant
  • 3 VPs => 3PP Assistant
  • 3 isometric Parallel Rulers => Isometric Drawing Assistant
  • 2 perpendicular Parallel Rulers => Grid Drawing Assistant

Option 1: Assistant Manager widget

  • Something like the Layers docker but for assistants only
  • Maybe a docker? or just a table/list widget in the Tool Options
  • Allow multiple selection of assistants
  • Operations on selection of multiple assistants:
    • Make group
    • HIde group
    • Save group
    • etc

Option 2: extend the Compositions Docker

  • implement Assistant Compositions: saves the state of assistant visibility and assistant snapping
  • or maybe a checkbox that can make a new Layer Compositions that also saves assistant visibility/snapping

Option 3: extend the Layers Docker

  • Option A: implement an Assistant Layer type
  • Option B: allow assistants to somehow "belong" to specific layers

Option 4: Python API

  • Let scripters/users can figure out themselves how they want to manage assistants
  • Can possibly be generalized into a Canvas Decorations API (since assistants get displayed and manipulated as a canvas decoration/guide I think)
  • Frankly, I think this shouldn't be an option, but just another task (Tiar 21.02.22)

Make assistants painting smarter with OpenGL

All the information below are from Windragon.

  • maybe we should port assistants to QtQuick
  • would be nice if assistants produce and cache vertex arrays
  • QPainterPath is fine too, but we need to tesselate into triangles
  • the individual lines from assistants become meshes, formed by triangles, then the vertices are passed to the GPU
  • to some extent it already happens when you draw a QPainterPath onto QOpenGLPaintDevice, but it doesn't cache vertices (so it redoes the tesselation)
  • if we do tesselation and cache, it will be more efficient
NMaghfurUsman triaged this task as Wishlist priority.
NMaghfurUsman updated the task description. (Show Details)Jul 9 2020, 2:07 AM
NMaghfurUsman updated the task description. (Show Details)Jul 9 2020, 2:11 AM

Hey again. This all sounds good to me!

No useful right-click menu unique to assistant tool / Popup Palette / RMB menu

As things work right now each tool can return a QMenu, and if they don't we open the popup palette.
Personally, I think it would be nicer if any tool could return an arbitrary popup widget.

If you want to build out a simple QMenu for the assistants tool it shouldn't be a problem.
Returning a unique popup widget also shouldn't be a problem, though we'd have to make a few minor changes and it's something we should discuss.

No mechanism to make assistants aware of each other / stitched together / aligned to each other / etc

One of the things we discussed at the 2019 sprint was composition of assistants by creating an assistants tree (probably owned by the Assistants Tool, I think), where transformations and visibility would be relative to/inherited from the parent assistant.
This attempts to solve (a) building bigger more complex assistants out of simpler ones and (b) handling something like a comic page where you might have multiple compositions in one document, each with its own subtree of assistants.
Some decent assistant-to-assistant snapping would probably be a prerequisite to this though.

I think with your good 2-point an 3-point assistants it might not be as necessary to compose assistants in this way, but it might still be something to consider if it can be done in a way that doesn't make assistants too much more complicated to use.

Assuming the configured alternate action key is Shift, we want specific helpful and documented things to happen when the user does the following when the assistant tool is active:

Do you think these should be context-dependent, based on the currently selected assistant, or uniform across all assistant types?

(For example, one thing I thought when using your 2-Point assistant is that it might be nice to have a way to shift-click-drag (or whatever) one of the vanishing points to have them move towards or away from each other, changing the field-of-view/perspective distortion without using the little handles.
Something like this might be able to apply to a 3-Point assistant, but wouldn't be applicable to others.)

Assistants can only be selected by clicking one of their handles, if the user accidentally click-drags, they can just undo it
Only show widget for currently selected assistant

The only thing that bothers me about this idea is that right now I spend a lot of time "juggling" assistants by hiding one while working with another.
By hiding the helper widget for unselected assistants this becomes a bit more clunky, since you'd have to click on a control point first.
Of course, with your 2-Point and 3-Point assistants coming, this kind of bad workflow probably won't be as important, so it's probably not a big deal.
It's certainly worth a try. =]

Generally I can agree that we have a big issue with widgets overlapping each other as well as handles.

More linear perspective grid/drawing assistants 2PP/3PP

I'm all for these. The 2-Point one works really well, looks good and the code looks very clean, too.
I think the fact that they draw out a tiled "ground plane" is a killer upgrade on its own.

Rework Perspective assistant and clean it out of the assistant tool and assistant class

I haven't looked at the code, but there are certainly instances of occasional inheritance abuse throughout Krita where some things have been wrongly added to a base class and it doesn't get caught in review.
Cleaning this up is something I would prioritize, since a cleaner base class will make everybody's life easier, I think.

mwein added a subscriber: mwein.Jul 14 2020, 1:57 AM
  • Assistants can only be selected by clicking one of their handles, if the user accidentally click-drags, they can just undo it
  • Only show widget for currently selected assistant

I'm afraid that'd be rather annoying for me...
As mentioned by Emmet, just toggling visibility of assistants is a common action for me too.

And clicking without moving is pretty tricky with a stylus, so the undo is likely unless you switch to mouse just to toggle assistants.
I'm also concerned how far away the widget may show up, sounds like a lot of extra cursor miles...

Sure, some assistant manager could make such things convenient, but I'm slowly running out of ideas where to put yet another tab for quasi-mandatory dockers without having to switch several tabs for every tool change, so doing this on-canvas should not be a pain for the average use.

The widgets definitely could do with some smarter placement to avoid unnecessary overlap, but either way I'd prefer if there was a way to select an assistant without inevitably triggering one of its widget actions or grabbing a handle...

If you want to build out a simple QMenu for the assistants tool it shouldn't be a problem.
Returning a unique popup widget also shouldn't be a problem, though we'd have to make a few minor changes and it's something we should discuss.

I'm definitely leaning towards a simple QMenu to do simple things like duplicating an assistant, rotating assistant or some other very very simple transforms (re-using Transform Tool code/UI for this might be nice but it sounds complex ...)

One of the things we discussed at the 2019 sprint was composition of assistants by creating an assistants tree (probably owned by the Assistants Tool, I think), where transformations and visibility would be relative to/inherited from the parent assistant.
This attempts to solve (a) building bigger more complex assistants out of simpler ones and (b) handling something like a comic page where you might have multiple compositions in one document, each with its own subtree of assistants.
Some decent assistant-to-assistant snapping would probably be a prerequisite to this though.

I think with your good 2-point an 3-point assistants it might not be as necessary to compose assistants in this way, but it might still be something to consider if it can be done in a way that doesn't make assistants too much more complicated to use.

I actually once approached this problem of building complex groups of assistants out of individual assistants by implementing an Assistant Python API, and using python scripting to introduce the complexity and "smartness" to assistants. In fact my 2PP assistant started out exactly as a python script that manipulated Vanishing Point assistants with a really buggy Assistant API I made. I got far enough to make a usable proof of concept, but juggling SIP, C++, and Python and all the bugs I caused made my brain melt just to implement what I wanted, so I opted to do it in C++ only.

Indeed perhaps a generalized C++ solution to allow users to build complexity is the way to go.

What I had in mind to specifically address (b) was to actually re-use the Compositions docker: somehow make it assistant-aware, so each "composition" could be considered a group of assistants that the user can be perform actions on in specific ways.

https://docs.krita.org/en/reference_manual/dockers/compositions.html

A long term project I think, I don't actually use the Compositions docker myself or ever read its code ... but I'd be very interested in your thoughts on that because I think re-using that docker is a clever solution for the comic-panelling use-case in particular.

Do you think these should be context-dependent, based on the currently selected assistant, or uniform across all assistant types?

Yes in my mind alternate actions (shift-drag, shift-move, shift-click, etc) would be heavily context-dependent, not just on the assistant type but also which of the assistant handles is being interacted with.

It would need to be very thoroughly documented or discoverable ... I was thinking perhaps a tooltip or floating message should appear when shift is held, so the user knows what shift-actions are going to do for the assistant under the cursor. Your idea for 2PP is exactly the type of thing I was thinking.

Not to mentions there's other modifiers to exploit like Ctrl and Ctrl+Shift ... I think the various selection-making tools like lasso even use Alt to do specific things.

I'm not keen on completely revolutionizing the way the current set of assistants work, they're pretty simple and there's very little alternate actions could add for them. This framework (all of it: shift, ctrl, alt etc) is intended to be exploited by more complex assistants like my one, or any other assistants future contributors might be interested in adding to krita.

It might also be helpful for implementing a complexity-building UI along with a popup menu, eg ctrl-click to select several assistants at once. I could probably look into how other parts of krita implement multiple selection like that, eg the layer docker, so it's consistent with the rest of krita in some way.

The only thing that bothers me about this idea is that right now I spend a lot of time "juggling" assistants by hiding one while working with another.
By hiding the helper widget for unselected assistants this becomes a bit more clunky, since you'd have to click on a control point first.
Of course, with your 2-Point and 3-Point assistants coming, this kind of bad workflow probably won't be as important, so it's probably not a big deal.
It's certainly worth a try. =]

Generally I can agree that we have a big issue with widgets overlapping each other as well as handles.

You know I do kinda agree that it isn't an ideal proposal ... I'm on the fence about it. Something definitely has to be done to make it easier for the user to juggle many assistants that might obscure each other. I should investigate how other programs handle this hard-to-select stuff that's overlapping each other ... Inkscape I think has some clever solutions I think.

In any case I do think having the editor widgets of unselected assistants be at least semi-transparent is a step in the right direction.

The 2-Point one works really well, looks good and the code looks very clean, too.
I think the fact that they draw out a tiled "ground plane" is a killer upgrade on its own.

Thanks! That was the most tedious part. I might add more options in the Tool Options docker to toggle the Top Plane and Bottom Plane, maybe even how high/low they appear to be, need to figure out how to do that without complicate the assistant tool class too much.

I haven't looked at the code, but there are certainly instances of occasional inheritance abuse throughout Krita where some things have been wrongly added to a base class and it doesn't get caught in review.
Cleaning this up is something I would prioritize, since a cleaner base class will make everybody's life easier, I think.

Yes, the code is really really weird. Honestly if it were up to me, I would just delete the Perspective assistant out of krita entirely and hope nobody misses it. But it is the only thing that supports the Perspective brush sensors ...

rempt added a subscriber: rempt.Jul 14 2020, 2:49 PM

The performance problem of the perspective assistant probably is because we use QPainter's OpenGL engine to paint the lines.

Deevad added a subscriber: Deevad.Jul 15 2020, 8:47 AM
tymond updated the task description. (Show Details)May 27 2021, 11:19 PM
tymond updated the task description. (Show Details)Feb 21 2022, 10:19 PM
tymond updated the task description. (Show Details)Feb 21 2022, 11:06 PM
tymond added a subscriber: tymond.EditedFeb 21 2022, 11:37 PM

My thoughts/priorities regarding this task. (The subtitle says the priority, to make it easy I just assigned three, "Now", "Maybe now" and "Later").

Complex assistants (3pp, 1pp, isometric)

Now

  • 1pp and 3pp need to be done
  • 3pp: needs discussion, what would be different from 2pp + vp? This link was mentioned: https://www.geogebra.org/m/pcjdtny8 but I'm not sure if I understand how it would be used. To draw a perfect square?
  • 1pp is easy, but it would be good to have as useful preview as with 2pp, which means smart lines that show the depth
  • 3 isometric parallel rulers -> that would be nice, and useful (since then the preview will be more useful than the usual since it could look like isometric grid) (this should work nicely with isometric grid). But it's not a priority.

Perspective assistant

Later

Those tasks mentioned in the description make sense, but it's not really my priority to do so.
Maybe making sure Perspective works nicely with our other perspective-related assistants. Other than that, it will be further down the line.

Python API

Later

This would be good to have, but I'm not thinking of working on it right now. I'm not sure what would be the requirements.
Should users be able to create their own assistant types? Or just create new assistants from the types Krita already have? (It could still be useful, though, frankly, it's kind of like just having a template document...)

Control widget changes

Now

Needs to be done.

Tool Options changes

Now

Needs to be done.

Alternate Actions

Maybe now

Needs to be thought about, and maybe done.

RMB Menu

Maybe now

Not a priority, though maybe it will become, if I get a good idea for it that would improve usability a lot.

Refactor of the system (4px limitation)

Now

Needs to be done.

Smaller changes

Now

  • localize all assistants
  • assistants aware of each other (needs design, what with what)
  • select multiple assistants
  • move multiple assistants?
  • scale up/down all assistants?
  • select an assistant without moving (possibly just a button on the control widget?)

Needs to be done.

Smaller new functionalities

Later

I'm definitely leaning towards a simple QMenu to do simple things like duplicating an assistant, rotating assistant or some other very very simple transforms (re-using Transform Tool code/UI for this might be nice but it sounds complex ...)

  • make Perspective sensor in the brush respond to assistants (note: it might be quite difficult for vp, because there is no "maximum" distance (to have 100% for example size) (it is available trivially in Perspective), but that could be arranged somehow, I guess - maybe even as an option for the sensor, just like Distance sensor has the limit too).

Not my priority currently. But nice to have in the future.

Make assistants painting smarter with OpenGL

Now

Windragon seems to think it's important, it sould make assistants faster, and they are not the fastest thing in Krita, so it might be worth it.

Assistant Manager, Assistant Layer, Assistant Compositions, Assistant Tree

Maybe now

I think this idea needs revisiting, because there are plenty of those floating around but no conclusion or design.

In this Task, you see "Option 1: Assistant Manager", "Option 2: Compositions Docker", "Options 3: Extend Layers docker", there is also T11345 (Assistant Manager) and T1616 (Special Layer type for assistants).

Questions:

  1. What is the problem with current assistant management? (General)
  2. How each of those solutions solve the problem?
  3. What is the usecase for each of those solutions? Are they still valid in 5.0.2? (For example, someone mentioned Assistant Tree for comic creation; wouldn't local assistant solve the problem already?)

This will be a big change so should probably go hand in hand with refactoring to remove the 4px limitation. It would be good to have an answer and design ready sooner than later so I can start working on both.

tymond updated the task description. (Show Details)Feb 22 2022, 2:48 PM