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

lyon 2D tessellation integration - Fixes many 2D bugs, adds support for stroke tessellation, Paths, curves and more. #375

Merged
merged 21 commits into from
Aug 10, 2019

Conversation

mitchmindtree
Copy link
Member

@mitchmindtree mitchmindtree commented Aug 3, 2019

This overhauls the Draw APIs tessellation approach to take advantage of the lyon crate.

Highlights of the PR include:

  • A new geom::path() API has been added that allows for building 2D vector graphics paths as an iterator yielding lyon::path::PathEvents. This adds support for curves, arcs, sub-paths and more.
  • A draw.path() API has been added to allow for taking advantage of paths via the Draw API. draw.path().stroke() produces a path that will be rendered via stroke tessellation, draw.path().fill() produces a path that will be rendered via fill tessellation.
  • The draw.polyline() and draw.line() APIs are now implemented in terms of draw.path().stroke().
  • All known polyline bugs should be fixed. Closes Polyline bugs - strange behaviour at extreme join angles, freezes on 1 point #185. Closes Polyline flashing with weird shapes #281. Closes Polyline with caps_round() #335.
  • draw.polygon() has been updated to use lyon's FillTessellator allowing for concave shapes. Closes Polygon and convexity? #245. Closes Allow for concave polygons via draw.polygon() #246.
  • draw.polygon() now supports optional stroke tessellation of its outline and includes a suite of stroke option builder methods including line join types, stroke weight, stroke color, etc. See the SetStroke method docs to find all new methods now available.
  • .no_fill() and .stroke(color) can be called on all polygon types to indicate that no fill tessellation is required or to specify stroke color respectively.
  • All other draw API polygons (rect, quad, tri, ellipse) have been implemented in terms of draw.polygon(), allowing them to take advantage of the same stroke tessellation options. Closes Add an .outline() method to some Draw types using polyline geometry. #167.
  • The line thickness methods have been replaced with stroke_weight and weight methods.
  • Fixes a pretty severe bug where any draw primitives that use the intermediary mesh would produce incorrect triangulation indices if they weren't the first instance to be created.

Regressions as a result of this PR include:

  • draw.polygon() will temporarily lose support for individually colored vertices. This is due to limitations with lyon's FillTessellator, however these are in the process of being addressed. See Fill tessellation and keeping track of vertex colour attributes for post-tessellation interpolation nical/lyon#488.
  • draw.tri() and draw.quad() now expect Point2s instead of Point3s. This was a trade-off in order to take advantage of the lyon tessellators which only support 2D geometry. Currently, the draw API's 3D story is very limited anyway, and this can likely be revisited as a part of a larger 3D tessellation overhaul. For now, draw.mesh() can still be used for drawing arbitrary 3D via the draw API.

As a side note, these new stroke tessellation features should open up the ability to implement a lot of the remaining nature of code examples! #86.

Closes #253.
Closes #371.

The next focus for the Draw API should likely be #194, but that can be addressed in a future PR.

@mitchmindtree
Copy link
Member Author

Looks like travis is just failing due to rustfmt missing from the latest nightly toolchain but will be fixed in the next rust-lang/rust#62805.

@mitchmindtree mitchmindtree changed the title lyon 2D tessellation integration WIP - polyline tessellation overhaul lyon 2D tessellation integration WIP Aug 4, 2019
This is a working WIP that replaces the old polyline implementation with
lyon's polyline tessellation.

The following commits will continue to replace the tessellation
approaches of all 2D shapes in favour of lyon tessellation.

Closes nannou-org#185.
Closes nannou-org#281.
Closes nannou-org#335.
Provides a simplified, nannou-friendly API to common items within the
lyon::path module. This will be useful for composing paths that may be
used with the upcoming `draw.path()` API.

Also adds a suite of conversions for lyon point and vector types making
interop a little easier.
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).
The stroke and fill builder methods are now genericly available for any
type containing a respective `StrokeOptions` or `FillOptions` field.

The `draw.ellipse()` API has been updated to take advantage of this,
providing a new `draw.stroke(color)` method along with a suite of stroke
tessellation options.

Some methods have been added to `Theme` in order to make it easier to
retrieve colors for draw primitives.
This fixes a bug where when more than one polyline, path or mesh were
drawn the indices inserted into the primary draw mesh would be
incorrectly offset for all but the first primitive.

This draw `Line` implementation has been simplified as a thin
abstraction around the `Path` primitive.

Also updates `Path` so that orientation, position and coloring methods
can also be specified during the tessellation options building stage.
These originally played an important role in line and polyline
tessellation, prior to the integration of lyon. It's usage within nannou
has largely been made redundant by lyon's path type.

Some of the line functions like `triangles`, `contains`, etc may still
be useful in some cases, but could likely be better implemented in a
more correct manner using the new `path` module in the future.
The `draw.polygon()` API now supports specifying both fill and stroke
tessellation simultaneously. All stroke options are now accessible as
builder methods. The stroke colour can be specified via
`.stroke(color)`.

This new polygon implementation will be used to simplify the ellipse,
tri, rect and quad implementations.
This also adds support for stroke tessellation to each of these
primitives.

Unfortunately, this has also resulted in `quad` and `tri` losing support
for 3-dimensional points. However, this is likely better addressed in
the future when we come up with a proper 3D tessellation pipeline
similar to lyon and some sort of ambient lighting to help visualise 3D
geometry.
@mitchmindtree mitchmindtree changed the title lyon 2D tessellation integration WIP lyon 2D tessellation integration - Fixes many 2D bugs, adds support for stroke tessellation, Paths, curves and more. Aug 10, 2019
@mitchmindtree mitchmindtree merged commit cffe68b into nannou-org:master Aug 10, 2019
@mitchmindtree mitchmindtree deleted the lyon branch August 10, 2019 21:44
mitchmindtree added a commit to mitchmindtree/nannou that referenced this pull request Sep 17, 2019
The main features of this version are:

- Integrate lyon! Fixes many 2D bugs and adds a `Path` API. nannou-org#375
- Add a `text` module and `draw.text("foo")` API. nannou-org#388
- Adds a `notosans` feature to guarantee a default, fallback font.
- Many new examples have been added and old ones improved. nannou-org#394 nannou-org#391
- Fixes a bug where shaderc would not build on some linux distros. nannou-org#386
- Fixes a bug where `app.draw()` couldn't be used in multiple windows.

Feel free to check out the CHANGELOG for some more details!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment