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

Fill tessellation and keeping track of vertex colour attributes for post-tessellation interpolation #488

Closed
mitchmindtree opened this issue Aug 4, 2019 · 3 comments

Comments

@mitchmindtree
Copy link

Hi @nical! I've been switching nannou's 2D tessellation over to lyon and it's been a joy to use! Thank you so much for all your work :)

One thing I'm currently struggling with is how to keep colour data associated with vertices during the fill tessellation process. E.g. Nannou provides an API for drawing a coloured polygon by submitting an iterator of coloured points, where the surface colour is linearly interpolated between each of the vertices (we get the interpolation "for free" in the fragment shader). The FillTessellator::tessellate_path method expects an iterator yielding PathEvents, which I can produce using the lyon::path::iterator::FromPolyline iterator adaptor around the user-submitted vertices, however in order to do so I have to drop the vertices' colour attribute and instead yield lyon points.

I've been able to work around this during stroke tessellation by using a custom GeometryBuilder to rebuild the colour types by retrieving the colour from a Cell<Color> that gets set each time next is called on the user-submitted vertex iterator, however I think I'm just getting lucky in this case as it seems that lyon's StrokeTessellator just happens to generate all vertices nearest each user submitted vertex while it takes them from the iterator. The FillTessellator on the other hand seems to consume all vertices before calling GeometryBuilder::add_vertex so my hack doesn't work in this case.

Any advice greatly appreciated! And thanks again for all your invaluable research and hard work :)

mitchmindtree added a commit to mitchmindtree/nannou that referenced this issue Aug 5, 2019
This adds a path drawing API that is a vastly more flexible and correct
version of the existing polyline and polygon APIs.

Allows for tessellating any given path with either lyon's
FillTessellator or the StrokeTessellator, with builder methods provided
for all the available options.

Colored vertices are currently only supported for stroke tessellation as
I'm currently unsure how to retain the color attributes for vertices
during the fill tessellation process (see nical/lyon#488).
@nical
Copy link
Owner

nical commented Aug 5, 2019

Hi!

This is by far the most requested feature and it's a little tricky because the fill tessellator has to insert new vertices (when there are self-intersections) and sometimes merges vertices that are at the same position.
I am currently rewriting the fill tessellator from scratch in order to address this and a few more fundamental issues of the current tessellator's design. The new tessellator will give you in the add_vertex hook a position and an iterator of "sources" which is the vertex's ID or the edge the vertex is on (described by the endpoint IDs) and how far along on the edge the point is.

Indeed the tessellator consumes the entire iterator before tessellating, because it has to sort all points from top to bottom (and from left to right for points with the same y coordinate). To make things worse, points are internally converted to 16.16 fixed-point numbers and the position you are given in add_vertex is converted back to floats so the values are not exactly the same as the original input which means you can't even use the position as a hash key to associate data later.

I'm making good progress on the new tessellator, but it isn't usable yet. I'm hoping to publish it towards the end of summer.
In the mean time I could try to bolt some kind of per-vertex ID in, it could be passed along with the positions while building the polygon and make it's way to the add_vertex hook. The problem with this is that I wouldn't be able to handle self-intersections and probably not be able to have a great answer for when points are merged, or to do these properly it would probably require enough work that waiting for the new tessellator would make more sense.
Also this solution would need a dedicated path building API rather than the PathBuilder/PathIterator facilities in place but I think that it's fine.

Let me know if this kind of incomplete solution would be valuable to you in the mean time.

@mitchmindtree
Copy link
Author

Thanks a lot for the detailed response!

Let me know if this kind of incomplete solution would be valuable to you in the mean time.

No worries at all @nical! We can absolutely live with the existing FillTessellator in the meantime, I'd much prefer to leave you to spend time on your new solution, but I really appreciate the gesture :)

mitchmindtree added a commit to mitchmindtree/nannou that referenced this issue Aug 6, 2019
This adds a path drawing API that is a vastly more flexible and correct
version of the existing polyline and polygon APIs.

Allows for tessellating any given path with either lyon's
FillTessellator or the StrokeTessellator, with builder methods provided
for all the available options.

Colored vertices are currently only supported for stroke tessellation as
I'm currently unsure how to retain the color attributes for vertices
during the fill tessellation process (see nical/lyon#488).
@nical
Copy link
Owner

nical commented Dec 23, 2019

The new tessellator in the master branch is now able to give information about which endpoint(s) of the input path a vertex comes from, or where in between several endpoints the vertex comes from if it was created as a result of self-intersection or curve flattening.

The new tessellator also has the ability to associate slices of floats to each endpoint and automatically interpolate them when needed, to simplify common use cases like per-vertex color or variable line width.

It took a while longer than I planned, sorry! Release coming in a few days.

@nical nical closed this as completed Dec 23, 2019
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

2 participants