[][src]Struct lyon_tessellation::FillTessellator

pub struct FillTessellator { /* fields omitted */ }

A Context object that can tessellate fill operations for complex paths.

Overview

The most important structure is FillTessellator. It implements the path fill tessellation algorithm which is by far the most advanced feature in all lyon crates.

The FillTessellator takes a FillEvents object and FillOptions as input. The former is an intermediate representation of the path, containing all edges sorted from top to bottom. FillOption contains some extra parameters (Some of which are not implemented yet).

The output of the tessellator is produced by the FillGeometryBuilder (see the geometry_builder documentation for more details about how tessellators produce their output geometry, and how to generate custom vertex layouts).

The tessellator's wiki page is a good place to learn more about how the tessellator's algorithm works. The source code also contains inline documentation for the adventurous who want to delve into more details.

Associating custom attributes with vertices.

It is sometimes useful to be able to link vertices generated by the tessellator back with the path's original data, for example to be able to add attributes that the tessellator does not know about (vertex color, texture coordinates, etc.).

The fill tessellator has two mechanisms to help with these advanced use cases. One is simple to use and one that, while more complicated to use, can cover advanced scenarios.

Before going delving into these mechanisms, it is important to understand that the vertices generated by the tessellator don't always correspond to the vertices existing in the original path.

  • Self-intersections, for example, introduce a new vertex where two edges meet.
  • When several vertices are at the same position, they are merged into a single vertex from the point of view of the tessellator.
  • The tessellator does not handle curves, and uses an approximation that introduces a number of line segments and therefeore endpoints between the original endpoints of any quadratic or cubic bézier curve.

This complicates the task of adding extra data to vertices without loosing the association during tessellation.

Vertex sources

This is the complicated, but most powerful mechanism. The tessellator keeps track of where each vertex comes from in the original path, and provides access to this information via an iterator of VertexSource in FillAttributes::sources.

It is most common for the vertex source iterator to yield a single VertexSource::Endpoint source, which happens when the vertex directly corresponds to an endpoint of the original path. More complicated cases can be expressed. For example if a vertex is inserted at an intersection halfway in the edge AB and two thirds of the way through edge BC, the source for this new vertex is VertexSource::Edge { from: A, to: B, t: 0.5 } and VertexSource::Edge { from: C, to: D, t: 0.666666 }` where A, B, C and D are endpoint IDs.

To use this feature, make sure to use FillTessellator::tessellate_with_ids instead of FillTessellator::tessellate.

Interpolated float attributes

Having to iterate over potentially several sources for each vertex can be cumbersome, in addition to having to deal with generating proper values for the attributes of vertices that were introduced at intersections or along curves.

In many scenarios, vertex attributes are made of floating point numbers and the most reasonable way to generate new attributes is to linearly interpolate these numbers between the endpoints of the edges they originate from.

Custom endpoint attributes are represented as &[f32] slices accessible via FillAttributes::interpolated_attributes. All vertices, whether they originate from a single endpoint or some more complex source, have exactly the same number of attributes. Without having to know about the meaning of attributes, the tessellator can either forward the slice of attributes from a provided AttributeStore when possible or generate the values via linear interpolation.

To use this feature, make sure to use FillTessellator::tessellate_path or FillTessellator::tessellate_with_ids instead of FillTessellator::tessellate.

Attributes are lazily computed when calling FillAttributes::interpolated_attributes. In other words they don't add overhead when not used, however it is best to avoid calling interpolated_attributes several times per vertex.

Examples

// Create a simple path.
let mut path_builder = Path::builder();
path_builder.move_to(point(0.0, 0.0));
path_builder.line_to(point(1.0, 2.0));
path_builder.line_to(point(2.0, 0.0));
path_builder.line_to(point(1.0, 1.0));
path_builder.close();
let path = path_builder.build();

// Create the destination vertex and index buffers.
let mut buffers: VertexBuffers<Point, u16> = VertexBuffers::new();

{
    let mut vertex_builder = simple_builder(&mut buffers);

    // Create the tessellator.
    let mut tessellator = FillTessellator::new();

    // Compute the tessellation.
    let result = tessellator.tessellate_path(
        &path,
        &FillOptions::default(),
        &mut vertex_builder
    );
    assert!(result.is_ok());
}

println!("The generated vertices are: {:?}.", &buffers.vertices[..]);
println!("The generated indices are: {:?}.", &buffers.indices[..]);
// Create a path with three custom endpoint attributes.
let mut path_builder = Path::builder_with_attributes(3);
path_builder.move_to(point(0.0, 0.0), &[0.0, 0.1, 0.5]);
path_builder.line_to(point(1.0, 2.0), &[1.0, 1.0, 0.1]);
path_builder.line_to(point(2.0, 0.0), &[1.0, 0.0, 0.8]);
path_builder.line_to(point(1.0, 1.0), &[0.1, 0.3, 0.5]);
path_builder.close();
let path = path_builder.build();

struct MyVertex {
    x: f32, y: f32,
    r: f32, g: f32, b: f32, a: f32,
}
// A custom vertex constructor, see the geometry_builder module.
struct Ctor;
impl FillVertexConstructor<MyVertex> for Ctor {
    fn new_vertex(&mut self, position: Point, mut attributes: FillAttributes) -> MyVertex {
        let attrs = attributes.interpolated_attributes();
        MyVertex {
            x: position.x,
            y: position.y,
            r: attrs[0],
            g: attrs[1],
            b: attrs[2],
            a: 1.0,
        }
    }
}

// Create the destination vertex and index buffers.
let mut buffers: VertexBuffers<MyVertex, u16> = VertexBuffers::new();

{
    // We use our custom vertex constructor here.
    let mut vertex_builder = BuffersBuilder::new(&mut buffers, Ctor);

    // Create the tessellator.
    let mut tessellator = FillTessellator::new();

    // Compute the tessellation. Here we use tessellate_with_ids
    // which has a slightlu more complicated interface. The provides
    // the iterator as well as storage for positions and attributes at
    // the same time.
    let result = tessellator.tessellate_with_ids(
        path.id_iter(), // Iterator over ids in the path
        &path,          // PositionStore
        Some(&path),    // AttributeStore
        &FillOptions::default(),
        &mut vertex_builder
    );
    assert!(result.is_ok());
}

Methods

impl FillTessellator[src]

pub fn new() -> Self[src]

Constructor.

pub fn tessellate(
    &mut self,
    path: impl IntoIterator<Item = PathEvent>,
    options: &FillOptions,
    output: &mut dyn FillGeometryBuilder
) -> TessellationResult
[src]

Compute the tessellation from a path iterator.

pub fn tessellate_with_ids(
    &mut self,
    path: impl IntoIterator<Item = IdEvent>,
    positions: &impl PositionStore,
    custom_attributes: Option<&dyn AttributeStore>,
    options: &FillOptions,
    output: &mut dyn FillGeometryBuilder
) -> TessellationResult
[src]

Compute the tessellation using an iterator over endpoint and control point ids, storage for the positions and, optionally, storage for custom endpoint attributes.

pub fn tessellate_path<'l>(
    &'l mut self,
    path: impl Into<PathSlice<'l>>,
    options: &'l FillOptions,
    builder: &'l mut dyn FillGeometryBuilder
) -> TessellationResult
[src]

Compute the tessellation from a path slice.

The tessellator will internally only track vertex sources and interpolated attributes if the path has interpolated attributes.

pub fn set_logging(&mut self, is_enabled: bool)[src]

Enable/disable some verbose logging during the tessellation, for debugging purposes.

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.