microsoft / Win2D

Win2D is an easy-to-use Windows Runtime API for immediate mode 2D graphics rendering with GPU acceleration. It is available to C#, C++ and VB developers writing apps for the Windows Universal Platform (UWP). It utilizes the power of Direct2D, and integrates seamlessly with XAML and CoreWindow.
http://microsoft.github.io/Win2D
Other
1.82k stars 287 forks source link

How to improve Erasure and storage of ink? #620

Closed Ponant closed 6 years ago

Ponant commented 6 years ago

Hi, I have a few related questions which are quite important as I have a few artists using my app and they face issues which seem to me difficult to solve with the current api.

Problem 1: Many artists are drawing strokes over strokes, for instance they start with a blue stroke filling a large region and latter on they apply some yellow on top. In this case there are quite a few blue strokes which become useless as they are not seen. When their work is saved, though, the isf files account for these hidden strokes, and hence get unnecessarily large. This make the save and load ink methods take too much time. Further more, as the user erases on such files, the system often hangs because there are too many inkstrokes at a given point of contact pen-surface. This limitation is also seen with windows 10 sketchpad, I could crash it on several occasions by just erasing over a sketch that has many strokes (circa 2MB of gif file containing only pressure sensitive strokes).

So I wonder if there is an api in Win2d which allows me to intersect strokes and detect if some are hidden, after which I can decide to just delete them?

Problem 2: I just have no clue on how I could implement a partial stroke eraser. I could try to hit test and use the inkstrokebuilder but I wonder if Win2D does not have a more clever approach. Almost half of my artists are drawing superlong strokes, so they panic when they erase. Furthermore, the erasure does not take into account a sort of Z-Index, such that everything which seems to be below the contact point is erased.

Problem 3: I am introducing layer in my app, ideally I would like to be able to select all strokes on a given inkcanvas and draw not a bounding rect but a shape which takes only the outermost strokes (just like a sticker). Is that possible?

Thank you,

shawnhar commented 6 years ago

For very large collections of ink, you might want to rasterize them into bitmap format and save this as image data rather than geometric ink.

The expense of operating on bitmap data is proportional to the number of pixels, while the expense of geometric data is proportional to the amount of geometry. As the latter goes up, image based approaches are increasingly likely to be more efficient.

To erase part of a stroke, you could rebuild a partial stroke itself using the inking APIs, or if you switch to a bitmap representation you could do this in Win2D using typical paint program style eraser tools.

I don't understand your third question. Could you give an example?

Ponant commented 6 years ago

Hi @shawnhar , Thanks for your answers; I was hoping for better solutions because my app is vector based only, so I need to avoid bitmaps.

So, there is no way in the api to detect if a stroke is entirely hidden by other strokes? In this case I would just delete it.

For you question, please ignore my third question I found a better and easier workaround. The other two are the most important.

shawnhar commented 6 years ago

If you cannot use bitmaps, you will have to accept that rendering performance will decrease linearly as the amount of ink you are drawing goes up.

You can convert ink strokes to geometry for more general manipulation, as long as you aren't using pencil strokes. Pencil cannot be converted to geometry, but is also not fully opaque so never entirely occludes anything.