Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Would Skia PathOps in principle able to do subtraction _without_ implying "union" on the subject? #74

Closed
justvanrossum opened this issue Aug 1, 2024 · 18 comments

Comments

@justvanrossum
Copy link

Before:

image

After subtracting the selected shape from the rest:

image

It would be nice if it were possible to keep the overlaps in the subject shape.

@anthrotype
Copy link
Member

anthrotype commented Aug 1, 2024

I see what you mean, but it's not us (python bindings) who are doing that, we are just calling the Skia PathOps C++ API (Op function or SkOpBuilder class) for binary operations like difference or intersection.
I suspect the pre-semplification of each operands is needed to more easily perform the path operation by clearly distinguishing the two, I don't know.

@justvanrossum
Copy link
Author

but it's not us (python bindings)

I know that, but to ask a question to the Skia library community is a way higher threshold... A long shot, for sure.

@justvanrossum
Copy link
Author

Thank you for your response!

@anthrotype
Copy link
Member

no worries.. Yeah I know. Skia is a bit of a black box for us too 😅

Are you perhaps using OpBuilder?
I see that one is effectively calling Simplify for each subpath as well as at the end (upon resolve), see:
https://github.com/google/skia/blob/main/src/pathops/SkOpBuilder.cpp

Maybe you could try using the alternative op function (wrapper for the C++ Op function), and see if that changes the result?
I don't see Simplify being called repeatedly in here (but I have only skimmed this and haven't tried myself):
https://github.com/google/skia/blob/main/src/pathops/SkPathOpsOp.cpp

@justvanrossum
Copy link
Author

Interesting! I will try to study and understand that, thanks.

@anthrotype
Copy link
Member

anthrotype commented Aug 1, 2024

I mean this:

like used in here for the binary operations.py:

@justvanrossum
Copy link
Author

We're indeed using OpBuilder. Thanks for the pointer! Will report back.

@anthrotype
Copy link
Member

anthrotype commented Aug 1, 2024

in theory they should produce the same output, OpBuilder being more efficient when one wants to apply a chain of path operations, as opposed to just one Op between two sets of 'subject' and 'clip' contours.

@anthrotype
Copy link
Member

anthrotype commented Aug 1, 2024

It would also be interesting to see what booleanOperations do in this case. I tried to design skia-pathops interface to be a drop-in replacement for booleanOperations (in fact ufo2ft can select one or the other). The binary ops (difference, intersection, reverse_difference, xor) take two lists of contours respectively for subject and clip ('contours' are any objects with a draw(pen) method), whereas union only takes a single list. All operations also take a pen to output the result.

@justvanrossum
Copy link
Author

I've tried with booleanOperations in DrawBot, and it also seems to remove overlaps.

@justvanrossum
Copy link
Author

I've tried with the raw "op" method instead of OpBuilder: no difference.

@anthrotype
Copy link
Member

hm well it was worth a try. I don't think booleanOperations attempts to simplify the contours before processing the binary operations, so if that occurs it must be happening in the underlying Clipper library. Maybe it is in fact necessary for the algorithm to work.
If you want to avoid this you'd have to only pass the contours that you want to participate and exclude the ones you don't want to be modified, but I understand this is tricky for fontra from a UI/UX perspective.

@justvanrossum
Copy link
Author

It's not about not-participating paths: it could be self-overlapping, or two paths that overlap each other, and after subtraction of another shape could still be overlapping.

For example, before:
image

After:
image

For a designer, the fact that the two subject paths merge is unexpected.

@anthrotype
Copy link
Member

good point. Seems like a hard problem and I'm afraid I don't have a solution right now.

@justvanrossum
Copy link
Author

justvanrossum commented Aug 1, 2024

Thanks for thinking along. I posted a feature request for the future Kurbo path operations feature :)

@anthrotype
Copy link
Member

I posted a feature request for the future Kurbo path operations feature :)

good idea! This looks beyond my pay-grade but possibly within Raph's :)

I think at least for the case of multiple mutually overlapping subject contours (as in the screenshot) one may perform the difference operation using the same clip path for each distinct subject contour (as opposed to a group of subjects ) such that they will continue to stay distict instead of being merged with one another. However for a single self-overlapping subject contour, that would not work.

@justvanrossum
Copy link
Author

I think at least for the case of multiple mutually overlapping subject contours (as in the screenshot) one may perform the difference operation using the same clip path for each distinct subject contour

I was thinking of that as well, but it becomes hard when there are countershapes involved. I even tried this, with setting "fix direction" to False, but somehow failed to get the correct cut for the counter. Maybe I didn't try hard enough.

image

@adrientetar
Copy link
Member

I think at least for Skia, it doesn't care about keeping overlapping paths since it's a rendering library. The path simplification step that it does first probably simplifies the subsequent boolean op logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants