Full Code of olson-sean-k/plexus for AI

master b4e4a4b0fb09 cached
73 files
640.4 KB
197.6k tokens
1716 symbols
1 requests
Download .txt
Showing preview only (668K chars total). Download the full file or copy to clipboard to get everything.
Repository: olson-sean-k/plexus
Branch: master
Commit: b4e4a4b0fb09
Files: 73
Total size: 640.4 KB

Directory structure:
gitextract_cu48aqwt/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── continuous-integration.yml
├── .gitignore
├── Cargo.toml
├── LICENSE
├── README.md
├── benches/
│   └── subdivide.rs
├── data/
│   ├── cube.ply
│   ├── plexus.ply
│   └── teapot.ply
├── doc/
│   └── katex-header.html
├── examples/
│   ├── sphere/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── main.rs
│   ├── subdivide/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── main.rs
│   └── teapot/
│       ├── Cargo.toml
│       └── src/
│           └── main.rs
├── pictor/
│   ├── Cargo.toml
│   └── src/
│       ├── camera.rs
│       ├── harness.rs
│       ├── lib.rs
│       ├── pipeline.rs
│       ├── renderer.rs
│       ├── shader.glsl.frag
│       ├── shader.glsl.vert
│       ├── shader.spv.frag
│       └── shader.spv.vert
├── plexus/
│   ├── Cargo.toml
│   └── src/
│       ├── buffer/
│       │   ├── builder.rs
│       │   └── mod.rs
│       ├── builder.rs
│       ├── constant.rs
│       ├── encoding/
│       │   ├── mod.rs
│       │   └── ply.rs
│       ├── entity/
│       │   ├── borrow.rs
│       │   ├── dijkstra.rs
│       │   ├── mod.rs
│       │   ├── storage/
│       │   │   ├── hash.rs
│       │   │   └── mod.rs
│       │   ├── traverse.rs
│       │   └── view.rs
│       ├── geometry/
│       │   ├── mod.rs
│       │   └── partition.rs
│       ├── graph/
│       │   ├── builder.rs
│       │   ├── core.rs
│       │   ├── data.rs
│       │   ├── edge.rs
│       │   ├── face.rs
│       │   ├── geometry.rs
│       │   ├── mod.rs
│       │   ├── mutation/
│       │   │   ├── edge.rs
│       │   │   ├── face.rs
│       │   │   ├── mod.rs
│       │   │   ├── path.rs
│       │   │   └── vertex.rs
│       │   ├── path.rs
│       │   └── vertex.rs
│       ├── index.rs
│       ├── integration/
│       │   ├── cgmath.rs
│       │   ├── glam.rs
│       │   ├── mint.rs
│       │   ├── mod.rs
│       │   ├── nalgebra.rs
│       │   └── ultraviolet.rs
│       ├── lib.rs
│       ├── primitive/
│       │   ├── cube.rs
│       │   ├── decompose.rs
│       │   ├── generate.rs
│       │   ├── mod.rs
│       │   └── sphere.rs
│       └── transact.rs
├── rustdoc.sh
└── rustfmt.toml

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "cargo"
    directory: "/"
    schedule:
      interval: "monthly"


================================================
FILE: .github/workflows/continuous-integration.yml
================================================
name: CI
on: [pull_request, push]
jobs:
  rustfmt:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: nightly
          override: true
          components: rustfmt
      - uses: actions-rs/cargo@v1
        with:
          command: fmt
          args: --all -- --check
  clippy:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: stable
          override: true
          components: clippy
      - uses: actions-rs/cargo@v1
        with:
          command: clippy
          args: --all-features --all-targets -- -D clippy::all
  test:
    name: Test
    needs: [clippy, rustfmt]
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [macOS-latest, ubuntu-latest, windows-latest]
        toolchain:
          - 1.81.0 # Minimum.
          - stable
          - beta
          - nightly
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.toolchain }}
          override: true
      - uses: actions-rs/cargo@v1
        with:
          command: test
          args: --manifest-path=plexus/Cargo.toml --features geometry-nalgebra --no-default-features --verbose
      - uses: actions-rs/cargo@v1
        with:
          command: test
          args: --manifest-path=plexus/Cargo.toml --all-features --verbose


================================================
FILE: .gitignore
================================================
.idea/
target/
**/*.rs.bk
*.iml
Cargo.lock


================================================
FILE: Cargo.toml
================================================
[workspace]
members = [
    "examples/sphere",
    "examples/subdivide",
    "examples/teapot",
    "pictor",
    "plexus",
]
resolver = "2"


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: README.md
================================================
<div align="center">
    <img alt="Plexus" src="https://raw.githubusercontent.com/olson-sean-k/plexus/master/doc/plexus.svg?sanitize=true" width="320"/>
</div>
<br/>

**Plexus** is a highly composable Rust library for polygonal mesh processing.
See [the website][website] for the most recent [API documentation][rustdoc] and
the [user guide][guide].

[![GitHub](https://img.shields.io/badge/GitHub-olson--sean--k/plexus-8da0cb?logo=github&style=for-the-badge)](https://github.com/olson-sean-k/plexus)
[![docs.rs](https://img.shields.io/badge/docs.rs-plexus-66c2a5?logo=rust&style=for-the-badge)](https://docs.rs/plexus)
[![crates.io](https://img.shields.io/crates/v/plexus.svg?logo=rust&style=for-the-badge)](https://crates.io/crates/plexus)
[![Gitter](https://img.shields.io/badge/Gitter-plexus--rs-c266a5?logo=gitter&style=for-the-badge)](https://gitter.im/plexus-rs/community)

## Primitives

Plexus provides primitive topological structures that can be composed using
generators and iterator expressions. Iterator expressions operate over a
sequence of polygons with arbitrary vertex data. These polygons can be
decomposed, tessellated, indexed, and collected into mesh data structures.

```rust
use decorum::R64; // See "Integrations".
use nalgebra::Point3;
use plexus::buffer::MeshBuffer;
use plexus::index::Flat3;
use plexus::prelude::*;
use plexus::primitive::generate::Position;
use plexus::primitive::sphere::UvSphere;

use crate::render::pipeline::{Color4, Vertex};

type E3 = Point3<R64>;

// Create a buffer of index and vertex data from a uv-sphere.
let buffer: MeshBuffer<Flat3, Vertex> = UvSphere::new(16, 8)
    .polygons::<Position<E3>>()
    .map_vertices(|position| Vertex::new(position, Color4::white()))
    .triangulate()
    .collect();
```

The above example uses a generator and iterator expression to transform the
positional data of a sphere into a linear buffer for indexed drawing. See [the
sphere example][example-sphere] for a rendered demonstration.

## Half-Edge Graphs

The `MeshGraph` type represents polygonal meshes as an ergonomic [half-edge
graph][dcel] that supports arbitrary data in vertices, arcs (half-edges), edges,
and faces. Graphs can be traversed and manipulated in many ways that iterator
expressions and linear buffers cannot.

```rust
use plexus::graph::MeshGraph;
use plexus::prelude::*;
use plexus::primitive::Tetragon;
use ultraviolet::vec::Vec3;

type E3 = Vec3;

// Create a graph of a tetragon.
let mut graph = MeshGraph::<E3>::from(Tetragon::from([
    (1.0, 1.0, 0.0),
    (-1.0, 1.0, 0.0),
    (-1.0, -1.0, 0.0),
    (1.0, -1.0, 0.0),
]));
// Extrude the face of the tetragon.
let key = graph.faces().next().unwrap().key();
let face = graph.face_mut(key).unwrap().extrude_with_offset(1.0).unwrap();
```

Plexus avoids exposing very basic topological operations like inserting
individual vertices into a graph, because they can easily be done incorrectly.
Instead, graphs are typically manipulated with more abstract operations like
merging and splitting.

See [the user guide][guide-graphs] for more details about graphs.

## Geometric Traits

Plexus provides optional traits to support spatial operations by exposing
positional data in vertices. If the data exposed by the `AsPosition` trait
supports these geometric traits, then geometric operations become available in
primitive and mesh data structure APIs.

```rust
use glam::Vec3A;
use plexus::geometry::{AsPosition, Vector};
use plexus::graph::GraphData;
use plexus::prelude::*;

type E3 = Vec3A;

#[derive(Clone, Copy, PartialEq)]
pub struct Vertex {
    pub position: E3,
    pub normal: Vector<E3>,
}

impl GraphData for Vertex {
    type Vertex = Self;
    type Arc = ();
    type Edge = ();
    type Face = ();
}

impl AsPosition for Vertex {
    type Position = E3;

    fn as_position(&self) -> &Self::Position {
        &self.position
    }
}
```

Data structures like `MeshGraph` also provide functions that allow user code to
compute geometry without requiring any of these traits; the data in these
structures may be arbitrary, including no data at all.

## Integrations

Plexus integrates with the [`theon`] crate to provide geometric traits and
support various mathematics crates in the Rust ecosystem. Any mathematics crate
can be used and, if it is supported by Theon, Plexus provides geometric APIs by
enabling Cargo features.

| Feature                | Default | Crate           |
|------------------------|---------|-----------------|
| `geometry-cgmath`      | No      | [`cgmath`]      |
| `geometry-glam`        | No      | [`glam`]        |
| `geometry-mint`        | No      | [`mint`]        |
| `geometry-nalgebra`    | No      | [`nalgebra`]    |
| `geometry-ultraviolet` | No      | [`ultraviolet`] |

Enabling the corresponding feature is recommended if using one of these
supported crates.

Plexus also integrates with the [`decorum`] crate for floating-point
representations that can be hashed for fast indexing. The `R64` type is a
(totally ordered) real number with an `f64` representation that cannot be `NaN`
nor infinity, for example. Geometric conversion traits are implemented for
supported types to allow for implicit conversions of scalar types.

## Encodings

Plexus provides support for polygonal mesh encodings. This allows mesh data
structures like `MeshGraph` and `MeshBuffer` to be serialized and deserialized
to and from various formats.

```rust
use nalgebra::Point3;
use plexus::encoding::ply::{FromPly, PositionEncoding};
use plexus::graph::MeshGraph;
use plexus::prelude::*;
use std::fs::File;

type E3 = Point3<f64>;

let ply = File::open("cube.ply").unwrap();
let encoding = PositionEncoding::<E3>::default();
let (graph, _) = MeshGraph::<E3>::from_ply(encoding, ply).unwrap();
```

Encoding support is optional and enabled via Cargo features.

| Feature        | Default | Encoding | Read | Write |
|----------------|---------|----------|------|-------|
| `encoding-ply` | No      | PLY      | Yes  | No    |

See [the teapot example][example-teapot] for a rendered demonstration of reading
a mesh from the file system.

[dcel]: https://en.wikipedia.org/wiki/doubly_connected_edge_list

[guide]: https://plexus.rs/user-guide/getting-started
[guide-graphs]: https://plexus.rs/user-guide/graphs
[rustdoc]: https://plexus.rs/rustdoc/plexus
[website]: https://plexus.rs

[example-sphere]: https://github.com/olson-sean-k/plexus/tree/master/examples/sphere/src/main.rs
[example-teapot]: https://github.com/olson-sean-k/plexus/tree/master/examples/teapot/src/main.rs

[`cgmath`]: https://crates.io/crates/cgmath
[`decorum`]: https://crates.io/crates/decorum
[`glam`]: https://crates.io/crates/glam
[`mint`]: https://crates.io/crates/mint
[`nalgebra`]: https://crates.io/crates/nalgebra
[`theon`]: https://crates.io/crates/theon
[`ultraviolet`]: https://crates.io/crates/ultraviolet


================================================
FILE: benches/subdivide.rs
================================================
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use nalgebra::Point3;
use plexus::geometry::AsPositionMut;
use plexus::graph::{EdgeMidpoint, FaceView, GraphData, MeshGraph};
use plexus::prelude::*;
use plexus::primitive::Tetragon;
use smallvec::SmallVec;

const DEPTH: usize = 8;

type E3 = Point3<f64>;

pub trait Ambo<G> {
    #[must_use]
    fn ambo(self) -> Self;
}

impl<G> Ambo<G> for FaceView<&'_ mut MeshGraph<G>>
where
    G: EdgeMidpoint + GraphData,
    G::Vertex: AsPositionMut,
{
    // Subdivide the face with a polygon formed from vertices at the midpoints
    // of the edges of the face.
    fn ambo(self) -> Self {
        // Split each edge, stashing the vertex key and moving to the next arc.
        let arity = self.arity();
        let mut arc = self.into_arc();
        let mut splits = SmallVec::<[_; 4]>::with_capacity(arity);
        for _ in 0..arity {
            let vertex = arc.split_at_midpoint();
            splits.push(vertex.key());
            arc = vertex.into_outgoing_arc().into_next_arc();
        }
        // Split faces along the vertices from each arc split.
        let mut face = arc.into_face().unwrap();
        for (a, b) in splits.into_iter().perimeter() {
            face = face.split(a, b).unwrap().into_face().unwrap();
        }
        // Return the face forming the similar polygon.
        face
    }
}

fn tetragon() -> MeshGraph<E3> {
    // Create a graph from a tetragon.
    MeshGraph::from(Tetragon::from([
        (1.0, 0.0, -1.0),
        (-1.0, 0.0, -1.0),
        (-1.0, 0.0, 1.0),
        (1.0, 0.0, 1.0),
    ]))
}

fn subdivide(mut graph: MeshGraph<E3>) {
    // Get the face of the tetragon.
    let key = graph.faces().next().unwrap().key();
    let mut face = graph.face_mut(key).unwrap();

    // Subdivide and extrude the face repeatedly.
    for _ in 0..DEPTH {
        face = face.ambo().extrude_with_offset(0.5).unwrap();
    }
}

fn benchmark(criterion: &mut Criterion) {
    criterion.bench_function("subdivide", move |bencher| {
        bencher.iter_batched(tetragon, subdivide, BatchSize::SmallInput)
    });
}

criterion_group!(benches, benchmark);
criterion_main!(benches);


================================================
FILE: data/cube.ply
================================================
ply
format ascii 1.0
element vertex 8
property float x
property float y
property float z
element face 6
property list uint8 uint32 vertex_index
end_header
0 0 0
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0


================================================
FILE: data/plexus.ply
================================================
ply
format ascii 1.0
comment 0 1 3 4 5 10 12 14 20 21 27 28 35 36 43 44 53 54
element vertex 55
property float x
property float y
property float z
element face 56
property list uint8 uint32 vertex_index
end_header
0 1 0
-2 0 0
0 0 0
2 0 0
2 -1 0
0 -2 0
-2 -1 0
-2 -3 0
0 -4 0
-2 -5 0
0 -6 0
-2 -7 0
0 -8 0
-2 -9 0
0 -10 0
2 -7 0
4 -6 0
2 -5 0
6 -5 0
4 -4 0
8 -4 0
6 -3 0
8 -2 0
6 -1 0
8 0 0
6 1 0
8 2 0
6 2 0
8 3 0
6 3 0
6 4 0
4 3 0
4 5 0
2 4 0
2 6 0
0 7 0
0 5 0
-2 6 0
-2 4 0
-4 5 0
-4 3 0
-6 4 0
-6 3 0
-6 2 0
-8 3 0
-6 1 0
-8 2 0
-6 -1 0
-8 0 0
-6 -3 0
-8 -2 0
-6 -5 0
-8 -4 0
-6 -7 0
-8 -6 0
3 4 2 5
3 3 2 4
3 3 0 2
3 0 1 2
3 2 1 6
3 2 6 5
3 5 6 7
3 5 7 8
3 8 7 9
3 8 9 10
3 10 9 11
3 10 11 12
3 12 11 13
3 12 13 14
3 15 10 12
3 17 10 15
3 16 17 15
3 19 17 16
3 18 19 16
3 21 19 18
3 20 21 18
3 22 21 20
3 22 23 21
3 24 23 22
3 24 25 23
3 26 25 24
3 26 27 25
3 26 29 27
3 28 29 26
3 28 30 29
3 29 31 27
3 30 31 29
3 30 32 31
3 32 33 31
3 32 34 33
3 34 36 33
3 34 35 36
3 35 37 36
3 36 37 38
3 37 39 38
3 38 39 40
3 39 41 40
3 40 41 42
3 40 42 43
3 41 44 42
3 42 44 46
3 42 46 43
3 43 46 45
3 45 46 48
3 45 48 47
3 47 48 50
3 47 50 49
3 49 50 52
3 49 52 51
3 51 52 54
3 51 54 53


================================================
FILE: data/teapot.ply
================================================
ply
format ascii 1.0
element vertex 1177
property float32 x
property float32 y
property float32 z
element face 2256
property list uint8 uint32 vertex_index
end_header
1.38137 0 2.45469
1.4 0 2.4
1.35074 -0.375926 2.4
1.33276 -0.370922 2.45469
1.38426 0 2.4875
1.33555 -0.371699 2.4875
1.40312 0 2.49844
1.35376 -0.376765 2.49844
1.43241 0 2.4875
1.38201 -0.384628 2.4875
1.46655 0 2.45469
1.41495 -0.393796 2.45469
1.5 0 2.4
1.44722 -0.402778 2.4
1.21126 -0.711407 2.4
1.19514 -0.701938 2.45469
1.19764 -0.703409 2.4875
1.21396 -0.712995 2.49844
1.2393 -0.727875 2.4875
1.26884 -0.745225 2.45469
1.29778 -0.762222 2.4
0.994 -0.994 2.4
0.98077 -0.98077 2.45469
0.982824 -0.982824 2.4875
0.996219 -0.996219 2.49844
1.01701 -1.01701 2.4875
1.04125 -1.04125 2.45469
1.065 -1.065 2.4
0.711407 -1.21126 2.4
0.701938 -1.19514 2.45469
0.703409 -1.19764 2.4875
0.712995 -1.21396 2.49844
0.727875 -1.2393 2.4875
0.745225 -1.26884 2.45469
0.762222 -1.29778 2.4
0.375926 -1.35074 2.4
0.370922 -1.33276 2.45469
0.371699 -1.33555 2.4875
0.376765 -1.35376 2.49844
0.384628 -1.38201 2.4875
0.393796 -1.41495 2.45469
0.402778 -1.44722 2.4
0 -1.4 2.4
0 -1.38137 2.45469
0 -1.38426 2.4875
0 -1.40312 2.49844
0 -1.43241 2.4875
0 -1.46655 2.45469
0 -1.5 2.4
-0.375926 -1.35074 2.4
-0.370922 -1.33276 2.45469
-0.371699 -1.33555 2.4875
-0.376765 -1.35376 2.49844
-0.384628 -1.38201 2.4875
-0.393796 -1.41495 2.45469
-0.402778 -1.44722 2.4
-0.711407 -1.21126 2.4
-0.701938 -1.19514 2.45469
-0.703409 -1.19764 2.4875
-0.712995 -1.21396 2.49844
-0.727875 -1.2393 2.4875
-0.745225 -1.26884 2.45469
-0.762222 -1.29778 2.4
-0.994 -0.994 2.4
-0.98077 -0.98077 2.45469
-0.982824 -0.982824 2.4875
-0.996219 -0.996219 2.49844
-1.01701 -1.01701 2.4875
-1.04125 -1.04125 2.45469
-1.065 -1.065 2.4
-1.21126 -0.711407 2.4
-1.19514 -0.701938 2.45469
-1.19764 -0.703409 2.4875
-1.21396 -0.712995 2.49844
-1.2393 -0.727875 2.4875
-1.26884 -0.745225 2.45469
-1.29778 -0.762222 2.4
-1.35074 -0.375926 2.4
-1.33276 -0.370922 2.45469
-1.33555 -0.371699 2.4875
-1.35376 -0.376765 2.49844
-1.38201 -0.384628 2.4875
-1.41495 -0.393796 2.45469
-1.44722 -0.402778 2.4
-1.4 0 2.4
-1.38137 0 2.45469
-1.38426 0 2.4875
-1.40312 0 2.49844
-1.43241 0 2.4875
-1.46655 0 2.45469
-1.5 0 2.4
-1.35074 0.375926 2.4
-1.33276 0.370922 2.45469
-1.33555 0.371699 2.4875
-1.35376 0.376765 2.49844
-1.38201 0.384628 2.4875
-1.41495 0.393796 2.45469
-1.44722 0.402778 2.4
-1.21126 0.711407 2.4
-1.19514 0.701938 2.45469
-1.19764 0.703409 2.4875
-1.21396 0.712995 2.49844
-1.2393 0.727875 2.4875
-1.26884 0.745225 2.45469
-1.29778 0.762222 2.4
-0.994 0.994 2.4
-0.98077 0.98077 2.45469
-0.982824 0.982824 2.4875
-0.996219 0.996219 2.49844
-1.01701 1.01701 2.4875
-1.04125 1.04125 2.45469
-1.065 1.065 2.4
-0.711407 1.21126 2.4
-0.701938 1.19514 2.45469
-0.703409 1.19764 2.4875
-0.712995 1.21396 2.49844
-0.727875 1.2393 2.4875
-0.745225 1.26884 2.45469
-0.762222 1.29778 2.4
-0.375926 1.35074 2.4
-0.370922 1.33276 2.45469
-0.371699 1.33555 2.4875
-0.376765 1.35376 2.49844
-0.384628 1.38201 2.4875
-0.393796 1.41495 2.45469
-0.402778 1.44722 2.4
0 1.4 2.4
0 1.38137 2.45469
0 1.38426 2.4875
0 1.40312 2.49844
0 1.43241 2.4875
0 1.46655 2.45469
0 1.5 2.4
0.375926 1.35074 2.4
0.370922 1.33276 2.45469
0.371699 1.33555 2.4875
0.376765 1.35376 2.49844
0.384628 1.38201 2.4875
0.393796 1.41495 2.45469
0.402778 1.44722 2.4
0.711407 1.21126 2.4
0.701938 1.19514 2.45469
0.703409 1.19764 2.4875
0.712995 1.21396 2.49844
0.727875 1.2393 2.4875
0.745225 1.26884 2.45469
0.762222 1.29778 2.4
0.994 0.994 2.4
0.98077 0.98077 2.45469
0.982824 0.982824 2.4875
0.996219 0.996219 2.49844
1.01701 1.01701 2.4875
1.04125 1.04125 2.45469
1.065 1.065 2.4
1.21126 0.711407 2.4
1.19514 0.701938 2.45469
1.19764 0.703409 2.4875
1.21396 0.712995 2.49844
1.2393 0.727875 2.4875
1.26884 0.745225 2.45469
1.29778 0.762222 2.4
1.35074 0.375926 2.4
1.33276 0.370922 2.45469
1.33555 0.371699 2.4875
1.35376 0.376765 2.49844
1.38201 0.384628 2.4875
1.41495 0.393796 2.45469
1.44722 0.402778 2.4
1.62384 0 2.13785
1.56671 -0.436032 2.13785
1.74074 0 1.87778
1.67949 -0.467421 1.87778
1.84375 0 1.62187
1.77888 -0.495081 1.62188
1.92593 0 1.37222
1.85816 -0.517147 1.37222
1.98032 0 1.1309
1.91065 -0.531754 1.1309
2 0 0.9
1.92963 -0.537037 0.9
1.40492 -0.825153 2.13785
1.50606 -0.884554 1.87778
1.59519 -0.936898 1.62188
1.66628 -0.978656 1.37222
1.71335 -1.0063 1.1309
1.73037 -1.0163 0.9
1.15293 -1.15293 2.13785
1.23593 -1.23593 1.87778
1.30906 -1.30906 1.62187
1.36741 -1.36741 1.37222
1.40603 -1.40603 1.1309
1.42 -1.42 0.9
0.825153 -1.40492 2.13785
0.884554 -1.50606 1.87778
0.936898 -1.59519 1.62188
0.978656 -1.66628 1.37222
1.0063 -1.71335 1.1309
1.0163 -1.73037 0.9
0.436032 -1.56671 2.13785
0.467421 -1.67949 1.87778
0.495081 -1.77888 1.62187
0.517147 -1.85816 1.37222
0.531754 -1.91065 1.1309
0.537037 -1.92963 0.9
0 -1.62384 2.13785
0 -1.74074 1.87778
0 -1.84375 1.62187
0 -1.92593 1.37222
0 -1.98032 1.1309
0 -2 0.9
-0.436032 -1.56671 2.13785
-0.467421 -1.67949 1.87778
-0.495081 -1.77888 1.62188
-0.517147 -1.85816 1.37222
-0.531754 -1.91065 1.1309
-0.537037 -1.92963 0.9
-0.825153 -1.40492 2.13785
-0.884554 -1.50606 1.87778
-0.936898 -1.59519 1.62188
-0.978656 -1.66628 1.37222
-1.0063 -1.71335 1.1309
-1.0163 -1.73037 0.9
-1.15293 -1.15293 2.13785
-1.23593 -1.23593 1.87778
-1.30906 -1.30906 1.62187
-1.36741 -1.36741 1.37222
-1.40603 -1.40603 1.1309
-1.42 -1.42 0.9
-1.40492 -0.825153 2.13785
-1.50606 -0.884554 1.87778
-1.59519 -0.936898 1.62188
-1.66628 -0.978656 1.37222
-1.71335 -1.0063 1.1309
-1.73037 -1.0163 0.9
-1.56671 -0.436032 2.13785
-1.67949 -0.467421 1.87778
-1.77888 -0.495081 1.62187
-1.85816 -0.517147 1.37222
-1.91065 -0.531754 1.1309
-1.92963 -0.537037 0.9
-1.62384 0 2.13785
-1.74074 0 1.87778
-1.84375 0 1.62187
-1.92593 0 1.37222
-1.98032 0 1.1309
-2 0 0.9
-1.56671 0.436032 2.13785
-1.67949 0.467421 1.87778
-1.77888 0.495081 1.62188
-1.85816 0.517147 1.37222
-1.91065 0.531754 1.1309
-1.92963 0.537037 0.9
-1.40492 0.825153 2.13785
-1.50606 0.884554 1.87778
-1.59519 0.936898 1.62188
-1.66628 0.978656 1.37222
-1.71335 1.0063 1.1309
-1.73037 1.0163 0.9
-1.15293 1.15293 2.13785
-1.23593 1.23593 1.87778
-1.30906 1.30906 1.62187
-1.36741 1.36741 1.37222
-1.40603 1.40603 1.1309
-1.42 1.42 0.9
-0.825153 1.40492 2.13785
-0.884554 1.50606 1.87778
-0.936898 1.59519 1.62188
-0.978656 1.66628 1.37222
-1.0063 1.71335 1.1309
-1.0163 1.73037 0.9
-0.436032 1.56671 2.13785
-0.467421 1.67949 1.87778
-0.495081 1.77888 1.62187
-0.517147 1.85816 1.37222
-0.531754 1.91065 1.1309
-0.537037 1.92963 0.9
0 1.62384 2.13785
0 1.74074 1.87778
0 1.84375 1.62187
0 1.92593 1.37222
0 1.98032 1.1309
0 2 0.9
0.436032 1.56671 2.13785
0.467421 1.67949 1.87778
0.495081 1.77888 1.62188
0.517147 1.85816 1.37222
0.531754 1.91065 1.1309
0.537037 1.92963 0.9
0.825153 1.40492 2.13785
0.884554 1.50606 1.87778
0.936898 1.59519 1.62188
0.978656 1.66628 1.37222
1.0063 1.71335 1.1309
1.0163 1.73037 0.9
1.15293 1.15293 2.13785
1.23593 1.23593 1.87778
1.30906 1.30906 1.62187
1.36741 1.36741 1.37222
1.40603 1.40603 1.1309
1.42 1.42 0.9
1.40492 0.825153 2.13785
1.50606 0.884554 1.87778
1.59519 0.936898 1.62188
1.66628 0.978656 1.37222
1.71335 1.0063 1.1309
1.73037 1.0163 0.9
1.56671 0.436032 2.13785
1.67949 0.467421 1.87778
1.77888 0.495081 1.62187
1.85816 0.517147 1.37222
1.91065 0.531754 1.1309
1.92963 0.537037 0.9
1.96296 0 0.693403
1.8939 -0.527092 0.693403
1.87037 0 0.522222
1.80456 -0.502229 0.522222
1.75 0 0.384375
1.68843 -0.469907 0.384375
1.62963 0 0.277778
1.57229 -0.437586 0.277778
1.53704 0 0.200347
1.48296 -0.412723 0.200347
1.5 0 0.15
1.44722 -0.402778 0.15
1.69833 -0.997476 0.693403
1.61822 -0.950425 0.522222
1.51407 -0.889259 0.384375
1.40993 -0.828093 0.277778
1.32982 -0.781043 0.200347
1.29778 -0.762222 0.15
1.3937 -1.3937 0.693403
1.32796 -1.32796 0.522222
1.2425 -1.2425 0.384375
1.15704 -1.15704 0.277778
1.0913 -1.0913 0.200347
1.065 -1.065 0.15
0.997476 -1.69833 0.693403
0.950425 -1.61822 0.522222
0.889259 -1.51407 0.384375
0.828093 -1.40993 0.277778
0.781043 -1.32982 0.200347
0.762222 -1.29778 0.15
0.527092 -1.8939 0.693403
0.502229 -1.80456 0.522222
0.469907 -1.68843 0.384375
0.437586 -1.57229 0.277778
0.412723 -1.48296 0.200347
0.402778 -1.44722 0.15
0 -1.96296 0.693403
0 -1.87037 0.522222
0 -1.75 0.384375
0 -1.62963 0.277778
0 -1.53704 0.200347
0 -1.5 0.15
-0.527092 -1.8939 0.693403
-0.502229 -1.80456 0.522222
-0.469907 -1.68843 0.384375
-0.437586 -1.57229 0.277778
-0.412723 -1.48296 0.200347
-0.402778 -1.44722 0.15
-0.997476 -1.69833 0.693403
-0.950425 -1.61822 0.522222
-0.889259 -1.51407 0.384375
-0.828093 -1.40993 0.277778
-0.781043 -1.32982 0.200347
-0.762222 -1.29778 0.15
-1.3937 -1.3937 0.693403
-1.32796 -1.32796 0.522222
-1.2425 -1.2425 0.384375
-1.15704 -1.15704 0.277778
-1.0913 -1.0913 0.200347
-1.065 -1.065 0.15
-1.69833 -0.997476 0.693403
-1.61822 -0.950425 0.522222
-1.51407 -0.889259 0.384375
-1.40993 -0.828093 0.277778
-1.32982 -0.781043 0.200347
-1.29778 -0.762222 0.15
-1.8939 -0.527092 0.693403
-1.80456 -0.502229 0.522222
-1.68843 -0.469907 0.384375
-1.57229 -0.437586 0.277778
-1.48296 -0.412723 0.200347
-1.44722 -0.402778 0.15
-1.96296 0 0.693403
-1.87037 0 0.522222
-1.75 0 0.384375
-1.62963 0 0.277778
-1.53704 0 0.200347
-1.5 0 0.15
-1.8939 0.527092 0.693403
-1.80456 0.502229 0.522222
-1.68843 0.469907 0.384375
-1.57229 0.437586 0.277778
-1.48296 0.412723 0.200347
-1.44722 0.402778 0.15
-1.69833 0.997476 0.693403
-1.61822 0.950425 0.522222
-1.51407 0.889259 0.384375
-1.40993 0.828093 0.277778
-1.32982 0.781043 0.200347
-1.29778 0.762222 0.15
-1.3937 1.3937 0.693403
-1.32796 1.32796 0.522222
-1.2425 1.2425 0.384375
-1.15704 1.15704 0.277778
-1.0913 1.0913 0.200347
-1.065 1.065 0.15
-0.997476 1.69833 0.693403
-0.950425 1.61822 0.522222
-0.889259 1.51407 0.384375
-0.828093 1.40993 0.277778
-0.781043 1.32982 0.200347
-0.762222 1.29778 0.15
-0.527092 1.8939 0.693403
-0.502229 1.80456 0.522222
-0.469907 1.68843 0.384375
-0.437586 1.57229 0.277778
-0.412723 1.48296 0.200347
-0.402778 1.44722 0.15
0 1.96296 0.693403
0 1.87037 0.522222
0 1.75 0.384375
0 1.62963 0.277778
0 1.53704 0.200347
0 1.5 0.15
0.527092 1.8939 0.693403
0.502229 1.80456 0.522222
0.469907 1.68843 0.384375
0.437586 1.57229 0.277778
0.412723 1.48296 0.200347
0.402778 1.44722 0.15
0.997476 1.69833 0.693403
0.950425 1.61822 0.522222
0.889259 1.51407 0.384375
0.828093 1.40993 0.277778
0.781043 1.32982 0.200347
0.762222 1.29778 0.15
1.3937 1.3937 0.693403
1.32796 1.32796 0.522222
1.2425 1.2425 0.384375
1.15704 1.15704 0.277778
1.0913 1.0913 0.200347
1.065 1.065 0.15
1.69833 0.997476 0.693403
1.61822 0.950425 0.522222
1.51407 0.889259 0.384375
1.40993 0.828093 0.277778
1.32982 0.781043 0.200347
1.29778 0.762222 0.15
1.8939 0.527092 0.693403
1.80456 0.502229 0.522222
1.68843 0.469907 0.384375
1.57229 0.437586 0.277778
1.48296 0.412723 0.200347
1.44722 0.402778 0.15
0.605903 0 0.005903
0 0 0
0.584584 0.162696 0.005903
1.02222 0 0.022222
0.986255 0.274486 0.022222
1.28437 0 0.046875
1.23918 0.344878 0.046875
1.42778 0 0.077778
1.37754 0.383385 0.077778
1.48785 0 0.112847
1.4355 0.399515 0.112847
0.524218 0.307888 0.005903
0.884412 0.51944 0.022222
1.11122 0.652653 0.046875
1.23529 0.725523 0.077778
1.28726 0.756047 0.112847
0.430191 0.430191 0.005903
0.725778 0.725778 0.022222
0.911906 0.911906 0.046875
1.01372 1.01372 0.077778
1.05637 1.05637 0.112847
0.307888 0.524218 0.005903
0.51944 0.884412 0.022222
0.652653 1.11122 0.046875
0.725523 1.23529 0.077778
0.756047 1.28726 0.112847
0.162696 0.584584 0.005903
0.274486 0.986255 0.022222
0.344878 1.23918 0.046875
0.383385 1.37754 0.077778
0.399515 1.4355 0.112847
0 0.605903 0.005903
0 1.02222 0.022222
0 1.28437 0.046875
0 1.42778 0.077778
0 1.48785 0.112847
-0.162696 0.584584 0.005903
-0.274486 0.986255 0.022222
-0.344878 1.23918 0.046875
-0.383385 1.37754 0.077778
-0.399515 1.4355 0.112847
-0.307888 0.524218 0.005903
-0.51944 0.884412 0.022222
-0.652653 1.11122 0.046875
-0.725523 1.23529 0.077778
-0.756047 1.28726 0.112847
-0.430191 0.430191 0.005903
-0.725778 0.725778 0.022222
-0.911906 0.911906 0.046875
-1.01372 1.01372 0.077778
-1.05637 1.05637 0.112847
-0.524218 0.307888 0.005903
-0.884412 0.51944 0.022222
-1.11122 0.652653 0.046875
-1.23529 0.725523 0.077778
-1.28726 0.756047 0.112847
-0.584584 0.162696 0.005903
-0.986255 0.274486 0.022222
-1.23918 0.344878 0.046875
-1.37754 0.383385 0.077778
-1.4355 0.399515 0.112847
-0.605903 0 0.005903
-1.02222 0 0.022222
-1.28437 0 0.046875
-1.42778 0 0.077778
-1.48785 0 0.112847
-0.584584 -0.162696 0.005903
-0.986255 -0.274486 0.022222
-1.23918 -0.344878 0.046875
-1.37754 -0.383385 0.077778
-1.4355 -0.399515 0.112847
-0.524218 -0.307888 0.005903
-0.884412 -0.51944 0.022222
-1.11122 -0.652653 0.046875
-1.23529 -0.725523 0.077778
-1.28726 -0.756047 0.112847
-0.430191 -0.430191 0.005903
-0.725778 -0.725778 0.022222
-0.911906 -0.911906 0.046875
-1.01372 -1.01372 0.077778
-1.05637 -1.05637 0.112847
-0.307888 -0.524218 0.005903
-0.51944 -0.884412 0.022222
-0.652653 -1.11122 0.046875
-0.725523 -1.23529 0.077778
-0.756047 -1.28726 0.112847
-0.162696 -0.584584 0.005903
-0.274486 -0.986255 0.022222
-0.344878 -1.23918 0.046875
-0.383385 -1.37754 0.077778
-0.399515 -1.4355 0.112847
0 -0.605903 0.005903
0 -1.02222 0.022222
0 -1.28437 0.046875
0 -1.42778 0.077778
0 -1.48785 0.112847
0.162696 -0.584584 0.005903
0.274486 -0.986255 0.022222
0.344878 -1.23918 0.046875
0.383385 -1.37754 0.077778
0.399515 -1.4355 0.112847
0.307888 -0.524218 0.005903
0.51944 -0.884412 0.022222
0.652653 -1.11122 0.046875
0.725523 -1.23529 0.077778
0.756047 -1.28726 0.112847
0.430191 -0.430191 0.005903
0.725778 -0.725778 0.022222
0.911906 -0.911906 0.046875
1.01372 -1.01372 0.077778
1.05637 -1.05637 0.112847
0.524218 -0.307888 0.005903
0.884412 -0.51944 0.022222
1.11122 -0.652653 0.046875
1.23529 -0.725523 0.077778
1.28726 -0.756047 0.112847
0.584584 -0.162696 0.005903
0.986255 -0.274486 0.022222
1.23918 -0.344878 0.046875
1.37754 -0.383385 0.077778
1.4355 -0.399515 0.112847
0.2 0 2.7
0.171296 0 2.78542
0.165279 -0.046045 2.78542
0.192963 -0.053704 2.7
0.148234 -0.087106 2.78542
0.173037 -0.10163 2.7
0.121672 -0.121672 2.78542
0.142 -0.142 2.7
0.087106 -0.148234 2.78542
0.10163 -0.173037 2.7
0.046045 -0.165279 2.78542
0.053704 -0.192963 2.7
0 -0.171296 2.78542
0 -0.2 2.7
-0.046045 -0.165279 2.78542
-0.053704 -0.192963 2.7
-0.087106 -0.148234 2.78542
-0.10163 -0.173037 2.7
-0.121672 -0.121672 2.78542
-0.142 -0.142 2.7
-0.148234 -0.087106 2.78542
-0.173037 -0.10163 2.7
-0.165279 -0.046045 2.78542
-0.192963 -0.053704 2.7
-0.171296 0 2.78542
-0.2 0 2.7
-0.165279 0.046045 2.78542
-0.192963 0.053704 2.7
-0.148234 0.087106 2.78542
-0.173037 0.10163 2.7
-0.121672 0.121672 2.78542
-0.142 0.142 2.7
-0.087106 0.148234 2.78542
-0.10163 0.173037 2.7
-0.046045 0.165279 2.78542
-0.053704 0.192963 2.7
0 0.171296 2.78542
0 0.2 2.7
0.046045 0.165279 2.78542
0.053704 0.192963 2.7
0.087106 0.148234 2.78542
0.10163 0.173037 2.7
0.121672 0.121672 2.78542
0.142 0.142 2.7
0.148234 0.087106 2.78542
0.173037 0.10163 2.7
0.165279 0.046045 2.78542
0.192963 0.053704 2.7
0.350926 0 2.63611
0.338579 -0.09423 2.63611
0.574074 0 2.58889
0.553875 -0.15415 2.58889
0.825 0 2.55
0.795972 -0.221528 2.55
1.05926 0 2.51111
1.02199 -0.284431 2.51111
1.23241 0 2.46389
1.18904 -0.330924 2.46389
1.3 0 2.4
1.25426 -0.349074 2.4
0.303616 -0.178322 2.63611
0.49668 -0.291715 2.58889
0.713778 -0.419222 2.55
0.916455 -0.538261 2.51111
1.06626 -0.626246 2.46389
1.12474 -0.660593 2.4
0.249157 -0.249157 2.63611
0.407593 -0.407593 2.58889
0.58575 -0.58575 2.55
0.752074 -0.752074 2.51111
0.875009 -0.875009 2.46389
0.923 -0.923 2.4
0.178322 -0.303616 2.63611
0.291715 -0.49668 2.58889
0.419222 -0.713778 2.55
0.538261 -0.916455 2.51111
0.626246 -1.06626 2.46389
0.660593 -1.12474 2.4
0.09423 -0.338579 2.63611
0.15415 -0.553875 2.58889
0.221528 -0.795972 2.55
0.284431 -1.02199 2.51111
0.330924 -1.18904 2.46389
0.349074 -1.25426 2.4
0 -0.350926 2.63611
0 -0.574074 2.58889
0 -0.825 2.55
0 -1.05926 2.51111
0 -1.23241 2.46389
0 -1.3 2.4
-0.09423 -0.338579 2.63611
-0.15415 -0.553875 2.58889
-0.221528 -0.795972 2.55
-0.284431 -1.02199 2.51111
-0.330924 -1.18904 2.46389
-0.349074 -1.25426 2.4
-0.178322 -0.303616 2.63611
-0.291715 -0.49668 2.58889
-0.419222 -0.713778 2.55
-0.538261 -0.916455 2.51111
-0.626246 -1.06626 2.46389
-0.660593 -1.12474 2.4
-0.249157 -0.249157 2.63611
-0.407593 -0.407593 2.58889
-0.58575 -0.58575 2.55
-0.752074 -0.752074 2.51111
-0.875009 -0.875009 2.46389
-0.923 -0.923 2.4
-0.303616 -0.178322 2.63611
-0.49668 -0.291715 2.58889
-0.713778 -0.419222 2.55
-0.916455 -0.538261 2.51111
-1.06626 -0.626246 2.46389
-1.12474 -0.660593 2.4
-0.338579 -0.09423 2.63611
-0.553875 -0.15415 2.58889
-0.795972 -0.221528 2.55
-1.02199 -0.284431 2.51111
-1.18904 -0.330924 2.46389
-1.25426 -0.349074 2.4
-0.350926 0 2.63611
-0.574074 0 2.58889
-0.825 0 2.55
-1.05926 0 2.51111
-1.23241 0 2.46389
-1.3 0 2.4
-0.338579 0.09423 2.63611
-0.553875 0.15415 2.58889
-0.795972 0.221528 2.55
-1.02199 0.284431 2.51111
-1.18904 0.330924 2.46389
-1.25426 0.349074 2.4
-0.303616 0.178322 2.63611
-0.49668 0.291715 2.58889
-0.713778 0.419222 2.55
-0.916455 0.538261 2.51111
-1.06626 0.626246 2.46389
-1.12474 0.660593 2.4
-0.249157 0.249157 2.63611
-0.407593 0.407593 2.58889
-0.58575 0.58575 2.55
-0.752074 0.752074 2.51111
-0.875009 0.875009 2.46389
-0.923 0.923 2.4
-0.178322 0.303616 2.63611
-0.291715 0.49668 2.58889
-0.419222 0.713778 2.55
-0.538261 0.916455 2.51111
-0.626246 1.06626 2.46389
-0.660593 1.12474 2.4
-0.09423 0.338579 2.63611
-0.15415 0.553875 2.58889
-0.221528 0.795972 2.55
-0.284431 1.02199 2.51111
-0.330924 1.18904 2.46389
-0.349074 1.25426 2.4
0 0.350926 2.63611
0 0.574074 2.58889
0 0.825 2.55
0 1.05926 2.51111
0 1.23241 2.46389
0 1.3 2.4
0.09423 0.338579 2.63611
0.15415 0.553875 2.58889
0.221528 0.795972 2.55
0.284431 1.02199 2.51111
0.330924 1.18904 2.46389
0.349074 1.25426 2.4
0.178322 0.303616 2.63611
0.291715 0.49668 2.58889
0.419222 0.713778 2.55
0.538261 0.916455 2.51111
0.626246 1.06626 2.46389
0.660593 1.12474 2.4
0.249157 0.249157 2.63611
0.407593 0.407593 2.58889
0.58575 0.58575 2.55
0.752074 0.752074 2.51111
0.875009 0.875009 2.46389
0.923 0.923 2.4
0.303616 0.178322 2.63611
0.49668 0.291715 2.58889
0.713778 0.419222 2.55
0.916455 0.538261 2.51111
1.06626 0.626246 2.46389
1.12474 0.660593 2.4
0.338579 0.09423 2.63611
0.553875 0.15415 2.58889
0.795972 0.221528 2.55
1.02199 0.284431 2.51111
1.18904 0.330924 2.46389
1.25426 0.349074 2.4
-1.92454 0 2.02396
-1.6 0 2.025
-1.59259 -0.125 2.04167
-1.92704 -0.125 2.04055
-2.1963 0 2.01667
-2.20645 -0.125 2.03272
-2.4125 0 1.99687
-2.42824 -0.125 2.01146
-2.57037 0 1.95833
-2.58985 -0.125 1.97006
-2.66713 0 1.89479
-2.6887 -0.125 1.90181
-2.7 0 1.8
-2.72222 -0.125 1.8
-1.57407 -0.2 2.08333
-1.9333 -0.2 2.08202
-2.23182 -0.2 2.07284
-2.46759 -0.2 2.04792
-2.63855 -0.2 1.99938
-2.74263 -0.2 1.91937
-2.77778 -0.2 1.8
-1.55 -0.225 2.1375
-1.94144 -0.225 2.13594
-2.26481 -0.225 2.125
-2.51875 -0.225 2.09531
-2.70185 -0.225 2.0375
-2.81273 -0.225 1.94219
-2.85 -0.225 1.8
-1.52593 -0.2 2.19167
-1.94957 -0.2 2.18985
-2.29781 -0.2 2.17716
-2.56991 -0.2 2.14271
-2.76516 -0.2 2.07562
-2.88284 -0.2 1.96501
-2.92222 -0.2 1.8
-1.50741 -0.125 2.23333
-1.95583 -0.125 2.23133
-2.32318 -0.125 2.21728
-2.60926 -0.125 2.17917
-2.81385 -0.125 2.10494
-2.93676 -0.125 1.98256
-2.97778 -0.125 1.8
-1.5 0 2.25
-1.95833 0 2.24792
-2.33333 0 2.23333
-2.625 0 2.19375
-2.83333 0 2.11667
-2.95833 0 1.98958
-3 0 1.8
-1.50741 0.125 2.23333
-1.95583 0.125 2.23133
-2.32318 0.125 2.21728
-2.60926 0.125 2.17917
-2.81385 0.125 2.10494
-2.93676 0.125 1.98256
-2.97778 0.125 1.8
-1.52593 0.2 2.19167
-1.94957 0.2 2.18985
-2.29781 0.2 2.17716
-2.56991 0.2 2.14271
-2.76516 0.2 2.07562
-2.88284 0.2 1.96501
-2.92222 0.2 1.8
-1.55 0.225 2.1375
-1.94144 0.225 2.13594
-2.26481 0.225 2.125
-2.51875 0.225 2.09531
-2.70185 0.225 2.0375
-2.81273 0.225 1.94219
-2.85 0.225 1.8
-1.57407 0.2 2.08333
-1.9333 0.2 2.08202
-2.23182 0.2 2.07284
-2.46759 0.2 2.04792
-2.63855 0.2 1.99938
-2.74263 0.2 1.91937
-2.77778 0.2 1.8
-1.59259 0.125 2.04167
-1.92704 0.125 2.04055
-2.20645 0.125 2.03272
-2.42824 0.125 2.01146
-2.58985 0.125 1.97006
-2.6887 0.125 1.90181
-2.72222 0.125 1.8
-2.68287 0 1.67083
-2.70418 -0.125 1.66398
-2.62963 0 1.51667
-2.64829 -0.125 1.50535
-2.5375 0 1.35
-2.55185 -0.125 1.33576
-2.4037 0 1.18333
-2.41221 -0.125 1.16687
-2.22546 0 1.02917
-2.22668 -0.125 1.01033
-1.99259 -0.125 0.877778
-2.75747 -0.2 1.64684
-2.69492 -0.2 1.47706
-2.58773 -0.2 1.30017
-2.43347 -0.2 1.12572
-2.22972 -0.2 0.963227
-1.97407 -0.2 0.822222
-2.82674 -0.225 1.62457
-2.75556 -0.225 1.44028
-2.63437 -0.225 1.25391
-2.46111 -0.225 1.07222
-2.23368 -0.225 0.901997
-1.95 -0.225 0.75
-2.896 -0.2 1.60229
-2.81619 -0.2 1.4035
-2.68102 -0.2 1.20764
-2.48875 -0.2 1.01872
-2.23764 -0.2 0.840766
-1.92593 -0.2 0.677778
-2.94929 -0.125 1.58515
-2.86283 -0.125 1.37521
-2.7169 -0.125 1.17205
-2.51001 -0.125 0.977572
-2.24068 -0.125 0.793666
-1.90741 -0.125 0.622222
-2.9706 0 1.5783
-2.88148 0 1.36389
-2.73125 0 1.15781
-2.51852 0 0.961111
-2.2419 0 0.774826
-1.9 0 0.6
-2.94929 0.125 1.58515
-2.86283 0.125 1.37521
-2.7169 0.125 1.17205
-2.51001 0.125 0.977572
-2.24068 0.125 0.793666
-1.90741 0.125 0.622222
-2.896 0.2 1.60229
-2.81619 0.2 1.4035
-2.68102 0.2 1.20764
-2.48875 0.2 1.01872
-2.23764 0.2 0.840766
-1.92593 0.2 0.677778
-2.82674 0.225 1.62457
-2.75556 0.225 1.44028
-2.63437 0.225 1.25391
-2.46111 0.225 1.07222
-2.23368 0.225 0.901997
-1.95 0.225 0.75
-2.75747 0.2 1.64684
-2.69492 0.2 1.47706
-2.58773 0.2 1.30017
-2.43347 0.2 1.12572
-2.22972 0.2 0.963227
-1.97407 0.2 0.822222
-2.70418 0.125 1.66398
-2.64829 0.125 1.50535
-2.55185 0.125 1.33576
-2.41221 0.125 1.16687
-2.22668 0.125 1.01033
-1.99259 0.125 0.877778
2.0588 0 1.47639
1.7 0 1.425
1.7 -0.275 1.36389
2.07238 -0.262346 1.42521
2.27037 0 1.61111
2.29012 -0.23071 1.57202
2.3875 0 1.8
2.40972 -0.189583 1.77361
2.46296 0 2.01389
2.48765 -0.148457 1.99928
2.54954 0 2.22361
2.5804 -0.116821 2.21831
2.7 0 2.4
2.74444 -0.104167 2.4
1.7 -0.44 1.21111
2.10633 -0.419753 1.29725
2.33951 -0.369136 1.47428
2.46528 -0.303333 1.70764
2.54938 -0.237531 1.96276
2.65756 -0.186914 2.20507
2.85556 -0.166667 2.4
1.7 -0.495 1.0125
2.15046 -0.472222 1.1309
2.4037 -0.415278 1.34722
2.5375 -0.34125 1.62187
2.62963 -0.267222 1.91528
2.75787 -0.210278 2.18785
3 -0.1875 2.4
1.7 -0.44 0.813889
2.1946 -0.419753 0.964558
2.4679 -0.369136 1.22016
2.60972 -0.303333 1.53611
2.70988 -0.237531 1.8678
2.85818 -0.186914 2.17063
3.14444 -0.166667 2.4
1.7 -0.275 0.661111
2.22855 -0.262346 0.8366
2.51728 -0.23071 1.12243
2.66528 -0.189583 1.47014
2.7716 -0.148457 1.83128
2.93534 -0.116821 2.15738
3.25556 -0.104167 2.4
1.7 0 0.6
2.24213 0 0.785417
2.53704 0 1.08333
2.6875 0 1.44375
2.7963 0 1.81667
2.9662 0 2.15208
3.3 0 2.4
1.7 0.275 0.661111
2.22855 0.262346 0.8366
2.51728 0.23071 1.12243
2.66528 0.189583 1.47014
2.7716 0.148457 1.83128
2.93534 0.116821 2.15738
3.25556 0.104167 2.4
1.7 0.44 0.813889
2.1946 0.419753 0.964558
2.4679 0.369136 1.22016
2.60972 0.303333 1.53611
2.70988 0.237531 1.8678
2.85818 0.186914 2.17063
3.14444 0.166667 2.4
1.7 0.495 1.0125
2.15046 0.472222 1.1309
2.4037 0.415278 1.34722
2.5375 0.34125 1.62187
2.62963 0.267222 1.91528
2.75787 0.210278 2.18785
3 0.1875 2.4
1.7 0.44 1.21111
2.10633 0.419753 1.29725
2.33951 0.369136 1.47428
2.46528 0.303333 1.70764
2.54938 0.237531 1.96276
2.65756 0.186914 2.20507
2.85556 0.166667 2.4
1.7 0.275 1.36389
2.07238 0.262346 1.42521
2.29012 0.23071 1.57202
2.40972 0.189583 1.77361
2.48765 0.148457 1.99928
2.5804 0.116821 2.21831
2.74444 0.104167 2.4
2.74907 0 2.43125
2.79641 -0.101032 2.43193
2.79259 0 2.45
2.83978 -0.092978 2.45123
2.825 0 2.45625
2.86968 -0.082031 2.45781
2.84074 0 2.45
2.88121 -0.070216 2.45154
2.83426 0 2.43125
2.86949 -0.059558 2.43231
2.8 0 2.4
2.82963 -0.052083 2.4
2.91474 -0.161574 2.43361
2.95775 -0.148148 2.45432
2.98137 -0.129167 2.46172
2.98237 -0.107407 2.4554
2.95756 -0.085648 2.43496
2.9037 -0.066667 2.4
3.06858 -0.181684 2.43581
3.11111 -0.165972 2.45833
3.12656 -0.142969 2.4668
3.11389 -0.115278 2.46042
3.07205 -0.085504 2.43841
3 -0.05625 2.4
3.22241 -0.16142 2.438
3.26447 -0.146914 2.46235
3.27176 -0.125 2.47187
3.2454 -0.097531 2.46543
3.18654 -0.066358 2.44186
3.0963 -0.033333 2.4
3.34075 -0.100839 2.43969
3.38244 -0.091435 2.46543
3.38345 -0.076823 2.47578
3.34657 -0.05787 2.46929
3.27461 -0.035446 2.44451
3.17037 -0.010417 2.4
3.38808 0 2.44036
3.42963 0 2.46667
3.42813 0 2.47734
3.38704 0 2.47083
3.30984 0 2.44557
3.2 0 2.4
3.34075 0.10108 2.43969
3.38244 0.093364 2.46543
3.38345 0.083333 2.47578
3.34657 0.073303 2.46929
3.27461 0.065586 2.44451
3.17037 0.0625 2.4
3.22241 0.161728 2.438
3.26447 0.149383 2.46235
3.27176 0.133333 2.47187
3.2454 0.117284 2.46543
3.18654 0.104938 2.44186
3.0963 0.1 2.4
3.06858 0.181944 2.43581
3.11111 0.168056 2.45833
3.12656 0.15 2.4668
3.11389 0.131944 2.46042
3.07205 0.118056 2.43841
3 0.1125 2.4
2.91474 0.161728 2.43361
2.95775 0.149383 2.45432
2.98137 0.133333 2.46172
2.98237 0.117284 2.4554
2.95756 0.104938 2.43496
2.9037 0.1 2.4
2.79641 0.10108 2.43193
2.83978 0.093364 2.45123
2.86968 0.083333 2.45781
2.88121 0.073303 2.45154
2.86949 0.065586 2.43231
2.82963 0.0625 2.4
0.278704 0 3.12708
0 0 3.15
0.268946 -0.075078 3.12708
0.362963 0 3.06667
0.350254 -0.097771 3.06667
0.325 0 2.98125
0.313617 -0.087529 2.98125
0.237037 0 2.88333
0.228728 -0.063803 2.88333
0.241285 -0.141931 3.12708
0.314228 -0.184834 3.06667
0.281352 -0.165481 2.98125
0.20518 -0.120647 2.88333
0.19814 -0.19814 3.12708
0.258037 -0.258037 3.06667
0.231031 -0.231031 2.98125
0.168463 -0.168463 2.88333
0.141931 -0.241285 3.12708
0.184834 -0.314228 3.06667
0.165481 -0.281352 2.98125
0.120647 -0.20518 2.88333
0.075078 -0.268946 3.12708
0.097771 -0.350254 3.06667
0.087529 -0.313617 2.98125
0.063803 -0.228728 2.88333
0 -0.278704 3.12708
0 -0.362963 3.06667
0 -0.325 2.98125
0 -0.237037 2.88333
-0.075078 -0.268946 3.12708
-0.097771 -0.350254 3.06667
-0.087529 -0.313617 2.98125
-0.063803 -0.228728 2.88333
-0.141931 -0.241285 3.12708
-0.184834 -0.314228 3.06667
-0.165481 -0.281352 2.98125
-0.120647 -0.20518 2.88333
-0.19814 -0.19814 3.12708
-0.258037 -0.258037 3.06667
-0.231031 -0.231031 2.98125
-0.168463 -0.168463 2.88333
-0.241285 -0.141931 3.12708
-0.314228 -0.184834 3.06667
-0.281352 -0.165481 2.98125
-0.20518 -0.120647 2.88333
-0.268946 -0.075078 3.12708
-0.350254 -0.097771 3.06667
-0.313617 -0.087529 2.98125
-0.228728 -0.063803 2.88333
-0.278704 0 3.12708
-0.362963 0 3.06667
-0.325 0 2.98125
-0.237037 0 2.88333
-0.268946 0.075078 3.12708
-0.350254 0.097771 3.06667
-0.313617 0.087529 2.98125
-0.228728 0.063803 2.88333
-0.241285 0.141931 3.12708
-0.314228 0.184834 3.06667
-0.281352 0.165481 2.98125
-0.20518 0.120647 2.88333
-0.19814 0.19814 3.12708
-0.258037 0.258037 3.06667
-0.231031 0.231031 2.98125
-0.168463 0.168463 2.88333
-0.141931 0.241285 3.12708
-0.184834 0.314228 3.06667
-0.165481 0.281352 2.98125
-0.120647 0.20518 2.88333
-0.075078 0.268946 3.12708
-0.097771 0.350254 3.06667
-0.087529 0.313617 2.98125
-0.063803 0.228728 2.88333
0 0.278704 3.12708
0 0.362963 3.06667
0 0.325 2.98125
0 0.237037 2.88333
0.075078 0.268946 3.12708
0.097771 0.350254 3.06667
0.087529 0.313617 2.98125
0.063803 0.228728 2.88333
0.141931 0.241285 3.12708
0.184834 0.314228 3.06667
0.165481 0.281352 2.98125
0.120647 0.20518 2.88333
0.19814 0.19814 3.12708
0.258037 0.258037 3.06667
0.231031 0.231031 2.98125
0.168463 0.168463 2.88333
0.241285 0.141931 3.12708
0.314228 0.184834 3.06667
0.281352 0.165481 2.98125
0.20518 0.120647 2.88333
0.268946 0.075078 3.12708
0.350254 0.097771 3.06667
0.313617 0.087529 2.98125
0.228728 0.063803 2.88333
3 0 1 2
3 0 2 3
3 4 0 3
3 4 3 5
3 6 4 5
3 6 5 7
3 8 6 7
3 8 7 9
3 10 8 9
3 10 9 11
3 12 10 11
3 12 11 13
3 3 2 14
3 3 14 15
3 5 3 15
3 5 15 16
3 7 5 16
3 7 16 17
3 9 7 17
3 9 17 18
3 11 9 18
3 11 18 19
3 13 11 19
3 13 19 20
3 15 14 21
3 15 21 22
3 16 15 22
3 16 22 23
3 17 16 23
3 17 23 24
3 18 17 24
3 18 24 25
3 19 18 25
3 19 25 26
3 20 19 26
3 20 26 27
3 22 21 28
3 22 28 29
3 23 22 29
3 23 29 30
3 24 23 30
3 24 30 31
3 25 24 31
3 25 31 32
3 26 25 32
3 26 32 33
3 27 26 33
3 27 33 34
3 29 28 35
3 29 35 36
3 30 29 36
3 30 36 37
3 31 30 37
3 31 37 38
3 32 31 38
3 32 38 39
3 33 32 39
3 33 39 40
3 34 33 40
3 34 40 41
3 36 35 42
3 36 42 43
3 37 36 43
3 37 43 44
3 38 37 44
3 38 44 45
3 39 38 45
3 39 45 46
3 40 39 46
3 40 46 47
3 41 40 47
3 41 47 48
3 43 42 49
3 43 49 50
3 44 43 50
3 44 50 51
3 45 44 51
3 45 51 52
3 46 45 52
3 46 52 53
3 47 46 53
3 47 53 54
3 48 47 54
3 48 54 55
3 50 49 56
3 50 56 57
3 51 50 57
3 51 57 58
3 52 51 58
3 52 58 59
3 53 52 59
3 53 59 60
3 54 53 60
3 54 60 61
3 55 54 61
3 55 61 62
3 57 56 63
3 57 63 64
3 58 57 64
3 58 64 65
3 59 58 65
3 59 65 66
3 60 59 66
3 60 66 67
3 61 60 67
3 61 67 68
3 62 61 68
3 62 68 69
3 64 63 70
3 64 70 71
3 65 64 71
3 65 71 72
3 66 65 72
3 66 72 73
3 67 66 73
3 67 73 74
3 68 67 74
3 68 74 75
3 69 68 75
3 69 75 76
3 71 70 77
3 71 77 78
3 72 71 78
3 72 78 79
3 73 72 79
3 73 79 80
3 74 73 80
3 74 80 81
3 75 74 81
3 75 81 82
3 76 75 82
3 76 82 83
3 78 77 84
3 78 84 85
3 79 78 85
3 79 85 86
3 80 79 86
3 80 86 87
3 81 80 87
3 81 87 88
3 82 81 88
3 82 88 89
3 83 82 89
3 83 89 90
3 85 84 91
3 85 91 92
3 86 85 92
3 86 92 93
3 87 86 93
3 87 93 94
3 88 87 94
3 88 94 95
3 89 88 95
3 89 95 96
3 90 89 96
3 90 96 97
3 92 91 98
3 92 98 99
3 93 92 99
3 93 99 100
3 94 93 100
3 94 100 101
3 95 94 101
3 95 101 102
3 96 95 102
3 96 102 103
3 97 96 103
3 97 103 104
3 99 98 105
3 99 105 106
3 100 99 106
3 100 106 107
3 101 100 107
3 101 107 108
3 102 101 108
3 102 108 109
3 103 102 109
3 103 109 110
3 104 103 110
3 104 110 111
3 106 105 112
3 106 112 113
3 107 106 113
3 107 113 114
3 108 107 114
3 108 114 115
3 109 108 115
3 109 115 116
3 110 109 116
3 110 116 117
3 111 110 117
3 111 117 118
3 113 112 119
3 113 119 120
3 114 113 120
3 114 120 121
3 115 114 121
3 115 121 122
3 116 115 122
3 116 122 123
3 117 116 123
3 117 123 124
3 118 117 124
3 118 124 125
3 120 119 126
3 120 126 127
3 121 120 127
3 121 127 128
3 122 121 128
3 122 128 129
3 123 122 129
3 123 129 130
3 124 123 130
3 124 130 131
3 125 124 131
3 125 131 132
3 127 126 133
3 127 133 134
3 128 127 134
3 128 134 135
3 129 128 135
3 129 135 136
3 130 129 136
3 130 136 137
3 131 130 137
3 131 137 138
3 132 131 138
3 132 138 139
3 134 133 140
3 134 140 141
3 135 134 141
3 135 141 142
3 136 135 142
3 136 142 143
3 137 136 143
3 137 143 144
3 138 137 144
3 138 144 145
3 139 138 145
3 139 145 146
3 141 140 147
3 141 147 148
3 142 141 148
3 142 148 149
3 143 142 149
3 143 149 150
3 144 143 150
3 144 150 151
3 145 144 151
3 145 151 152
3 146 145 152
3 146 152 153
3 148 147 154
3 148 154 155
3 149 148 155
3 149 155 156
3 150 149 156
3 150 156 157
3 151 150 157
3 151 157 158
3 152 151 158
3 152 158 159
3 153 152 159
3 153 159 160
3 155 154 161
3 155 161 162
3 156 155 162
3 156 162 163
3 157 156 163
3 157 163 164
3 158 157 164
3 158 164 165
3 159 158 165
3 159 165 166
3 160 159 166
3 160 166 167
3 162 161 1
3 162 1 0
3 163 162 0
3 163 0 4
3 164 163 4
3 164 4 6
3 165 164 6
3 165 6 8
3 166 165 8
3 166 8 10
3 167 166 10
3 167 10 12
3 168 12 13
3 168 13 169
3 170 168 169
3 170 169 171
3 172 170 171
3 172 171 173
3 174 172 173
3 174 173 175
3 176 174 175
3 176 175 177
3 178 176 177
3 178 177 179
3 169 13 20
3 169 20 180
3 171 169 180
3 171 180 181
3 173 171 181
3 173 181 182
3 175 173 182
3 175 182 183
3 177 175 183
3 177 183 184
3 179 177 184
3 179 184 185
3 180 20 27
3 180 27 186
3 181 180 186
3 181 186 187
3 182 181 187
3 182 187 188
3 183 182 188
3 183 188 189
3 184 183 189
3 184 189 190
3 185 184 190
3 185 190 191
3 186 27 34
3 186 34 192
3 187 186 192
3 187 192 193
3 188 187 193
3 188 193 194
3 189 188 194
3 189 194 195
3 190 189 195
3 190 195 196
3 191 190 196
3 191 196 197
3 192 34 41
3 192 41 198
3 193 192 198
3 193 198 199
3 194 193 199
3 194 199 200
3 195 194 200
3 195 200 201
3 196 195 201
3 196 201 202
3 197 196 202
3 197 202 203
3 198 41 48
3 198 48 204
3 199 198 204
3 199 204 205
3 200 199 205
3 200 205 206
3 201 200 206
3 201 206 207
3 202 201 207
3 202 207 208
3 203 202 208
3 203 208 209
3 204 48 55
3 204 55 210
3 205 204 210
3 205 210 211
3 206 205 211
3 206 211 212
3 207 206 212
3 207 212 213
3 208 207 213
3 208 213 214
3 209 208 214
3 209 214 215
3 210 55 62
3 210 62 216
3 211 210 216
3 211 216 217
3 212 211 217
3 212 217 218
3 213 212 218
3 213 218 219
3 214 213 219
3 214 219 220
3 215 214 220
3 215 220 221
3 216 62 69
3 216 69 222
3 217 216 222
3 217 222 223
3 218 217 223
3 218 223 224
3 219 218 224
3 219 224 225
3 220 219 225
3 220 225 226
3 221 220 226
3 221 226 227
3 222 69 76
3 222 76 228
3 223 222 228
3 223 228 229
3 224 223 229
3 224 229 230
3 225 224 230
3 225 230 231
3 226 225 231
3 226 231 232
3 227 226 232
3 227 232 233
3 228 76 83
3 228 83 234
3 229 228 234
3 229 234 235
3 230 229 235
3 230 235 236
3 231 230 236
3 231 236 237
3 232 231 237
3 232 237 238
3 233 232 238
3 233 238 239
3 234 83 90
3 234 90 240
3 235 234 240
3 235 240 241
3 236 235 241
3 236 241 242
3 237 236 242
3 237 242 243
3 238 237 243
3 238 243 244
3 239 238 244
3 239 244 245
3 240 90 97
3 240 97 246
3 241 240 246
3 241 246 247
3 242 241 247
3 242 247 248
3 243 242 248
3 243 248 249
3 244 243 249
3 244 249 250
3 245 244 250
3 245 250 251
3 246 97 104
3 246 104 252
3 247 246 252
3 247 252 253
3 248 247 253
3 248 253 254
3 249 248 254
3 249 254 255
3 250 249 255
3 250 255 256
3 251 250 256
3 251 256 257
3 252 104 111
3 252 111 258
3 253 252 258
3 253 258 259
3 254 253 259
3 254 259 260
3 255 254 260
3 255 260 261
3 256 255 261
3 256 261 262
3 257 256 262
3 257 262 263
3 258 111 118
3 258 118 264
3 259 258 264
3 259 264 265
3 260 259 265
3 260 265 266
3 261 260 266
3 261 266 267
3 262 261 267
3 262 267 268
3 263 262 268
3 263 268 269
3 264 118 125
3 264 125 270
3 265 264 270
3 265 270 271
3 266 265 271
3 266 271 272
3 267 266 272
3 267 272 273
3 268 267 273
3 268 273 274
3 269 268 274
3 269 274 275
3 270 125 132
3 270 132 276
3 271 270 276
3 271 276 277
3 272 271 277
3 272 277 278
3 273 272 278
3 273 278 279
3 274 273 279
3 274 279 280
3 275 274 280
3 275 280 281
3 276 132 139
3 276 139 282
3 277 276 282
3 277 282 283
3 278 277 283
3 278 283 284
3 279 278 284
3 279 284 285
3 280 279 285
3 280 285 286
3 281 280 286
3 281 286 287
3 282 139 146
3 282 146 288
3 283 282 288
3 283 288 289
3 284 283 289
3 284 289 290
3 285 284 290
3 285 290 291
3 286 285 291
3 286 291 292
3 287 286 292
3 287 292 293
3 288 146 153
3 288 153 294
3 289 288 294
3 289 294 295
3 290 289 295
3 290 295 296
3 291 290 296
3 291 296 297
3 292 291 297
3 292 297 298
3 293 292 298
3 293 298 299
3 294 153 160
3 294 160 300
3 295 294 300
3 295 300 301
3 296 295 301
3 296 301 302
3 297 296 302
3 297 302 303
3 298 297 303
3 298 303 304
3 299 298 304
3 299 304 305
3 300 160 167
3 300 167 306
3 301 300 306
3 301 306 307
3 302 301 307
3 302 307 308
3 303 302 308
3 303 308 309
3 304 303 309
3 304 309 310
3 305 304 310
3 305 310 311
3 306 167 12
3 306 12 168
3 307 306 168
3 307 168 170
3 308 307 170
3 308 170 172
3 309 308 172
3 309 172 174
3 310 309 174
3 310 174 176
3 311 310 176
3 311 176 178
3 312 178 179
3 312 179 313
3 314 312 313
3 314 313 315
3 316 314 315
3 316 315 317
3 318 316 317
3 318 317 319
3 320 318 319
3 320 319 321
3 322 320 321
3 322 321 323
3 313 179 185
3 313 185 324
3 315 313 324
3 315 324 325
3 317 315 325
3 317 325 326
3 319 317 326
3 319 326 327
3 321 319 327
3 321 327 328
3 323 321 328
3 323 328 329
3 324 185 191
3 324 191 330
3 325 324 330
3 325 330 331
3 326 325 331
3 326 331 332
3 327 326 332
3 327 332 333
3 328 327 333
3 328 333 334
3 329 328 334
3 329 334 335
3 330 191 197
3 330 197 336
3 331 330 336
3 331 336 337
3 332 331 337
3 332 337 338
3 333 332 338
3 333 338 339
3 334 333 339
3 334 339 340
3 335 334 340
3 335 340 341
3 336 197 203
3 336 203 342
3 337 336 342
3 337 342 343
3 338 337 343
3 338 343 344
3 339 338 344
3 339 344 345
3 340 339 345
3 340 345 346
3 341 340 346
3 341 346 347
3 342 203 209
3 342 209 348
3 343 342 348
3 343 348 349
3 344 343 349
3 344 349 350
3 345 344 350
3 345 350 351
3 346 345 351
3 346 351 352
3 347 346 352
3 347 352 353
3 348 209 215
3 348 215 354
3 349 348 354
3 349 354 355
3 350 349 355
3 350 355 356
3 351 350 356
3 351 356 357
3 352 351 357
3 352 357 358
3 353 352 358
3 353 358 359
3 354 215 221
3 354 221 360
3 355 354 360
3 355 360 361
3 356 355 361
3 356 361 362
3 357 356 362
3 357 362 363
3 358 357 363
3 358 363 364
3 359 358 364
3 359 364 365
3 360 221 227
3 360 227 366
3 361 360 366
3 361 366 367
3 362 361 367
3 362 367 368
3 363 362 368
3 363 368 369
3 364 363 369
3 364 369 370
3 365 364 370
3 365 370 371
3 366 227 233
3 366 233 372
3 367 366 372
3 367 372 373
3 368 367 373
3 368 373 374
3 369 368 374
3 369 374 375
3 370 369 375
3 370 375 376
3 371 370 376
3 371 376 377
3 372 233 239
3 372 239 378
3 373 372 378
3 373 378 379
3 374 373 379
3 374 379 380
3 375 374 380
3 375 380 381
3 376 375 381
3 376 381 382
3 377 376 382
3 377 382 383
3 378 239 245
3 378 245 384
3 379 378 384
3 379 384 385
3 380 379 385
3 380 385 386
3 381 380 386
3 381 386 387
3 382 381 387
3 382 387 388
3 383 382 388
3 383 388 389
3 384 245 251
3 384 251 390
3 385 384 390
3 385 390 391
3 386 385 391
3 386 391 392
3 387 386 392
3 387 392 393
3 388 387 393
3 388 393 394
3 389 388 394
3 389 394 395
3 390 251 257
3 390 257 396
3 391 390 396
3 391 396 397
3 392 391 397
3 392 397 398
3 393 392 398
3 393 398 399
3 394 393 399
3 394 399 400
3 395 394 400
3 395 400 401
3 396 257 263
3 396 263 402
3 397 396 402
3 397 402 403
3 398 397 403
3 398 403 404
3 399 398 404
3 399 404 405
3 400 399 405
3 400 405 406
3 401 400 406
3 401 406 407
3 402 263 269
3 402 269 408
3 403 402 408
3 403 408 409
3 404 403 409
3 404 409 410
3 405 404 410
3 405 410 411
3 406 405 411
3 406 411 412
3 407 406 412
3 407 412 413
3 408 269 275
3 408 275 414
3 409 408 414
3 409 414 415
3 410 409 415
3 410 415 416
3 411 410 416
3 411 416 417
3 412 411 417
3 412 417 418
3 413 412 418
3 413 418 419
3 414 275 281
3 414 281 420
3 415 414 420
3 415 420 421
3 416 415 421
3 416 421 422
3 417 416 422
3 417 422 423
3 418 417 423
3 418 423 424
3 419 418 424
3 419 424 425
3 420 281 287
3 420 287 426
3 421 420 426
3 421 426 427
3 422 421 427
3 422 427 428
3 423 422 428
3 423 428 429
3 424 423 429
3 424 429 430
3 425 424 430
3 425 430 431
3 426 287 293
3 426 293 432
3 427 426 432
3 427 432 433
3 428 427 433
3 428 433 434
3 429 428 434
3 429 434 435
3 430 429 435
3 430 435 436
3 431 430 436
3 431 436 437
3 432 293 299
3 432 299 438
3 433 432 438
3 433 438 439
3 434 433 439
3 434 439 440
3 435 434 440
3 435 440 441
3 436 435 441
3 436 441 442
3 437 436 442
3 437 442 443
3 438 299 305
3 438 305 444
3 439 438 444
3 439 444 445
3 440 439 445
3 440 445 446
3 441 440 446
3 441 446 447
3 442 441 447
3 442 447 448
3 443 442 448
3 443 448 449
3 444 305 311
3 444 311 450
3 445 444 450
3 445 450 451
3 446 445 451
3 446 451 452
3 447 446 452
3 447 452 453
3 448 447 453
3 448 453 454
3 449 448 454
3 449 454 455
3 450 311 178
3 450 178 312
3 451 450 312
3 451 312 314
3 452 451 314
3 452 314 316
3 453 452 316
3 453 316 318
3 454 453 318
3 454 318 320
3 455 454 320
3 455 320 322
3 456 457 458
3 459 456 458
3 459 458 460
3 461 459 460
3 461 460 462
3 463 461 462
3 463 462 464
3 465 463 464
3 465 464 466
3 322 465 466
3 322 466 455
3 458 457 467
3 460 458 467
3 460 467 468
3 462 460 468
3 462 468 469
3 464 462 469
3 464 469 470
3 466 464 470
3 466 470 471
3 455 466 471
3 455 471 449
3 467 457 472
3 468 467 472
3 468 472 473
3 469 468 473
3 469 473 474
3 470 469 474
3 470 474 475
3 471 470 475
3 471 475 476
3 449 471 476
3 449 476 443
3 472 457 477
3 473 472 477
3 473 477 478
3 474 473 478
3 474 478 479
3 475 474 479
3 475 479 480
3 476 475 480
3 476 480 481
3 443 476 481
3 443 481 437
3 477 457 482
3 478 477 482
3 478 482 483
3 479 478 483
3 479 483 484
3 480 479 484
3 480 484 485
3 481 480 485
3 481 485 486
3 437 481 486
3 437 486 431
3 482 457 487
3 483 482 487
3 483 487 488
3 484 483 488
3 484 488 489
3 485 484 489
3 485 489 490
3 486 485 490
3 486 490 491
3 431 486 491
3 431 491 425
3 487 457 492
3 488 487 492
3 488 492 493
3 489 488 493
3 489 493 494
3 490 489 494
3 490 494 495
3 491 490 495
3 491 495 496
3 425 491 496
3 425 496 419
3 492 457 497
3 493 492 497
3 493 497 498
3 494 493 498
3 494 498 499
3 495 494 499
3 495 499 500
3 496 495 500
3 496 500 501
3 419 496 501
3 419 501 413
3 497 457 502
3 498 497 502
3 498 502 503
3 499 498 503
3 499 503 504
3 500 499 504
3 500 504 505
3 501 500 505
3 501 505 506
3 413 501 506
3 413 506 407
3 502 457 507
3 503 502 507
3 503 507 508
3 504 503 508
3 504 508 509
3 505 504 509
3 505 509 510
3 506 505 510
3 506 510 511
3 407 506 511
3 407 511 401
3 507 457 512
3 508 507 512
3 508 512 513
3 509 508 513
3 509 513 514
3 510 509 514
3 510 514 515
3 511 510 515
3 511 515 516
3 401 511 516
3 401 516 395
3 512 457 517
3 513 512 517
3 513 517 518
3 514 513 518
3 514 518 519
3 515 514 519
3 515 519 520
3 516 515 520
3 516 520 521
3 395 516 521
3 395 521 389
3 517 457 522
3 518 517 522
3 518 522 523
3 519 518 523
3 519 523 524
3 520 519 524
3 520 524 525
3 521 520 525
3 521 525 526
3 389 521 526
3 389 526 383
3 522 457 527
3 523 522 527
3 523 527 528
3 524 523 528
3 524 528 529
3 525 524 529
3 525 529 530
3 526 525 530
3 526 530 531
3 383 526 531
3 383 531 377
3 527 457 532
3 528 527 532
3 528 532 533
3 529 528 533
3 529 533 534
3 530 529 534
3 530 534 535
3 531 530 535
3 531 535 536
3 377 531 536
3 377 536 371
3 532 457 537
3 533 532 537
3 533 537 538
3 534 533 538
3 534 538 539
3 535 534 539
3 535 539 540
3 536 535 540
3 536 540 541
3 371 536 541
3 371 541 365
3 537 457 542
3 538 537 542
3 538 542 543
3 539 538 543
3 539 543 544
3 540 539 544
3 540 544 545
3 541 540 545
3 541 545 546
3 365 541 546
3 365 546 359
3 542 457 547
3 543 542 547
3 543 547 548
3 544 543 548
3 544 548 549
3 545 544 549
3 545 549 550
3 546 545 550
3 546 550 551
3 359 546 551
3 359 551 353
3 547 457 552
3 548 547 552
3 548 552 553
3 549 548 553
3 549 553 554
3 550 549 554
3 550 554 555
3 551 550 555
3 551 555 556
3 353 551 556
3 353 556 347
3 552 457 557
3 553 552 557
3 553 557 558
3 554 553 558
3 554 558 559
3 555 554 559
3 555 559 560
3 556 555 560
3 556 560 561
3 347 556 561
3 347 561 341
3 557 457 562
3 558 557 562
3 558 562 563
3 559 558 563
3 559 563 564
3 560 559 564
3 560 564 565
3 561 560 565
3 561 565 566
3 341 561 566
3 341 566 335
3 562 457 567
3 563 562 567
3 563 567 568
3 564 563 568
3 564 568 569
3 565 564 569
3 565 569 570
3 566 565 570
3 566 570 571
3 335 566 571
3 335 571 329
3 567 457 572
3 568 567 572
3 568 572 573
3 569 568 573
3 569 573 574
3 570 569 574
3 570 574 575
3 571 570 575
3 571 575 576
3 329 571 576
3 329 576 323
3 572 457 456
3 573 572 456
3 573 456 459
3 574 573 459
3 574 459 461
3 575 574 461
3 575 461 463
3 576 575 463
3 576 463 465
3 323 576 465
3 323 465 322
3 577 578 579
3 577 579 580
3 580 579 581
3 580 581 582
3 582 581 583
3 582 583 584
3 584 583 585
3 584 585 586
3 586 585 587
3 586 587 588
3 588 587 589
3 588 589 590
3 590 589 591
3 590 591 592
3 592 591 593
3 592 593 594
3 594 593 595
3 594 595 596
3 596 595 597
3 596 597 598
3 598 597 599
3 598 599 600
3 600 599 601
3 600 601 602
3 602 601 603
3 602 603 604
3 604 603 605
3 604 605 606
3 606 605 607
3 606 607 608
3 608 607 609
3 608 609 610
3 610 609 611
3 610 611 612
3 612 611 613
3 612 613 614
3 614 613 615
3 614 615 616
3 616 615 617
3 616 617 618
3 618 617 619
3 618 619 620
3 620 619 621
3 620 621 622
3 622 621 623
3 622 623 624
3 624 623 578
3 624 578 577
3 625 577 580
3 625 580 626
3 627 625 626
3 627 626 628
3 629 627 628
3 629 628 630
3 631 629 630
3 631 630 632
3 633 631 632
3 633 632 634
3 635 633 634
3 635 634 636
3 626 580 582
3 626 582 637
3 628 626 637
3 628 637 638
3 630 628 638
3 630 638 639
3 632 630 639
3 632 639 640
3 634 632 640
3 634 640 641
3 636 634 641
3 636 641 642
3 637 582 584
3 637 584 643
3 638 637 643
3 638 643 644
3 639 638 644
3 639 644 645
3 640 639 645
3 640 645 646
3 641 640 646
3 641 646 647
3 642 641 647
3 642 647 648
3 643 584 586
3 643 586 649
3 644 643 649
3 644 649 650
3 645 644 650
3 645 650 651
3 646 645 651
3 646 651 652
3 647 646 652
3 647 652 653
3 648 647 653
3 648 653 654
3 649 586 588
3 649 588 655
3 650 649 655
3 650 655 656
3 651 650 656
3 651 656 657
3 652 651 657
3 652 657 658
3 653 652 658
3 653 658 659
3 654 653 659
3 654 659 660
3 655 588 590
3 655 590 661
3 656 655 661
3 656 661 662
3 657 656 662
3 657 662 663
3 658 657 663
3 658 663 664
3 659 658 664
3 659 664 665
3 660 659 665
3 660 665 666
3 661 590 592
3 661 592 667
3 662 661 667
3 662 667 668
3 663 662 668
3 663 668 669
3 664 663 669
3 664 669 670
3 665 664 670
3 665 670 671
3 666 665 671
3 666 671 672
3 667 592 594
3 667 594 673
3 668 667 673
3 668 673 674
3 669 668 674
3 669 674 675
3 670 669 675
3 670 675 676
3 671 670 676
3 671 676 677
3 672 671 677
3 672 677 678
3 673 594 596
3 673 596 679
3 674 673 679
3 674 679 680
3 675 674 680
3 675 680 681
3 676 675 681
3 676 681 682
3 677 676 682
3 677 682 683
3 678 677 683
3 678 683 684
3 679 596 598
3 679 598 685
3 680 679 685
3 680 685 686
3 681 680 686
3 681 686 687
3 682 681 687
3 682 687 688
3 683 682 688
3 683 688 689
3 684 683 689
3 684 689 690
3 685 598 600
3 685 600 691
3 686 685 691
3 686 691 692
3 687 686 692
3 687 692 693
3 688 687 693
3 688 693 694
3 689 688 694
3 689 694 695
3 690 689 695
3 690 695 696
3 691 600 602
3 691 602 697
3 692 691 697
3 692 697 698
3 693 692 698
3 693 698 699
3 694 693 699
3 694 699 700
3 695 694 700
3 695 700 701
3 696 695 701
3 696 701 702
3 697 602 604
3 697 604 703
3 698 697 703
3 698 703 704
3 699 698 704
3 699 704 705
3 700 699 705
3 700 705 706
3 701 700 706
3 701 706 707
3 702 701 707
3 702 707 708
3 703 604 606
3 703 606 709
3 704 703 709
3 704 709 710
3 705 704 710
3 705 710 711
3 706 705 711
3 706 711 712
3 707 706 712
3 707 712 713
3 708 707 713
3 708 713 714
3 709 606 608
3 709 608 715
3 710 709 715
3 710 715 716
3 711 710 716
3 711 716 717
3 712 711 717
3 712 717 718
3 713 712 718
3 713 718 719
3 714 713 719
3 714 719 720
3 715 608 610
3 715 610 721
3 716 715 721
3 716 721 722
3 717 716 722
3 717 722 723
3 718 717 723
3 718 723 724
3 719 718 724
3 719 724 725
3 720 719 725
3 720 725 726
3 721 610 612
3 721 612 727
3 722 721 727
3 722 727 728
3 723 722 728
3 723 728 729
3 724 723 729
3 724 729 730
3 725 724 730
3 725 730 731
3 726 725 731
3 726 731 732
3 727 612 614
3 727 614 733
3 728 727 733
3 728 733 734
3 729 728 734
3 729 734 735
3 730 729 735
3 730 735 736
3 731 730 736
3 731 736 737
3 732 731 737
3 732 737 738
3 733 614 616
3 733 616 739
3 734 733 739
3 734 739 740
3 735 734 740
3 735 740 741
3 736 735 741
3 736 741 742
3 737 736 742
3 737 742 743
3 738 737 743
3 738 743 744
3 739 616 618
3 739 618 745
3 740 739 745
3 740 745 746
3 741 740 746
3 741 746 747
3 742 741 747
3 742 747 748
3 743 742 748
3 743 748 749
3 744 743 749
3 744 749 750
3 745 618 620
3 745 620 751
3 746 745 751
3 746 751 752
3 747 746 752
3 747 752 753
3 748 747 753
3 748 753 754
3 749 748 754
3 749 754 755
3 750 749 755
3 750 755 756
3 751 620 622
3 751 622 757
3 752 751 757
3 752 757 758
3 753 752 758
3 753 758 759
3 754 753 759
3 754 759 760
3 755 754 760
3 755 760 761
3 756 755 761
3 756 761 762
3 757 622 624
3 757 624 763
3 758 757 763
3 758 763 764
3 759 758 764
3 759 764 765
3 760 759 765
3 760 765 766
3 761 760 766
3 761 766 767
3 762 761 767
3 762 767 768
3 763 624 577
3 763 577 625
3 764 763 625
3 764 625 627
3 765 764 627
3 765 627 629
3 766 765 629
3 766 629 631
3 767 766 631
3 767 631 633
3 768 767 633
3 768 633 635
3 769 770 771
3 769 771 772
3 773 769 772
3 773 772 774
3 775 773 774
3 775 774 776
3 777 775 776
3 777 776 778
3 779 777 778
3 779 778 780
3 781 779 780
3 781 780 782
3 772 771 783
3 772 783 784
3 774 772 784
3 774 784 785
3 776 774 785
3 776 785 786
3 778 776 786
3 778 786 787
3 780 778 787
3 780 787 788
3 782 780 788
3 782 788 789
3 784 783 790
3 784 790 791
3 785 784 791
3 785 791 792
3 786 785 792
3 786 792 793
3 787 786 793
3 787 793 794
3 788 787 794
3 788 794 795
3 789 788 795
3 789 795 796
3 791 790 797
3 791 797 798
3 792 791 798
3 792 798 799
3 793 792 799
3 793 799 800
3 794 793 800
3 794 800 801
3 795 794 801
3 795 801 802
3 796 795 802
3 796 802 803
3 798 797 804
3 798 804 805
3 799 798 805
3 799 805 806
3 800 799 806
3 800 806 807
3 801 800 807
3 801 807 808
3 802 801 808
3 802 808 809
3 803 802 809
3 803 809 810
3 805 804 811
3 805 811 812
3 806 805 812
3 806 812 813
3 807 806 813
3 807 813 814
3 808 807 814
3 808 814 815
3 809 808 815
3 809 815 816
3 810 809 816
3 810 816 817
3 812 811 818
3 812 818 819
3 813 812 819
3 813 819 820
3 814 813 820
3 814 820 821
3 815 814 821
3 815 821 822
3 816 815 822
3 816 822 823
3 817 816 823
3 817 823 824
3 819 818 825
3 819 825 826
3 820 819 826
3 820 826 827
3 821 820 827
3 821 827 828
3 822 821 828
3 822 828 829
3 823 822 829
3 823 829 830
3 824 823 830
3 824 830 831
3 826 825 832
3 826 832 833
3 827 826 833
3 827 833 834
3 828 827 834
3 828 834 835
3 829 828 835
3 829 835 836
3 830 829 836
3 830 836 837
3 831 830 837
3 831 837 838
3 833 832 839
3 833 839 840
3 834 833 840
3 834 840 841
3 835 834 841
3 835 841 842
3 836 835 842
3 836 842 843
3 837 836 843
3 837 843 844
3 838 837 844
3 838 844 845
3 840 839 846
3 840 846 847
3 841 840 847
3 841 847 848
3 842 841 848
3 842 848 849
3 843 842 849
3 843 849 850
3 844 843 850
3 844 850 851
3 845 844 851
3 845 851 852
3 847 846 770
3 847 770 769
3 848 847 769
3 848 769 773
3 849 848 773
3 849 773 775
3 850 849 775
3 850 775 777
3 851 850 777
3 851 777 779
3 852 851 779
3 852 779 781
3 853 781 782
3 853 782 854
3 855 853 854
3 855 854 856
3 857 855 856
3 857 856 858
3 859 857 858
3 859 858 860
3 861 859 860
3 861 860 862
3 245 861 862
3 245 862 863
3 854 782 789
3 854 789 864
3 856 854 864
3 856 864 865
3 858 856 865
3 858 865 866
3 860 858 866
3 860 866 867
3 862 860 867
3 862 867 868
3 863 862 868
3 863 868 869
3 864 789 796
3 864 796 870
3 865 864 870
3 865 870 871
3 866 865 871
3 866 871 872
3 867 866 872
3 867 872 873
3 868 867 873
3 868 873 874
3 869 868 874
3 869 874 875
3 870 796 803
3 870 803 876
3 871 870 876
3 871 876 877
3 872 871 877
3 872 877 878
3 873 872 878
3 873 878 879
3 874 873 879
3 874 879 880
3 875 874 880
3 875 880 881
3 876 803 810
3 876 810 882
3 877 876 882
3 877 882 883
3 878 877 883
3 878 883 884
3 879 878 884
3 879 884 885
3 880 879 885
3 880 885 886
3 881 880 886
3 881 886 887
3 882 810 817
3 882 817 888
3 883 882 888
3 883 888 889
3 884 883 889
3 884 889 890
3 885 884 890
3 885 890 891
3 886 885 891
3 886 891 892
3 887 886 892
3 887 892 893
3 888 817 824
3 888 824 894
3 889 888 894
3 889 894 895
3 890 889 895
3 890 895 896
3 891 890 896
3 891 896 897
3 892 891 897
3 892 897 898
3 893 892 898
3 893 898 899
3 894 824 831
3 894 831 900
3 895 894 900
3 895 900 901
3 896 895 901
3 896 901 902
3 897 896 902
3 897 902 903
3 898 897 903
3 898 903 904
3 899 898 904
3 899 904 905
3 900 831 838
3 900 838 906
3 901 900 906
3 901 906 907
3 902 901 907
3 902 907 908
3 903 902 908
3 903 908 909
3 904 903 909
3 904 909 910
3 905 904 910
3 905 910 911
3 906 838 845
3 906 845 912
3 907 906 912
3 907 912 913
3 908 907 913
3 908 913 914
3 909 908 914
3 909 914 915
3 910 909 915
3 910 915 916
3 911 910 916
3 911 916 917
3 912 845 852
3 912 852 918
3 913 912 918
3 913 918 919
3 914 913 919
3 914 919 920
3 915 914 920
3 915 920 921
3 916 915 921
3 916 921 922
3 917 916 922
3 917 922 923
3 918 852 781
3 918 781 853
3 919 918 853
3 919 853 855
3 920 919 855
3 920 855 857
3 921 920 857
3 921 857 859
3 922 921 859
3 922 859 861
3 923 922 861
3 923 861 245
3 924 925 926
3 924 926 927
3 928 924 927
3 928 927 929
3 930 928 929
3 930 929 931
3 932 930 931
3 932 931 933
3 934 932 933
3 934 933 935
3 936 934 935
3 936 935 937
3 927 926 938
3 927 938 939
3 929 927 939
3 929 939 940
3 931 929 940
3 931 940 941
3 933 931 941
3 933 941 942
3 935 933 942
3 935 942 943
3 937 935 943
3 937 943 944
3 939 938 945
3 939 945 946
3 940 939 946
3 940 946 947
3 941 940 947
3 941 947 948
3 942 941 948
3 942 948 949
3 943 942 949
3 943 949 950
3 944 943 950
3 944 950 951
3 946 945 952
3 946 952 953
3 947 946 953
3 947 953 954
3 948 947 954
3 948 954 955
3 949 948 955
3 949 955 956
3 950 949 956
3 950 956 957
3 951 950 957
3 951 957 958
3 953 952 959
3 953 959 960
3 954 953 960
3 954 960 961
3 955 954 961
3 955 961 962
3 956 955 962
3 956 962 963
3 957 956 963
3 957 963 964
3 958 957 964
3 958 964 965
3 960 959 966
3 960 966 967
3 961 960 967
3 961 967 968
3 962 961 968
3 962 968 969
3 963 962 969
3 963 969 970
3 964 963 970
3 964 970 971
3 965 964 971
3 965 971 972
3 967 966 973
3 967 973 974
3 968 967 974
3 968 974 975
3 969 968 975
3 969 975 976
3 970 969 976
3 970 976 977
3 971 970 977
3 971 977 978
3 972 971 978
3 972 978 979
3 974 973 980
3 974 980 981
3 975 974 981
3 975 981 982
3 976 975 982
3 976 982 983
3 977 976 983
3 977 983 984
3 978 977 984
3 978 984 985
3 979 978 985
3 979 985 986
3 981 980 987
3 981 987 988
3 982 981 988
3 982 988 989
3 983 982 989
3 983 989 990
3 984 983 990
3 984 990 991
3 985 984 991
3 985 991 992
3 986 985 992
3 986 992 993
3 988 987 994
3 988 994 995
3 989 988 995
3 989 995 996
3 990 989 996
3 990 996 997
3 991 990 997
3 991 997 998
3 992 991 998
3 992 998 999
3 993 992 999
3 993 999 1000
3 995 994 1001
3 995 1001 1002
3 996 995 1002
3 996 1002 1003
3 997 996 1003
3 997 1003 1004
3 998 997 1004
3 998 1004 1005
3 999 998 1005
3 999 1005 1006
3 1000 999 1006
3 1000 1006 1007
3 1002 1001 925
3 1002 925 924
3 1003 1002 924
3 1003 924 928
3 1004 1003 928
3 1004 928 930
3 1005 1004 930
3 1005 930 932
3 1006 1005 932
3 1006 932 934
3 1007 1006 934
3 1007 934 936
3 1008 936 937
3 1008 937 1009
3 1010 1008 1009
3 1010 1009 1011
3 1012 1010 1011
3 1012 1011 1013
3 1014 1012 1013
3 1014 1013 1015
3 1016 1014 1015
3 1016 1015 1017
3 1018 1016 1017
3 1018 1017 1019
3 1009 937 944
3 1009 944 1020
3 1011 1009 1020
3 1011 1020 1021
3 1013 1011 1021
3 1013 1021 1022
3 1015 1013 1022
3 1015 1022 1023
3 1017 1015 1023
3 1017 1023 1024
3 1019 1017 1024
3 1019 1024 1025
3 1020 944 951
3 1020 951 1026
3 1021 1020 1026
3 1021 1026 1027
3 1022 1021 1027
3 1022 1027 1028
3 1023 1022 1028
3 1023 1028 1029
3 1024 1023 1029
3 1024 1029 1030
3 1025 1024 1030
3 1025 1030 1031
3 1026 951 958
3 1026 958 1032
3 1027 1026 1032
3 1027 1032 1033
3 1028 1027 1033
3 1028 1033 1034
3 1029 1028 1034
3 1029 1034 1035
3 1030 1029 1035
3 1030 1035 1036
3 1031 1030 1036
3 1031 1036 1037
3 1032 958 965
3 1032 965 1038
3 1033 1032 1038
3 1033 1038 1039
3 1034 1033 1039
3 1034 1039 1040
3 1035 1034 1040
3 1035 1040 1041
3 1036 1035 1041
3 1036 1041 1042
3 1037 1036 1042
3 1037 1042 1043
3 1038 965 972
3 1038 972 1044
3 1039 1038 1044
3 1039 1044 1045
3 1040 1039 1045
3 1040 1045 1046
3 1041 1040 1046
3 1041 1046 1047
3 1042 1041 1047
3 1042 1047 1048
3 1043 1042 1048
3 1043 1048 1049
3 1044 972 979
3 1044 979 1050
3 1045 1044 1050
3 1045 1050 1051
3 1046 1045 1051
3 1046 1051 1052
3 1047 1046 1052
3 1047 1052 1053
3 1048 1047 1053
3 1048 1053 1054
3 1049 1048 1054
3 1049 1054 1055
3 1050 979 986
3 1050 986 1056
3 1051 1050 1056
3 1051 1056 1057
3 1052 1051 1057
3 1052 1057 1058
3 1053 1052 1058
3 1053 1058 1059
3 1054 1053 1059
3 1054 1059 1060
3 1055 1054 1060
3 1055 1060 1061
3 1056 986 993
3 1056 993 1062
3 1057 1056 1062
3 1057 1062 1063
3 1058 1057 1063
3 1058 1063 1064
3 1059 1058 1064
3 1059 1064 1065
3 1060 1059 1065
3 1060 1065 1066
3 1061 1060 1066
3 1061 1066 1067
3 1062 993 1000
3 1062 1000 1068
3 1063 1062 1068
3 1063 1068 1069
3 1064 1063 1069
3 1064 1069 1070
3 1065 1064 1070
3 1065 1070 1071
3 1066 1065 1071
3 1066 1071 1072
3 1067 1066 1072
3 1067 1072 1073
3 1068 1000 1007
3 1068 1007 1074
3 1069 1068 1074
3 1069 1074 1075
3 1070 1069 1075
3 1070 1075 1076
3 1071 1070 1076
3 1071 1076 1077
3 1072 1071 1077
3 1072 1077 1078
3 1073 1072 1078
3 1073 1078 1079
3 1074 1007 936
3 1074 936 1008
3 1075 1074 1008
3 1075 1008 1010
3 1076 1075 1010
3 1076 1010 1012
3 1077 1076 1012
3 1077 1012 1014
3 1078 1077 1014
3 1078 1014 1016
3 1079 1078 1016
3 1079 1016 1018
3 1080 1081 1082
3 1083 1080 1082
3 1083 1082 1084
3 1085 1083 1084
3 1085 1084 1086
3 1087 1085 1086
3 1087 1086 1088
3 578 1087 1088
3 578 1088 579
3 1082 1081 1089
3 1084 1082 1089
3 1084 1089 1090
3 1086 1084 1090
3 1086 1090 1091
3 1088 1086 1091
3 1088 1091 1092
3 579 1088 1092
3 579 1092 581
3 1089 1081 1093
3 1090 1089 1093
3 1090 1093 1094
3 1091 1090 1094
3 1091 1094 1095
3 1092 1091 1095
3 1092 1095 1096
3 581 1092 1096
3 581 1096 583
3 1093 1081 1097
3 1094 1093 1097
3 1094 1097 1098
3 1095 1094 1098
3 1095 1098 1099
3 1096 1095 1099
3 1096 1099 1100
3 583 1096 1100
3 583 1100 585
3 1097 1081 1101
3 1098 1097 1101
3 1098 1101 1102
3 1099 1098 1102
3 1099 1102 1103
3 1100 1099 1103
3 1100 1103 1104
3 585 1100 1104
3 585 1104 587
3 1101 1081 1105
3 1102 1101 1105
3 1102 1105 1106
3 1103 1102 1106
3 1103 1106 1107
3 1104 1103 1107
3 1104 1107 1108
3 587 1104 1108
3 587 1108 589
3 1105 1081 1109
3 1106 1105 1109
3 1106 1109 1110
3 1107 1106 1110
3 1107 1110 1111
3 1108 1107 1111
3 1108 1111 1112
3 589 1108 1112
3 589 1112 591
3 1109 1081 1113
3 1110 1109 1113
3 1110 1113 1114
3 1111 1110 1114
3 1111 1114 1115
3 1112 1111 1115
3 1112 1115 1116
3 591 1112 1116
3 591 1116 593
3 1113 1081 1117
3 1114 1113 1117
3 1114 1117 1118
3 1115 1114 1118
3 1115 1118 1119
3 1116 1115 1119
3 1116 1119 1120
3 593 1116 1120
3 593 1120 595
3 1117 1081 1121
3 1118 1117 1121
3 1118 1121 1122
3 1119 1118 1122
3 1119 1122 1123
3 1120 1119 1123
3 1120 1123 1124
3 595 1120 1124
3 595 1124 597
3 1121 1081 1125
3 1122 1121 1125
3 1122 1125 1126
3 1123 1122 1126
3 1123 1126 1127
3 1124 1123 1127
3 1124 1127 1128
3 597 1124 1128
3 597 1128 599
3 1125 1081 1129
3 1126 1125 1129
3 1126 1129 1130
3 1127 1126 1130
3 1127 1130 1131
3 1128 1127 1131
3 1128 1131 1132
3 599 1128 1132
3 599 1132 601
3 1129 1081 1133
3 1130 1129 1133
3 1130 1133 1134
3 1131 1130 1134
3 1131 1134 1135
3 1132 1131 1135
3 1132 1135 1136
3 601 1132 1136
3 601 1136 603
3 1133 1081 1137
3 1134 1133 1137
3 1134 1137 1138
3 1135 1134 1138
3 1135 1138 1139
3 1136 1135 1139
3 1136 1139 1140
3 603 1136 1140
3 603 1140 605
3 1137 1081 1141
3 1138 1137 1141
3 1138 1141 1142
3 1139 1138 1142
3 1139 1142 1143
3 1140 1139 1143
3 1140 1143 1144
3 605 1140 1144
3 605 1144 607
3 1141 1081 1145
3 1142 1141 1145
3 1142 1145 1146
3 1143 1142 1146
3 1143 1146 1147
3 1144 1143 1147
3 1144 1147 1148
3 607 1144 1148
3 607 1148 609
3 1145 1081 1149
3 1146 1145 1149
3 1146 1149 1150
3 1147 1146 1150
3 1147 1150 1151
3 1148 1147 1151
3 1148 1151 1152
3 609 1148 1152
3 609 1152 611
3 1149 1081 1153
3 1150 1149 1153
3 1150 1153 1154
3 1151 1150 1154
3 1151 1154 1155
3 1152 1151 1155
3 1152 1155 1156
3 611 1152 1156
3 611 1156 613
3 1153 1081 1157
3 1154 1153 1157
3 1154 1157 1158
3 1155 1154 1158
3 1155 1158 1159
3 1156 1155 1159
3 1156 1159 1160
3 613 1156 1160
3 613 1160 615
3 1157 1081 1161
3 1158 1157 1161
3 1158 1161 1162
3 1159 1158 1162
3 1159 1162 1163
3 1160 1159 1163
3 1160 1163 1164
3 615 1160 1164
3 615 1164 617
3 1161 1081 1165
3 1162 1161 1165
3 1162 1165 1166
3 1163 1162 1166
3 1163 1166 1167
3 1164 1163 1167
3 1164 1167 1168
3 617 1164 1168
3 617 1168 619
3 1165 1081 1169
3 1166 1165 1169
3 1166 1169 1170
3 1167 1166 1170
3 1167 1170 1171
3 1168 1167 1171
3 1168 1171 1172
3 619 1168 1172
3 619 1172 621
3 1169 1081 1173
3 1170 1169 1173
3 1170 1173 1174
3 1171 1170 1174
3 1171 1174 1175
3 1172 1171 1175
3 1172 1175 1176
3 621 1172 1176
3 621 1176 623
3 1173 1081 1080
3 1174 1173 1080
3 1174 1080 1083
3 1175 1174 1083
3 1175 1083 1085
3 1176 1175 1085
3 1176 1085 1087
3 623 1176 1087
3 623 1087 578


================================================
FILE: doc/katex-header.html
================================================
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"></script>
<script>
    document.addEventListener("DOMContentLoaded", function() {
        renderMathInElement(document.body, {
            delimiters: [
                { left: "$$", right: "$$", display: true },
                { left: "\\(", right: "\\)", display: false },
                { left: "$", right: "$", display: false },
                { left: "\\[", right: "\\]", display: true }
            ]
        });
    });
</script>


================================================
FILE: examples/sphere/Cargo.toml
================================================
[package]
name = "example-sphere"
version = "0.0.0"
edition = "2021"
authors = ["Sean Olson <olson.sean.k@gmail.com>"]
license = "MIT"
publish = false

[dependencies]
nalgebra = "^0.33.0"
theon = "^0.1.0"

[dependencies.pictor]
path = "../../pictor"

[dependencies.plexus]
path = "../../plexus"
default-features = false
features = [
    "encoding-ply",
    "geometry-nalgebra",
]


================================================
FILE: examples/sphere/src/main.rs
================================================
use nalgebra::Point3;
use pictor::pipeline::{self, Vertex};
use plexus::prelude::*;
use plexus::primitive;
use plexus::primitive::generate::{Normal, Position};
use plexus::primitive::sphere::UvSphere;
use theon::space::{EuclideanSpace, VectorSpace};

type E3 = Point3<f32>;

fn main() {
    let from = Point3::new(0.0, 0.0, 3.0);
    let to = Point3::origin();
    pipeline::render_mesh_buffer_with(from, to, move || {
        let sphere = UvSphere::new(32, 16);
        primitive::zip_vertices((
            sphere.polygons::<Position<E3>>().triangulate(),
            sphere.polygons::<Normal<E3>>().triangulate(),
        ))
        .map_vertices(|(position, normal)| Vertex {
            position: position.into_homogeneous().into(),
            normal: normal.into_inner().into_homogeneous().into(),
            color: [1.0, 0.6, 0.2, 1.0],
        })
        .collect()
    });
}


================================================
FILE: examples/subdivide/Cargo.toml
================================================
[package]
name = "example-subdivide"
version = "0.0.0"
edition = "2021"
authors = ["Sean Olson <olson.sean.k@gmail.com>"]
license = "MIT"
publish = false

[dependencies]
nalgebra = "^0.33.0"
smallvec = "^1.0.0"
theon = "^0.1.0"

[dependencies.pictor]
path = "../../pictor"

[dependencies.plexus]
path = "../../plexus"
default-features = false
features = ["geometry-nalgebra"]


================================================
FILE: examples/subdivide/src/main.rs
================================================
use nalgebra::Point3;
use pictor::pipeline::{self, Vertex};
use plexus::geometry::AsPositionMut;
use plexus::graph::{ClosedView, EdgeMidpoint, FaceView, GraphData, MeshGraph};
use plexus::prelude::*;
use plexus::primitive::Tetragon;
use smallvec::SmallVec;
use theon::space::{EuclideanSpace, VectorSpace};

type E3 = Point3<f32>;

pub trait Ambo<G>: ClosedView {
    #[must_use]
    fn ambo(self) -> Self;
}

impl<G> Ambo<G> for FaceView<&'_ mut MeshGraph<G>>
where
    G: EdgeMidpoint + GraphData,
    G::Vertex: AsPositionMut,
{
    // Subdivide the face with a polygon formed from vertices at the midpoints
    // of the edges of the face.
    fn ambo(self) -> Self {
        // Split each edge, stashing the vertex key and moving to the next arc.
        let arity = self.arity();
        let mut arc = self.into_arc();
        let mut splits = SmallVec::<[_; 4]>::with_capacity(arity);
        for _ in 0..arity {
            let vertex = arc.split_at_midpoint();
            splits.push(vertex.key());
            arc = vertex.into_outgoing_arc().into_next_arc();
        }
        // Split faces along the vertices from each arc split.
        let mut face = arc.into_face().unwrap();
        for (a, b) in splits.into_iter().perimeter() {
            face = face.split(a, b).unwrap().into_face().unwrap();
        }
        // Return the face forming the similar polygon.
        face
    }
}

fn main() {
    let from = Point3::new(-0.9, 3.1, 2.4);
    let to = Point3::new(0.0, 1.0, 0.0);
    pipeline::render_mesh_buffer_with(from, to, || {
        // Create a graph from a tetragon.
        let mut graph = MeshGraph::<E3>::from(Tetragon::from([
            (1.0, 0.0, -1.0),
            (-1.0, 0.0, -1.0),
            (-1.0, 0.0, 1.0),
            (1.0, 0.0, 1.0),
        ]));
        // Get the face of the tetragon.
        let key = graph.faces().next().unwrap().key();
        let mut face = graph.face_mut(key).unwrap();

        // Subdivide and extrude the face repeatedly.
        for _ in 0..5 {
            face = face.ambo().extrude_with_offset(0.5).unwrap();
        }

        // Convert the graph into a buffer.
        graph.triangulate();
        graph
            .to_mesh_by_face_with(|face, vertex| Vertex {
                position: vertex.position().into_homogeneous().into(),
                normal: face.normal().unwrap().into_homogeneous().into(),
                color: [1.0, 0.6, 0.2, 1.0],
            })
            .unwrap()
    });
}


================================================
FILE: examples/teapot/Cargo.toml
================================================
[package]
name = "example-teapot"
version = "0.0.0"
edition = "2021"
authors = ["Sean Olson <olson.sean.k@gmail.com>"]
license = "MIT"
publish = false

[dependencies]
nalgebra = "^0.33.0"
theon = "^0.1.0"

[dependencies.pictor]
path = "../../pictor"

[dependencies.plexus]
path = "../../plexus"
default-features = false
features = [
    "encoding-ply",
    "geometry-nalgebra",
]


================================================
FILE: examples/teapot/src/main.rs
================================================
use nalgebra::Point3;
use pictor::pipeline::{self, Vertex};
use plexus::encoding::ply::{FromPly, PositionEncoding};
use plexus::graph::MeshGraph;
use theon::space::{EuclideanSpace, VectorSpace};

type E3 = Point3<f32>;

fn main() {
    let from = Point3::new(0.0, -6.0, 4.0);
    let to = Point3::new(0.0, 0.0, 1.0);
    pipeline::render_mesh_buffer_with(from, to, move || {
        // Read PLY data into a graph.
        let ply: &[u8] = include_bytes!("../../../data/teapot.ply");
        let encoding = PositionEncoding::<E3>::default();
        let (graph, _) = MeshGraph::<E3>::from_ply(encoding, ply).expect("teapot");

        // Convert the graph into a buffer.
        graph
            .to_mesh_by_vertex_with(|vertex| Vertex {
                position: vertex.position().into_homogeneous().into(),
                normal: vertex.normal().unwrap().into_homogeneous().into(),
                color: [1.0, 0.6, 0.2, 1.0],
            })
            .expect("buffer")
    });
}


================================================
FILE: pictor/Cargo.toml
================================================
[package]
name = "pictor"
version = "0.0.0"
edition = "2021"
rust-version = "1.81.0"
authors = ["Sean Olson <olson.sean.k@gmail.com>"]
license = "MIT"
description = "Renderer and support library for Plexus examples."
publish = false

[dependencies]
bytemuck = "^1.13.0"
decorum = "^0.4.0"
naga = "^23.0.0"
nalgebra = "^0.33.0"
num = "^0.4.3"
rand = "^0.8.5"
theon = "^0.1.0"
winit = "^0.30.8"

[dependencies.futures]
version = "^0.3.31"
default-features = false
features = [
    "std",
    "executor",
]

[dependencies.plexus]
path = "../plexus"
default-features = false
features = ["geometry-nalgebra"]

[dependencies.wgpu]
version = "^23.0.1"
features = ["spirv"]


================================================
FILE: pictor/src/camera.rs
================================================
use nalgebra::{Isometry3, Matrix4, Orthographic3, Perspective3, Point3, Vector3};
use std::sync::LazyLock;
use wgpu::SurfaceConfiguration;

#[rustfmt::skip]
static OPENGL_TO_WGPU_TRANSFORM: LazyLock<Matrix4<f32>> = LazyLock::new(|| {
    Matrix4::new(
        1.0, 0.0, 0.0, 0.0,
        0.0, 1.0, 0.0, 0.0,
        0.0, 0.0, 0.5, 0.0,
        0.0, 0.0, 0.5, 1.0,
    )
});

#[derive(Clone, Debug)]
pub enum Projection {
    Perspective(Perspective3<f32>),
    Orthographic(Orthographic3<f32>),
}

impl Projection {
    pub fn perspective(aspect: f32, fov: f32, near: f32, far: f32) -> Self {
        Projection::Perspective(Perspective3::new(aspect, fov, near, far))
    }

    pub fn orthographic(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Self {
        Projection::Orthographic(Orthographic3::new(left, right, bottom, top, near, far))
    }
}

impl AsRef<Matrix4<f32>> for Projection {
    fn as_ref(&self) -> &Matrix4<f32> {
        match *self {
            Projection::Perspective(ref perspective) => perspective.as_matrix(),
            Projection::Orthographic(ref orthographic) => orthographic.as_matrix(),
        }
    }
}

#[derive(Clone, Debug)]
pub struct Camera {
    pub projection: Projection,
    view: Isometry3<f32>,
}

impl Camera {
    pub fn look_at(&mut self, from: &Point3<f32>, to: &Point3<f32>) {
        self.view = Isometry3::look_at_rh(from, to, &Vector3::y());
    }

    pub fn reproject(&mut self, surface: &SurfaceConfiguration) {
        match self.projection {
            Projection::Perspective(ref mut perspective) => {
                perspective.set_aspect(surface.width as f32 / surface.height as f32);
            }
            Projection::Orthographic(ref mut orthographic) => {
                let inverse = surface.height as f32 / surface.width as f32;
                let radius = (orthographic.right() - orthographic.left()) * inverse * 0.5;
                orthographic.set_bottom_and_top(-radius, radius);
            }
        }
    }

    pub fn transform(&self) -> Matrix4<f32> {
        *OPENGL_TO_WGPU_TRANSFORM * self.projection.as_ref() * self.view.to_homogeneous()
    }
}

impl From<Projection> for Camera {
    fn from(projection: Projection) -> Self {
        Camera {
            projection,
            view: Isometry3::look_at_rh(
                &Point3::new(0.0, 0.0, 1.0),
                &Point3::origin(),
                &Vector3::y(),
            ),
        }
    }
}


================================================
FILE: pictor/src/harness.rs
================================================
use futures::executor::{self, LocalPool, LocalSpawner};
use futures::task::LocalSpawn;
use std::cmp;
use std::fmt::Debug;
use std::sync::Arc;
use winit::application::ApplicationHandler;
use winit::dpi::PhysicalSize;
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
use winit::window::{Window, WindowAttributes, WindowId};

use crate::renderer::Renderer;

#[derive(Debug)]
struct Executor {
    pool: LocalPool,
    spawner: LocalSpawner,
}

impl Executor {
    pub fn new() -> Self {
        let pool = LocalPool::new();
        let spawner = pool.spawner();
        Executor { pool, spawner }
    }

    pub fn flush(&mut self) {
        self.pool.run_until_stalled()
    }

    pub fn spawner(&self) -> &impl LocalSpawn {
        &self.spawner
    }
}

#[derive(Debug)]
struct Activity<T> {
    window: Arc<Window>,
    renderer: Renderer<'static>,
    application: T,
}

impl<T> Activity<T>
where
    T: Application,
{
    pub fn bind_and_configure(window: Window, configuration: T::Configuration) -> Self {
        let window = Arc::new(window);
        let renderer = executor::block_on(Renderer::try_from_window(window.clone())).unwrap();
        let application = T::configure(configuration, &renderer).unwrap();
        Activity {
            window,
            renderer,
            application,
        }
    }
}

#[derive(Debug)]
struct Harness<T, F> {
    executor: Executor,
    f: F,
    activity: Option<Activity<T>>,
}

impl<T, F> Harness<T, F>
where
    T: Application,
{
    fn redraw(&mut self) {
        if let Some(activity) = self.activity.as_mut() {
            let frame = activity.renderer.surface.get_current_texture().unwrap();
            let view = frame
                .texture
                .create_view(&wgpu::TextureViewDescriptor::default());
            activity
                .application
                .render(&activity.renderer, &view, self.executor.spawner());
            frame.present();
        }
    }

    fn resize(&mut self, dimensions: PhysicalSize<u32>) {
        if let Some(activity) = self.activity.as_mut() {
            activity.renderer.surface_configuration.width = cmp::max(1, dimensions.width);
            activity.renderer.surface_configuration.height = cmp::max(1, dimensions.height);
            activity.application.resize(&activity.renderer);
            activity.renderer.surface.configure(
                &activity.renderer.device,
                &activity.renderer.surface_configuration,
            );
            activity.window.request_redraw();
        }
    }
}

impl<T, F> ApplicationHandler<()> for Harness<T, F>
where
    T: Application,
    F: FnMut() -> (WindowAttributes, T::Configuration),
{
    fn resumed(&mut self, reactor: &ActiveEventLoop) {
        let (window, configuration) = (self.f)();
        self.activity.replace(Activity::bind_and_configure(
            reactor.create_window(window).unwrap(),
            configuration,
        ));
    }

    fn suspended(&mut self, _reactor: &ActiveEventLoop) {
        self.activity.take();
    }

    fn window_event(&mut self, reactor: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
        match event {
            WindowEvent::RedrawRequested => {
                self.redraw();
            }
            WindowEvent::CloseRequested => {
                reactor.exit();
            }
            WindowEvent::Resized(dimensions) => {
                self.resize(dimensions);
            }
            _ => {
                if let Some(activity) = self.activity.as_mut() {
                    if let Reaction::Abort = activity.application.react(event) {
                        reactor.exit();
                    }
                }
            }
        }
        self.executor.flush();
    }
}

#[derive(Clone, Copy, Debug, Default)]
pub enum Reaction {
    #[default]
    Continue,
    Abort,
}

pub trait ConfigureStage {
    fn device(&self) -> &wgpu::Device;

    fn queue(&self) -> &wgpu::Queue;

    fn surface_configuration(&self) -> &wgpu::SurfaceConfiguration;
}

pub trait RenderStage {
    fn device(&self) -> &wgpu::Device;

    fn queue(&self) -> &wgpu::Queue;
}

pub trait Application: 'static + Sized {
    type Configuration: Sized;
    type Error: Debug;

    fn configure(
        configuration: Self::Configuration,
        stage: &impl ConfigureStage,
    ) -> Result<Self, Self::Error>;

    fn react(&mut self, event: WindowEvent) -> Reaction {
        let _ = event;
        Reaction::Continue
    }

    fn resize(&mut self, stage: &impl ConfigureStage);

    fn render(
        &mut self,
        stage: &impl RenderStage,
        view: &wgpu::TextureView,
        spawn: &impl LocalSpawn,
    );
}

pub fn run<T, F>(f: F)
where
    T: Application,
    F: FnMut() -> (WindowAttributes, T::Configuration),
{
    let executor = Executor::new();
    let reactor = EventLoop::new().unwrap();
    reactor.set_control_flow(ControlFlow::Poll);
    reactor
        .run_app(&mut Harness::<T, _> {
            executor,
            f,
            activity: None,
        })
        .unwrap();
}


================================================
FILE: pictor/src/lib.rs
================================================
mod camera;
mod harness;
pub mod pipeline;
mod renderer;

pub use crate::camera::*;
pub use crate::harness::*;

// TODO: Compile shaders from source code rather than statically loading binary SpirV.


================================================
FILE: pictor/src/pipeline.rs
================================================
use bytemuck::{self, Pod, Zeroable};
use decorum::cmp::CanonicalEq;
use decorum::hash::CanonicalHash;
use futures::task::LocalSpawn;
use nalgebra::{Point3, Scalar, Vector3, Vector4};
use num::{self, One};
use plexus::buffer::MeshBuffer;
use plexus::geometry::UnitGeometry;
use plexus::index::Flat3;
use rand::distributions::{Distribution, Standard};
use rand::{self, Rng};
use std::f32::consts::FRAC_PI_4;
use std::hash::{Hash, Hasher};
use std::mem;
use theon::adjunct::Extend;
use wgpu::include_spirv_raw;
use wgpu::util::DeviceExt as _;
use winit::event::{ElementState, KeyEvent, WindowEvent};
use winit::keyboard::{Key, NamedKey};
use winit::window::Window;

use crate::camera::{Camera, Projection};
use crate::harness::{self, Application, ConfigureStage, Reaction, RenderStage};

use Reaction::Abort;
use Reaction::Continue;

#[derive(Clone, Copy, Debug)]
pub struct Color4<T>(pub Vector4<T>)
where
    T: Scalar;

impl<T> Color4<T>
where
    T: Scalar,
{
    pub fn white() -> Self
    where
        T: One,
    {
        Color4(Vector4::repeat(One::one()))
    }

    pub fn random() -> Self
    where
        T: One,
        Standard: Distribution<T>,
        Vector3<T>: Extend<Vector4<T>, Item = T>,
    {
        let mut rng = rand::thread_rng();
        Color4(Vector3::from_fn(|_, _| rng.gen()).extend(One::one()))
    }
}

impl<T> AsRef<Vector4<T>> for Color4<T>
where
    T: Scalar,
{
    fn as_ref(&self) -> &Vector4<T> {
        &self.0
    }
}

impl<T> Default for Color4<T>
where
    T: One + Scalar,
{
    fn default() -> Self {
        Color4::white()
    }
}

impl<T> From<Vector4<T>> for Color4<T>
where
    T: Scalar,
{
    fn from(vector: Vector4<T>) -> Self {
        Color4(vector)
    }
}

impl<T> From<Color4<T>> for Vector4<T>
where
    T: Scalar,
{
    fn from(color: Color4<T>) -> Self {
        color.0
    }
}

impl<T> UnitGeometry for Color4<T> where T: One + Scalar {}

#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Vertex {
    pub position: [f32; 4],
    pub normal: [f32; 4],
    pub color: [f32; 4],
}

impl Eq for Vertex {}

impl Hash for Vertex {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        self.position.hash_canonical(state);
        self.normal.hash_canonical(state);
        self.color.hash_canonical(state);
    }
}

impl PartialEq for Vertex {
    fn eq(&self, other: &Self) -> bool {
        self.position.eq_canonical(&other.position)
            && self.normal.eq_canonical(&other.normal)
            && self.color.eq_canonical(&other.color)
    }
}

// SAFETY: This type is inhabited, is `repr(C)`, has no padding, has no illegal bit patterns,
//         contains no pointers, and has only fields that are also `Pod`.
unsafe impl Pod for Vertex {}

// SAFETY: This type has a zeroed inhabitant.
unsafe impl Zeroable for Vertex {}

#[derive(Debug)]
struct RenderConfiguration {
    camera: Camera,
    from: Point3<f32>,
    buffer: MeshBuffer<Flat3<u32>, Vertex>,
}

#[derive(Debug)]
struct RenderApplication {
    camera: Camera,
    _viewpoint: wgpu::Buffer,
    transform: wgpu::Buffer,
    vertices: wgpu::Buffer,
    indices: wgpu::Buffer,
    depth: wgpu::TextureView,
    n: u32,
    bind_group: wgpu::BindGroup,
    pipeline: wgpu::RenderPipeline,
}

impl RenderApplication {
    fn configure_depth_buffer(stage: &impl ConfigureStage) -> wgpu::TextureView {
        stage
            .device()
            .create_texture(&wgpu::TextureDescriptor {
                label: None,
                view_formats: stage.surface_configuration().view_formats.as_slice(),
                size: wgpu::Extent3d {
                    width: stage.surface_configuration().width,
                    height: stage.surface_configuration().height,
                    depth_or_array_layers: 1,
                },
                mip_level_count: 1,
                sample_count: 1,
                dimension: wgpu::TextureDimension::D2,
                format: wgpu::TextureFormat::Depth32Float,
                usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::RENDER_ATTACHMENT,
            })
            .create_view(&Default::default())
    }
}

impl Application for RenderApplication {
    type Configuration = RenderConfiguration;
    type Error = ();

    fn configure(
        configuration: Self::Configuration,
        stage: &impl ConfigureStage,
    ) -> Result<Self, Self::Error> {
        let RenderConfiguration {
            mut camera,
            from,
            buffer,
        } = configuration;
        camera.reproject(stage.surface_configuration());
        let vertices = stage
            .device()
            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
                label: None,
                contents: bytemuck::cast_slice(buffer.as_vertex_slice()),
                usage: wgpu::BufferUsages::VERTEX,
            });
        let indices = stage
            .device()
            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
                label: None,
                contents: bytemuck::cast_slice(buffer.as_index_slice()),
                usage: wgpu::BufferUsages::INDEX,
            });
        let transform = stage
            .device()
            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
                label: None,
                contents: bytemuck::cast_slice(camera.transform().as_slice()),
                usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM,
            });
        let viewpoint = stage
            .device()
            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
                label: None,
                contents: bytemuck::cast_slice(from.coords.as_slice()),
                usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM,
            });
        let depth = Self::configure_depth_buffer(stage);
        let bind_group_layout =
            stage
                .device()
                .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                    label: None,
                    entries: &[
                        wgpu::BindGroupLayoutEntry {
                            binding: 0,
                            visibility: wgpu::ShaderStages::VERTEX,
                            ty: wgpu::BindingType::Buffer {
                                ty: wgpu::BufferBindingType::Uniform,
                                has_dynamic_offset: false,
                                min_binding_size: wgpu::BufferSize::new(64),
                            },
                            count: None,
                        },
                        wgpu::BindGroupLayoutEntry {
                            binding: 1,
                            visibility: wgpu::ShaderStages::VERTEX,
                            ty: wgpu::BindingType::Buffer {
                                ty: wgpu::BufferBindingType::Uniform,
                                has_dynamic_offset: false,
                                min_binding_size: wgpu::BufferSize::new(12),
                            },
                            count: None,
                        },
                    ],
                });
        let bind_group = stage
            .device()
            .create_bind_group(&wgpu::BindGroupDescriptor {
                label: None,
                layout: &bind_group_layout,
                entries: &[
                    wgpu::BindGroupEntry {
                        binding: 0,
                        resource: transform.as_entire_binding(),
                    },
                    wgpu::BindGroupEntry {
                        binding: 1,
                        resource: viewpoint.as_entire_binding(),
                    },
                ],
            });
        let pipeline = stage
            .device()
            .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
                label: None,
                layout: Some(&stage.device().create_pipeline_layout(
                    &wgpu::PipelineLayoutDescriptor {
                        label: None,
                        bind_group_layouts: &[&bind_group_layout],
                        push_constant_ranges: &[],
                    },
                )),
                vertex: wgpu::VertexState {
                    module: unsafe {
                        &stage
                            .device()
                            .create_shader_module_spirv(&include_spirv_raw!("shader.spv.vert"))
                    },
                    entry_point: Some("main"),
                    compilation_options: Default::default(),
                    buffers: &[wgpu::VertexBufferLayout {
                        array_stride: mem::size_of::<Vertex>() as wgpu::BufferAddress,
                        step_mode: wgpu::VertexStepMode::Vertex,
                        // LINT: The constants in these trivial expressions illustrate the sizing
                        //       and layout of the data more clearly than the evaluation alone.
                        attributes: &[
                            #[expect(clippy::erasing_op)]
                            wgpu::VertexAttribute {
                                format: wgpu::VertexFormat::Float32x4,
                                offset: 0 * 4 * 4,
                                shader_location: 0,
                            },
                            #[expect(clippy::identity_op)]
                            wgpu::VertexAttribute {
                                format: wgpu::VertexFormat::Float32x4,
                                offset: 1 * 4 * 4,
                                shader_location: 1,
                            },
                            wgpu::VertexAttribute {
                                format: wgpu::VertexFormat::Float32x4,
                                offset: 2 * 4 * 4,
                                shader_location: 2,
                            },
                        ],
                    }],
                },
                fragment: Some(wgpu::FragmentState {
                    module: unsafe {
                        &stage
                            .device()
                            .create_shader_module_spirv(&include_spirv_raw!("shader.spv.frag"))
                    },
                    entry_point: Some("main"),
                    compilation_options: Default::default(),
                    targets: &[Some(wgpu::ColorTargetState {
                        format: stage.surface_configuration().format,
                        blend: Some(wgpu::BlendState {
                            color: wgpu::BlendComponent::REPLACE,
                            alpha: wgpu::BlendComponent::REPLACE,
                        }),
                        write_mask: wgpu::ColorWrites::ALL,
                    })],
                }),
                depth_stencil: Some(wgpu::DepthStencilState {
                    format: wgpu::TextureFormat::Depth32Float,
                    depth_write_enabled: true,
                    depth_compare: wgpu::CompareFunction::Less,
                    stencil: Default::default(),
                    bias: Default::default(),
                }),
                primitive: wgpu::PrimitiveState {
                    topology: wgpu::PrimitiveTopology::TriangleList,
                    front_face: wgpu::FrontFace::Ccw,
                    cull_mode: Some(wgpu::Face::Back),
                    ..Default::default()
                },
                multisample: Default::default(),
                multiview: None,
                cache: None,
            });
        Ok(RenderApplication {
            camera,
            _viewpoint: viewpoint,
            transform,
            vertices,
            indices,
            depth,
            n: buffer.as_index_slice().len() as u32,
            bind_group,
            pipeline,
        })
    }

    fn react(&mut self, event: WindowEvent) -> Reaction {
        match event {
            WindowEvent::KeyboardInput {
                event:
                    KeyEvent {
                        logical_key: Key::Named(NamedKey::Escape),
                        state: ElementState::Pressed,
                        ..
                    },
                ..
            } => Abort,
            _ => Continue,
        }
    }

    fn resize(&mut self, stage: &impl ConfigureStage) {
        self.camera.reproject(stage.surface_configuration());
        stage.queue().write_buffer(
            &self.transform,
            0,
            bytemuck::cast_slice(self.camera.transform().as_slice()),
        );
        self.depth = Self::configure_depth_buffer(stage);
    }

    fn render(&mut self, stage: &impl RenderStage, view: &wgpu::TextureView, _: &impl LocalSpawn) {
        let mut encoder = stage
            .device()
            .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
        let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                view,
                resolve_target: None,
                ops: wgpu::Operations {
                    load: wgpu::LoadOp::Clear(wgpu::Color {
                        r: 0.1,
                        g: 0.2,
                        b: 0.3,
                        a: 1.0,
                    }),
                    store: wgpu::StoreOp::Store,
                },
            })],
            depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
                view: &self.depth,
                depth_ops: Some(wgpu::Operations {
                    load: wgpu::LoadOp::Clear(1.0),
                    store: wgpu::StoreOp::Store,
                }),
                stencil_ops: None,
            }),
            ..Default::default()
        });
        pass.set_pipeline(&self.pipeline);
        pass.set_bind_group(0, &self.bind_group, &[]);
        pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint32);
        pass.set_vertex_buffer(0, self.vertices.slice(..));
        pass.draw_indexed(0..self.n, 0, 0..1);

        drop(pass); // Release `encoder`.
        stage.queue().submit(Some(encoder.finish()));
    }
}

pub fn render_mesh_buffer_with<F>(from: Point3<f32>, to: Point3<f32>, mut f: F)
where
    F: FnMut() -> MeshBuffer<Flat3<u32>, Vertex>,
{
    let camera = {
        let mut camera = Camera::from(Projection::perspective(1.0, FRAC_PI_4, 0.1, 8.0));
        //let mut camera = Camera::from(Projection::orthographic(-4.0, 4.0, -4.0, 4.0, -8.0, 8.0));
        camera.look_at(&from, &to);
        camera
    };
    harness::run::<RenderApplication, _>(move || {
        (
            Window::default_attributes().with_title("Plexus"),
            RenderConfiguration {
                camera: camera.clone(),
                from,
                buffer: f(),
            },
        )
    })
}


================================================
FILE: pictor/src/renderer.rs
================================================
use std::borrow::Borrow;
use winit::window::Window;

use crate::harness::{ConfigureStage, RenderStage};

#[derive(Debug)]
pub struct Renderer<'window> {
    _instance: wgpu::Instance,
    _adapter: wgpu::Adapter,
    pub surface: wgpu::Surface<'window>,
    pub surface_configuration: wgpu::SurfaceConfiguration,
    pub device: wgpu::Device,
    queue: wgpu::Queue,
}

impl<'window> Renderer<'window> {
    pub async fn try_from_window<T>(window: T) -> Result<Self, ()>
    where
        T: Borrow<Window> + Into<wgpu::SurfaceTarget<'window>>,
    {
        let dimensions = window.borrow().inner_size();
        let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
        let surface = instance.create_surface(window).unwrap();
        let adapter = instance
            .request_adapter(&wgpu::RequestAdapterOptions {
                compatible_surface: Some(&surface),
                ..Default::default()
            })
            .await
            .ok_or(())?;
        let (device, queue) = adapter
            .request_device(
                &wgpu::DeviceDescriptor {
                    required_features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
                    required_limits: wgpu::Limits::downlevel_webgl2_defaults()
                        .using_resolution(adapter.limits()),
                    memory_hints: wgpu::MemoryHints::MemoryUsage,
                    ..Default::default()
                },
                None,
            )
            .await
            .map_err(|_| ())?;
        let surface_configuration = surface
            .get_default_config(&adapter, dimensions.width, dimensions.height)
            .unwrap();
        Ok(Renderer {
            _instance: instance,
            _adapter: adapter,
            surface,
            surface_configuration,
            device,
            queue,
        })
    }
}

impl ConfigureStage for Renderer<'_> {
    fn device(&self) -> &wgpu::Device {
        &self.device
    }

    fn queue(&self) -> &wgpu::Queue {
        &self.queue
    }

    fn surface_configuration(&self) -> &wgpu::SurfaceConfiguration {
        &self.surface_configuration
    }
}

impl RenderStage for Renderer<'_> {
    fn device(&self) -> &wgpu::Device {
        &self.device
    }

    fn queue(&self) -> &wgpu::Queue {
        &self.queue
    }
}


================================================
FILE: pictor/src/shader.glsl.frag
================================================
#version 450

layout(location = 0) in vec4 v_color;

layout(location = 0) out vec4 f_target0;

void main() {
    f_target0 = v_color;
}


================================================
FILE: pictor/src/shader.glsl.vert
================================================
#version 450

layout(location = 0) in vec4 a_position;
layout(location = 1) in vec4 a_normal;
layout(location = 2) in vec4 a_color;

layout(set = 0, binding = 0) uniform transform {
    mat4 u_transform;
};
layout(set = 0, binding = 1) uniform viewpoint {
    vec3 u_viewpoint;
};

layout(location = 0) out vec4 v_color;

void main() {
    v_color = a_color * vec4(vec3(max(0.0, dot(vec3(a_normal), normalize(u_viewpoint - vec3(a_position))))), 1.0);
    gl_Position = u_transform * a_position;
}


================================================
FILE: plexus/Cargo.toml
================================================
[package]
name = "plexus"
version = "0.0.11"
edition = "2021"
rust-version = "1.81.0"
authors = ["Sean Olson <olson.sean.k@gmail.com>"]
license = "MIT"
readme = "../README.md"
homepage = "https://plexus.rs"
repository = "https://github.com/olson-sean-k/plexus"
description = "Polygonal mesh processing."
keywords = [
    "polygon",
    "mesh",
    "topology",
    "geometry",
    "half-edge",
]
categories = [
    "algorithms",
    "data-structures",
    "graphics",
    "rendering::data-formats",
]

[package.metadata.docs.rs]
# Enable all features for API documentation.
all-features = true
# Enable KaTeX support by injecting a header into the documentation.
rustdoc-args = [
    "--html-in-header",
    "../doc/katex-header.html",
]

[[bench]]
name = "subdivide"
harness = false
path = "../benches/subdivide.rs"

[features]
default = []
encoding-ply = ["dep:ply-rs"]
geometry-cgmath = [
    "dep:cgmath",
    "theon/cgmath",
]
geometry-glam = [
    "dep:glam",
    "theon/glam",
]
geometry-mint = [
    "dep:mint",
    "theon/mint",
]
geometry-nalgebra = [
    "dep:nalgebra",
    "theon/nalgebra",
]
geometry-ultraviolet = [
    "dep:ultraviolet",
    "theon/ultraviolet",
]

[dependencies]
approx = "^0.5.0"
ahash = "^0.8.11"
arrayvec = "^0.7.6"
derivative = "^2.1.1"
itertools = "^0.14.0"
num = "^0.4.3"
smallvec = "^1.0.0"
thiserror = "^2.0.10"
typenum = "^1.17.0"

[dependencies.cgmath]
version = "^0.18.0"
optional = true

[dependencies.decorum]
version = "^0.4.0"
default-features = false
features = [
    "approx",
    "serde",
    "std",
]

[dependencies.glam]
version = "^0.29.0"
optional = true

[dependencies.mint]
version = "^0.5.0"
optional = true

[dependencies.nalgebra]
version = "^0.33.0"
optional = true

[dependencies.ply-rs]
version = "^0.1.2"
optional = true

[dependencies.theon]
version = "^0.1.0"
default-features = false
features = ["lapack"]

[dependencies.ultraviolet]
version = "^0.9.0"
optional = true

[build-dependencies]
rustversion = "^1.0.3"

[dev-dependencies]
criterion = "^0.5.1"
# For brevity and simplicity, tests and API documentation use a direct
# dependency on `nalgebra`. This approach requires that the version
# specification is compatible with `theon`.
nalgebra = "^0.33.0"

[dev-dependencies.theon]
version = "^0.1.0"
default-features = false
features = [
    "lapack",
    "nalgebra",
]


================================================
FILE: plexus/src/buffer/builder.rs
================================================
use num::{Integer, NumCast, Unsigned};
use std::hash::Hash;
use typenum::NonZero;

use crate::buffer::{BufferError, MeshBuffer};
use crate::builder::{FacetBuilder, MeshBuilder, SurfaceBuilder};
use crate::constant::{Constant, ToType, TypeOf};
use crate::geometry::{FromGeometry, IntoGeometry};
use crate::index::{Flat, Grouping, IndexBuffer};
use crate::primitive::Topological;
use crate::transact::{ClosedInput, Transact};
use crate::Arity;

// TODO: It should not be possible to manufacture keys without placing
//       additional constraints on the type bounds of `FacetBuilder` (for
//       example, `FacetBuilder<Key = usize>`). Is it important to check for
//       out-of-bounds indices in `insert_facet`?

pub type VertexKey<R> = <Vec<<R as Grouping>::Group> as IndexBuffer<R>>::Index;

pub struct BufferBuilder<R, G>
where
    R: Grouping,
{
    indices: Vec<R::Group>,
    vertices: Vec<G>,
}

impl<R, G> Default for BufferBuilder<R, G>
where
    R: Grouping,
    Vec<R::Group>: IndexBuffer<R>,
{
    fn default() -> Self {
        BufferBuilder {
            indices: Default::default(),
            vertices: Default::default(),
        }
    }
}

impl<R, G> ClosedInput for BufferBuilder<R, G>
where
    R: Grouping,
    Vec<R::Group>: IndexBuffer<R>,
{
    type Input = ();
}

impl<K, G, const N: usize> FacetBuilder<K> for BufferBuilder<Flat<K, N>, G>
where
    Constant<N>: ToType,
    TypeOf<N>: NonZero,
    K: Copy + Hash + Integer + Unsigned,
    Vec<K>: IndexBuffer<Flat<K, N>>,
{
    type Facet = ();
    type Key = ();

    fn insert_facet<T, U>(&mut self, keys: T, _: U) -> Result<Self::Key, Self::Error>
    where
        Self::Facet: FromGeometry<U>,
        T: AsRef<[K]>,
    {
        let keys = keys.as_ref();
        if keys.len() == N {
            self.indices.extend(keys.iter());
            Ok(())
        }
        else {
            // TODO: These numbers do not necessarily represent arity (i.e., the
            //       number of edges of each topological structure). Use a
            //       different error variant to express this.
            Err(BufferError::ArityConflict {
                expected: N,
                actual: keys.len(),
            })
        }
    }
}

impl<P, G> FacetBuilder<P::Vertex> for BufferBuilder<P, G>
where
    P: Grouping<Group = P> + Topological,
    P::Vertex: Copy + Hash + Integer + Unsigned,
    Vec<P>: IndexBuffer<P>,
{
    type Facet = ();
    type Key = ();

    fn insert_facet<T, U>(&mut self, keys: T, _: U) -> Result<Self::Key, Self::Error>
    where
        Self::Facet: FromGeometry<U>,
        T: AsRef<[P::Vertex]>,
    {
        let arity = keys.as_ref().len();
        P::try_from_slice(keys)
            .ok_or(BufferError::ArityConflict {
                expected: P::ARITY.into_interval().0,
                actual: arity,
            })
            .map(|polygon| self.indices.push(polygon))
    }
}

impl<R, G> MeshBuilder for BufferBuilder<R, G>
where
    Self: SurfaceBuilder<Vertex = G, Facet = ()>,
    R: Grouping,
    VertexKey<R>: Hash,
    Vec<R::Group>: IndexBuffer<R>,
{
    type Builder = Self;

    type Vertex = G;
    type Facet = ();

    fn surface_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
    where
        Self::Error: From<E>,
        F: FnOnce(&mut Self::Builder) -> Result<T, E>,
    {
        f(self).map_err(|error| error.into())
    }
}

impl<R, G> SurfaceBuilder for BufferBuilder<R, G>
where
    Self: FacetBuilder<VertexKey<R>, Facet = ()>,
    Self::Error: From<BufferError>, // TODO: Why is this necessary?
    R: Grouping,
    VertexKey<R>: Hash + NumCast,
    Vec<R::Group>: IndexBuffer<R>,
{
    type Builder = Self;
    type Key = VertexKey<R>;

    type Vertex = G;
    type Facet = ();

    fn facets_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
    where
        Self::Error: From<E>,
        F: FnOnce(&mut Self::Builder) -> Result<T, E>,
    {
        f(self).map_err(|error| error.into())
    }

    fn insert_vertex<T>(&mut self, data: T) -> Result<Self::Key, Self::Error>
    where
        Self::Vertex: FromGeometry<T>,
    {
        let key = <VertexKey<R> as NumCast>::from(self.vertices.len())
            .ok_or(BufferError::IndexOverflow)?;
        self.vertices.push(data.into_geometry());
        Ok(key)
    }
}

impl<R, G> Transact<<Self as ClosedInput>::Input> for BufferBuilder<R, G>
where
    R: Grouping,
    Vec<R::Group>: IndexBuffer<R>,
{
    type Commit = MeshBuffer<R, G>;
    type Abort = ();
    type Error = BufferError;

    fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
        let BufferBuilder { indices, vertices } = self;
        Ok(MeshBuffer::from_raw_buffers_unchecked(indices, vertices))
    }

    fn abort(self) -> Self::Abort {}
}


================================================
FILE: plexus/src/buffer/mod.rs
================================================
//! Linear representations of polygonal meshes.
//!
//! This module provides types and traits that describe polygonal meshes as
//! buffers of vertex data and buffers of indices into that vertex data. These
//! buffers are called the _vertex buffer_ and _index buffer_, respectively, and
//! are typically used for indexed drawing. The [`MeshBuffer`] type unifies
//! vertex and index buffers and maintains their consistency.
//!
//! Note that only _composite_ vertex buffers are supported, in which each
//! element of a vertex buffer completely describes all attributes of a vertex.
//! Plexus does not support _component_ buffers, in which each attribute of a
//! vertex is stored in a dedicated buffer.
//!
//! Plexus refers to independent vertex and index buffers as _raw buffers_. For
//! example, a [`Vec`] of index data is a raw buffer and can be modified without
//! regard to consistency with any particular vertex buffer. The
//! [`FromRawBuffers`] trait provides a way to construct mesh data structures
//! from such raw buffers.
//!
//! Index buffers may contain either _flat_ or _structured_ data. See the
//! [`index`] module for more about these buffers and how they are defined.
//!
//! # Examples
//!
//! Generating a flat [`MeshBuffer`] from a [$uv$-sphere][`UvSphere`]:
//!
//! ```rust
//! # extern crate decorum;
//! # extern crate nalgebra;
//! # extern crate plexus;
//! #
//! use decorum::R32;
//! use nalgebra::Point3;
//! use plexus::buffer::MeshBuffer3;
//! use plexus::prelude::*;
//! use plexus::primitive::generate::Position;
//! use plexus::primitive::sphere::UvSphere;
//!
//! let buffer: MeshBuffer3<u32, Point3<f32>> = UvSphere::new(16, 16)
//!     .polygons::<Position<Point3<R32>>>()
//!     .triangulate()
//!     .collect();
//! let indices = buffer.as_index_slice();
//! let positions = buffer.as_vertex_slice();
//! ```
//!
//! Converting a [`MeshGraph`] to a structured [`MeshBuffer`]:
//!
//! ```rust
//! # extern crate decorum;
//! # extern crate nalgebra;
//! # extern crate plexus;
//! #
//! use decorum::R64;
//! use nalgebra::Point3;
//! use plexus::buffer::MeshBufferN;
//! use plexus::graph::MeshGraph;
//! use plexus::prelude::*;
//! use plexus::primitive::cube::Cube;
//! use plexus::primitive::generate::Position;
//!
//! type E3 = Point3<R64>;
//!
//! let graph: MeshGraph<E3> = Cube::new().polygons::<Position<E3>>().collect();
//! let buffer: MeshBufferN<usize, E3> = graph.to_mesh_by_vertex().unwrap();
//! ```
//!
//! [`Vec`]: std::vec::Vec
//! [`FromRawBuffers`]: crate::buffer::FromRawBuffers
//! [`MeshBuffer`]: crate::buffer::MeshBuffer
//! [`MeshGraph`]: crate::graph::MeshGraph
//! [`index`]: crate::index
//! [`UvSphere`]: crate::primitive::sphere::UvSphere

// `MeshBuffer`s must convert and sum indices into their vertex data. Some of
// these conversions may fail, but others are never expected to fail, because of
// invariants enforced by `MeshBuffer`.
//
// Index types require `Unsigned` and `Vec` capacity is limited by word size
// (the width of `usize`). An overflow cannot occur in some contexts, because a
// consistent `MeshBuffer` cannot index into a `Vec` with an index larger than
// its maximum addressable capacity (the maximum value that `usize` can
// represent).

// TODO: More consistently `expect` or `ok_or` index conversions and sums.

mod builder;

use itertools::Itertools;
use num::{Integer, NumCast, Unsigned};
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::FromIterator;
use std::vec;
use theon::adjunct::Map;
use thiserror::Error;
use typenum::{self, NonZero, Unsigned as _, U3, U4};

use crate::buffer::builder::BufferBuilder;
use crate::builder::{Buildable, MeshBuilder};
use crate::constant::{Constant, ToType, TypeOf};
use crate::encoding::{FaceDecoder, FromEncoding, VertexDecoder};
use crate::geometry::{FromGeometry, IntoGeometry};
use crate::index::{
    BufferOf, Flat, Flat3, Flat4, FromIndexer, Grouping, HashIndexer, IndexBuffer, IndexOf,
    IndexVertices, Indexer, Push,
};
use crate::primitive::decompose::IntoVertices;
use crate::primitive::{
    BoundedPolygon, IntoIndexed, IntoPolygons, Polygonal, Tetragon, Topological, Trigon,
    UnboundedPolygon,
};
use crate::{Arity, DynamicArity, MeshArity, Monomorphic, StaticArity, TryFromIterator};

/// Errors concerning raw buffers and [`MeshBuffer`]s.
///
/// [`MeshBuffer`]: crate::buffer::MeshBuffer
#[derive(Debug, Eq, Error, PartialEq)]
pub enum BufferError {
    /// An index into vertex data is out of bounds.
    ///
    /// This error occurs when an index read from an index buffer is out of
    /// bounds of the vertex buffer it indexes.
    #[error("index into vertex data out of bounds")]
    IndexOutOfBounds,
    /// The computation of an index causes an overflow.
    ///
    /// This error occurs if the result of computing an index overflows the type
    /// used to represent indices. For example, if the elements of an index
    /// buffer are `u8`s and an operation results in indices greater than
    /// [`u8::MAX`], then this error will occur.
    ///
    /// [`u8::MAX`]: std::u8::MAX
    #[error("index overflow")]
    IndexOverflow,
    #[error("index buffer conflicts with arity")]
    /// The number of indices in a flat index buffer is incompatible with the
    /// arity of the buffer.
    ///
    /// This error may occur if a flat index buffer contains a number of indices
    /// that is indivisible by the arity of the topology it represents. For
    /// example, this may error occur if a triangular index buffer contains a
    /// number of indices that is not divisible by three.
    IndexUnaligned,
    /// The arity of a buffer or other data structure is not compatible with an
    /// operation.
    #[error("conflicting arity; expected {expected}, but got {actual}")]
    ArityConflict {
        /// The expected arity.
        expected: usize,
        /// The incompatible arity that was encountered.
        actual: usize,
    },
}

/// Triangular [`MeshBuffer`].
///
/// The index buffer for this type contains [`Trigon`]s. For applications where
/// a flat index buffer is necessary, consider [`IntoFlatIndex`] or the
/// [`Flat3`] meta-grouping.
///
/// [`IntoFlatIndex`]: crate::buffer::IntoFlatIndex
/// [`MeshBuffer`]: crate::buffer::MeshBuffer
/// [`Flat3`]: crate::index::Flat3
/// [`Trigon`]: crate::primitive::Trigon
pub type MeshBuffer3<N, G> = MeshBuffer<Trigon<N>, G>;

/// Quadrilateral [`MeshBuffer`].
///
/// The index buffer for this type contains [`Tetragon`]s. For applications
/// where a flat index buffer is necessary, consider [`IntoFlatIndex`] or the
/// [`Flat4`] meta-grouping.
///
/// [`IntoFlatIndex`]: crate::buffer::IntoFlatIndex
/// [`MeshBuffer`]: crate::buffer::MeshBuffer
/// [`Flat4`]: crate::index::Flat4
/// [`Tetragon`]: crate::primitive::Tetragon
pub type MeshBuffer4<N, G> = MeshBuffer<Tetragon<N>, G>;

/// [`MeshBuffer`] that supports polygons with arbitrary [arity][`Arity`].
///
/// [`MeshBuffer`]: crate::buffer::MeshBuffer
/// [`Arity`]: crate::Arity
pub type MeshBufferN<N, G> = MeshBuffer<UnboundedPolygon<N>, G>;

/// Conversion from raw buffers.
pub trait FromRawBuffers<N, G>: Sized {
    type Error: Debug;

    /// Creates a type from raw buffers.
    ///
    /// # Errors
    ///
    /// Returns an error if the raw buffers are inconsistent or the implementor
    /// cannot be constructed from the buffers. The latter typically occurs if
    /// the given topology is unsupported.
    fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = N>,
        J: IntoIterator<Item = G>;
}

/// Conversion from raw buffers that do not encode their arity.
pub trait FromRawBuffersWithArity<N, G>: Sized {
    type Error: Debug;

    /// Creates a type from raw buffers with the given arity.
    ///
    /// # Errors
    ///
    /// Returns an error if the raw buffers are inconsistent, the raw buffers
    /// are incompatible with the given arity, or the implementor cannot be
    /// constructed from the buffers. The latter typically occurs if the given
    /// topology is unsupported.
    fn from_raw_buffers_with_arity<I, J>(
        indices: I,
        vertices: J,
        arity: usize,
    ) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = N>,
        J: IntoIterator<Item = G>;
}

// TODO: Provide a similar trait for index buffers instead. `MeshBuffer` could
//       use such a trait to provide this API.
pub trait IntoFlatIndex<G, const N: usize>
where
    Constant<N>: ToType,
    TypeOf<N>: NonZero,
{
    type Item: Copy + Integer + Unsigned;

    fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, N>, G>;
}

// TODO: Provide a similar trait for index buffers instead. `MeshBuffer` could
//       use such a trait to provide this API.
pub trait IntoStructuredIndex<G>
where
    <Self::Item as Topological>::Vertex: Copy + Integer + Unsigned,
{
    type Item: Polygonal;

    fn into_structured_index(self) -> MeshBuffer<Self::Item, G>;
}

/// Polygonal mesh composed of vertex and index buffers.
///
/// A `MeshBuffer` is a linear representation of a polygonal mesh that is
/// composed of two separate but related linear buffers: an _index buffer_ and a
/// _vertex buffer_. The index buffer contains ordered indices into the data in
/// the vertex buffer and describes the topology of the mesh. The vertex buffer
/// contains arbitrary data that describes each vertex.
///
/// `MeshBuffer` only explicitly respresents vertices via the vertex buffer and
/// surfaces via the index buffer. There is no explicit representation of
/// structures like edges and faces.
///
/// The `R` type parameter specifies the [`Grouping`] of the index buffer. See
/// the [`index`] module documention for more information.
///
/// [`Grouping`]: crate::index::Grouping
/// [`index`]: crate::index
#[derive(Debug)]
pub struct MeshBuffer<R, G>
where
    R: Grouping,
{
    indices: Vec<R::Group>,
    vertices: Vec<G>,
}

impl<R, G> MeshBuffer<R, G>
where
    R: Grouping,
    Vec<R::Group>: IndexBuffer<R>,
{
    pub(in crate::buffer) fn from_raw_buffers_unchecked(
        indices: Vec<R::Group>,
        vertices: Vec<G>,
    ) -> Self {
        MeshBuffer { indices, vertices }
    }

    /// Creates an empty `MeshBuffer`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::index::Flat3;
    ///
    /// let buffer = MeshBuffer::<Flat3<u64>, (f64, f64, f64)>::new();
    /// ```
    pub fn new() -> Self {
        Self::default()
    }
}

impl<R, G> MeshBuffer<R, G>
where
    R: Grouping,
{
    /// Converts a `MeshBuffer` into its index and vertex buffers.
    pub fn into_raw_buffers(self) -> (Vec<R::Group>, Vec<G>) {
        let MeshBuffer { indices, vertices } = self;
        (indices, vertices)
    }

    /// Maps over the vertex data in a `MeshBuffer`.
    ///
    /// # Examples
    ///
    /// Translating the position data in a buffer:
    ///
    /// ```rust
    /// # extern crate decorum;
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use decorum::R64;
    /// use nalgebra::{Point3, Vector3};
    /// use plexus::buffer::MeshBuffer3;
    /// use plexus::prelude::*;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::sphere::UvSphere;
    ///
    /// let buffer: MeshBuffer3<usize, Point3<f64>> = UvSphere::new(16, 8)
    ///     .polygons::<Position<Point3<R64>>>()
    ///     .triangulate()
    ///     .collect();
    /// // Translate the positions.
    /// let translation = Vector3::<f64>::x() * 2.0;
    /// let buffer = buffer.map_vertices(|position| position + translation);
    /// ```
    pub fn map_vertices<H, F>(self, f: F) -> MeshBuffer<R, H>
    where
        F: FnMut(G) -> H,
    {
        let (indices, vertices) = self.into_raw_buffers();
        MeshBuffer {
            indices,
            vertices: vertices.into_iter().map(f).collect::<Vec<_>>(),
        }
    }

    /// Gets a slice over the index data.
    pub fn as_index_slice(&self) -> &[R::Group] {
        self.indices.as_slice()
    }

    /// Gets a slice over the vertex data.
    pub fn as_vertex_slice(&self) -> &[G] {
        self.vertices.as_slice()
    }
}

/// Exposes a [`MeshBuilder`] that can be used to construct a [`MeshBuffer`]
/// incrementally from _surfaces_ and _facets_.
///
/// Note that the facet data for [`MeshBuffer`] is always the unit type `()`.
///
/// See the documentation for the [`builder`] module.
///
/// # Examples
///
/// Creating a [`MeshBuffer`] from a triangle:
///
/// ```rust
/// # extern crate nalgebra;
/// # extern crate plexus;
/// #
/// use nalgebra::Point2;
/// use plexus::buffer::MeshBuffer3;
/// use plexus::builder::Buildable;
/// use plexus::prelude::*;
///
/// let mut builder = MeshBuffer3::<usize, Point2<f64>>::builder();
/// let buffer = builder
///     .surface_with(|builder| {
///         let a = builder.insert_vertex((0.0, 0.0))?;
///         let b = builder.insert_vertex((1.0, 0.0))?;
///         let c = builder.insert_vertex((0.0, 1.0))?;
///         builder.facets_with(|builder| builder.insert_facet(&[a, b, c], ()))
///     })
///     .and_then(|_| builder.build())
///     .unwrap();
/// ```
///
/// [`MeshBuffer`]: crate::buffer::MeshBuffer
/// [`MeshBuilder`]: crate::builder::MeshBuilder
/// [`builder`]: crate::builder
impl<R, G> Buildable for MeshBuffer<R, G>
where
    R: Grouping,
    Vec<R::Group>: IndexBuffer<R>,
    BufferBuilder<R, G>: MeshBuilder<Error = BufferError, Commit = Self, Vertex = G, Facet = ()>,
{
    type Builder = BufferBuilder<R, G>;
    type Error = BufferError;

    type Vertex = G;
    type Facet = ();

    fn builder() -> Self::Builder {
        BufferBuilder::default()
    }
}

impl<R, G> Default for MeshBuffer<R, G>
where
    R: Grouping,
    Vec<R::Group>: IndexBuffer<R>,
{
    fn default() -> Self {
        MeshBuffer {
            indices: Default::default(),
            vertices: Default::default(),
        }
    }
}

impl<T, G, const N: usize> DynamicArity for MeshBuffer<Flat<T, N>, G>
where
    Constant<N>: ToType,
    TypeOf<N>: NonZero,
    T: Copy + Integer + Unsigned,
{
    type Dynamic = <Flat<T, N> as StaticArity>::Static;

    fn arity(&self) -> Self::Dynamic {
        Flat::<T, N>::ARITY
    }
}

impl<P, G> DynamicArity for MeshBuffer<P, G>
where
    P: Grouping + Monomorphic + Polygonal,
    P::Vertex: Copy + Integer + Unsigned,
{
    type Dynamic = <P as StaticArity>::Static;

    fn arity(&self) -> Self::Dynamic {
        P::ARITY
    }
}

impl<N, G> DynamicArity for MeshBuffer<BoundedPolygon<N>, G>
where
    N: Copy + Integer + Unsigned,
{
    type Dynamic = MeshArity;

    fn arity(&self) -> Self::Dynamic {
        MeshArity::from_components::<BoundedPolygon<N>, _>(self.indices.iter())
    }
}

impl<N, G> DynamicArity for MeshBuffer<UnboundedPolygon<N>, G>
where
    N: Copy + Integer + Unsigned,
{
    type Dynamic = MeshArity;

    fn arity(&self) -> Self::Dynamic {
        MeshArity::from_components::<UnboundedPolygon<N>, _>(self.indices.iter())
    }
}

impl<R, G> Monomorphic for MeshBuffer<R, G> where R: Grouping + Monomorphic {}

impl<R, G> StaticArity for MeshBuffer<R, G>
where
    R: Grouping,
{
    type Static = <R as StaticArity>::Static;

    const ARITY: Self::Static = R::ARITY;
}

impl<T, G, const N: usize> MeshBuffer<Flat<T, N>, G>
where
    Constant<N>: ToType,
    TypeOf<N>: NonZero,
    T: Copy + Integer + NumCast + Unsigned,
{
    /// Appends the contents of a flat `MeshBuffer` into another `MeshBuffer`.
    /// The source buffer is drained.
    ///
    /// # Errors
    ///
    /// Returns an error if an index overflows.
    pub fn append<R, H>(&mut self, buffer: &mut MeshBuffer<R, H>) -> Result<(), BufferError>
    where
        G: FromGeometry<H>,
        R: Grouping,
        R::Group: Into<<Flat<T, N> as Grouping>::Group>,
    {
        let offset = T::from(self.vertices.len()).ok_or(BufferError::IndexOverflow)?;
        self.vertices.extend(
            buffer
                .vertices
                .drain(..)
                .map(|vertex| vertex.into_geometry()),
        );
        self.indices
            .extend(buffer.indices.drain(..).map(|index| index.into() + offset));
        Ok(())
    }
}

impl<P, G> MeshBuffer<P, G>
where
    P: Grouping + Polygonal,
    P::Vertex: Copy + Integer + NumCast + Unsigned,
{
    /// Appends the contents of a structured `MeshBuffer` into another
    /// `MeshBuffer`. The source buffer is drained.
    ///
    /// # Errors
    ///
    /// Returns an error if an index overflows.
    pub fn append<R, H>(&mut self, buffer: &mut MeshBuffer<R, H>) -> Result<(), BufferError>
    where
        G: FromGeometry<H>,
        R: Grouping,
        R::Group: Into<<P as Grouping>::Group>,
        <P as Grouping>::Group:
            Map<P::Vertex, Output = <P as Grouping>::Group> + Topological<Vertex = P::Vertex>,
    {
        let offset =
            <P::Vertex as NumCast>::from(self.vertices.len()).ok_or(BufferError::IndexOverflow)?;
        self.vertices.extend(
            buffer
                .vertices
                .drain(..)
                .map(|vertex| vertex.into_geometry()),
        );
        self.indices.extend(
            buffer
                .indices
                .drain(..)
                .map(|topology| topology.into().map(|index| index + offset)),
        );
        Ok(())
    }
}

impl<P, Q, T, R, N, G> From<P> for MeshBuffer<R, G>
where
    P: IntoIndexed<N, Indexed = Q> + Polygonal,
    Q: Clone + Map<G, Output = T> + Map<N, Output = R> + Polygonal<Vertex = (N, P::Vertex)>,
    T: Polygonal<Vertex = G>,
    R: Grouping<Group = R> + Polygonal<Vertex = N>,
    N: Copy + Integer + NumCast + Unsigned,
    G: FromGeometry<P::Vertex>,
{
    fn from(polygon: P) -> Self {
        let indexed = polygon.into_indexed();
        MeshBuffer::from_raw_buffers(
            // It is tempting to use a range over the polygon's arity to
            // construct `R`, but that weakens the relationship between the
            // input polygon `P` and the index buffer grouping `R`. These types
            // must have compatible type-level arity, so this implementation
            // relies on the `Map` implementation from `P` to `R`.
            Some(indexed.clone().map(|(index, _)| index)),
            Map::<G>::map(indexed, |(_, vertex)| vertex.into_geometry()),
        )
        .expect("inconsistent index buffer")
    }
}

impl<E, P, G> FromEncoding<E> for MeshBuffer<P, G>
where
    E: FaceDecoder<Face = ()> + VertexDecoder,
    E::Index: AsRef<[P::Vertex]>,
    P: Polygonal<Vertex = usize>,
    G: FromGeometry<E::Vertex>,
    Self: FromRawBuffers<P, G, Error = BufferError>,
{
    type Error = <Self as FromRawBuffers<P, G>>::Error;

    fn from_encoding(
        vertices: <E as VertexDecoder>::Output,
        faces: <E as FaceDecoder>::Output,
    ) -> Result<Self, Self::Error> {
        let indices: Vec<_> = faces
            .into_iter()
            .map(|(index, _)| {
                P::try_from_slice(index.as_ref()).ok_or(BufferError::ArityConflict {
                    expected: P::ARITY.into_interval().0,
                    actual: index.as_ref().len(),
                })
            })
            .collect::<Result<_, _>>()?;
        let vertices = vertices.into_iter().map(|vertex| vertex.into_geometry());
        MeshBuffer::from_raw_buffers(indices, vertices)
    }
}

impl<R, P, G> FromIndexer<P, P> for MeshBuffer<R, G>
where
    R: Grouping,
    G: FromGeometry<P::Vertex>,
    P: Map<IndexOf<R>> + Topological,
    P::Output: Topological<Vertex = IndexOf<R>>,
    BufferOf<R>: Push<R, P::Output>,
    IndexOf<R>: NumCast,
    Self: FromRawBuffers<R::Group, G>,
{
    type Error = <Self as FromRawBuffers<R::Group, G>>::Error;

    fn from_indexer<I, M>(input: I, indexer: M) -> Result<Self, Self::Error>
    where
        I: IntoIterator<Item = P>,
        M: Indexer<P, P::Vertex>,
    {
        let (indices, vertices) = input.into_iter().index_vertices(indexer);
        MeshBuffer::<R, _>::from_raw_buffers(
            indices,
            vertices.into_iter().map(|vertex| vertex.into_geometry()),
        )
    }
}

impl<R, P, G> FromIterator<P> for MeshBuffer<R, G>
where
    R: Grouping,
    G: FromGeometry<P::Vertex>,
    P: Topological,
    P::Vertex: Copy + Eq + Hash,
    BufferOf<R>: IndexBuffer<R>,
    Self: FromIndexer<P, P>,
{
    fn from_iter<I>(input: I) -> Self
    where
        I: IntoIterator<Item = P>,
    {
        Self::from_indexer(input, HashIndexer::default()).unwrap_or_else(|_| Self::default())
    }
}

impl<T, U, G, H, const N: usize> FromRawBuffers<U, H> for MeshBuffer<Flat<T, N>, G>
where
    Constant<N>: ToType,
    TypeOf<N>: NonZero,
    T: Copy + Integer + NumCast + Unsigned,
    U: Copy + Integer + NumCast + Unsigned,
    G: FromGeometry<H>,
{
    type Error = BufferError;

    /// Creates a flat `MeshBuffer` from raw index and vertex buffers.
    ///
    /// # Errors
    ///
    /// Returns an error if the index data is out of bounds within the vertex
    /// buffer or if the number of indices disagrees with the arity of the index
    /// buffer.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate decorum;
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use decorum::R64;
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::geometry::Vector;
    /// use plexus::index::{Flat3, HashIndexer};
    /// use plexus::prelude::*;
    /// use plexus::primitive;
    /// use plexus::primitive::cube::Cube;
    /// use plexus::primitive::generate::{Normal, Position};
    ///
    /// type E3 = Point3<R64>;
    /// type Vertex = (E3, Vector<E3>); // Position and normal.
    ///
    /// let cube = Cube::new();
    /// let (indices, vertices) = primitive::zip_vertices((
    ///     cube.polygons::<Position<E3>>(),
    ///     cube.polygons::<Normal<E3>>()
    ///         .map_vertices(|normal| normal.into_inner()),
    /// ))
    /// .triangulate()
    /// .index_vertices::<Flat3, _>(HashIndexer::default());
    /// let buffer = MeshBuffer::<Flat3, Vertex>::from_raw_buffers(indices, vertices).unwrap();
    /// ```
    fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, BufferError>
    where
        I: IntoIterator<Item = U>,
        J: IntoIterator<Item = H>,
    {
        let indices = indices
            .into_iter()
            .map(|index| <T as NumCast>::from(index).ok_or(BufferError::IndexOverflow))
            .collect::<Result<Vec<_>, _>>()?;
        if indices.len() % N != 0 {
            Err(BufferError::IndexUnaligned)
        }
        else {
            let vertices: Vec<_> = vertices
                .into_iter()
                .map(|vertex| vertex.into_geometry())
                .collect();
            let len = T::from(vertices.len()).unwrap();
            if indices.iter().any(|index| *index >= len) {
                Err(BufferError::IndexOutOfBounds)
            }
            else {
                Ok(MeshBuffer { indices, vertices })
            }
        }
    }
}

impl<P, Q, G, H> FromRawBuffers<Q, H> for MeshBuffer<P, G>
where
    P: From<Q> + Grouping<Group = P> + Polygonal,
    P::Vertex: Copy + Integer + NumCast + Unsigned,
    G: FromGeometry<H>,
{
    type Error = BufferError;

    /// Creates a structured `MeshBuffer` from raw index and vertex buffers.
    ///
    /// # Errors
    ///
    /// Returns an error if the index data is out of bounds within the vertex
    /// buffer.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBufferN;
    /// use plexus::prelude::*;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::sphere::UvSphere;
    ///
    /// type E3 = Point3<f64>;
    ///
    /// let sphere = UvSphere::new(8, 8);
    /// let buffer = MeshBufferN::<usize, E3>::from_raw_buffers(
    ///     sphere.indexing_polygons::<Position>(),
    ///     sphere.vertices::<Position<E3>>(),
    /// )
    /// .unwrap();
    /// ```
    fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, BufferError>
    where
        I: IntoIterator<Item = Q>,
        J: IntoIterator<Item = H>,
    {
        let indices: Vec<_> = indices.into_iter().map(P::from).collect();
        let vertices: Vec<_> = vertices
            .into_iter()
            .map(|vertex| vertex.into_geometry())
            .collect();
        let is_out_of_bounds = {
            let len =
                <P::Vertex as NumCast>::from(vertices.len()).ok_or(BufferError::IndexOverflow)?;
            indices
                .iter()
                .any(|polygon| polygon.as_ref().iter().any(|index| *index >= len))
        };
        if is_out_of_bounds {
            Err(BufferError::IndexOutOfBounds)
        }
        else {
            Ok(MeshBuffer { indices, vertices })
        }
    }
}

impl<T, G, const N: usize> IntoFlatIndex<G, N> for MeshBuffer<Flat<T, N>, G>
where
    Constant<N>: ToType,
    TypeOf<N>: NonZero,
    T: Copy + Integer + Unsigned,
{
    type Item = T;

    fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, N>, G> {
        self
    }
}

impl<N, G> IntoFlatIndex<G, 3> for MeshBuffer<Trigon<N>, G>
where
    N: Copy + Integer + Unsigned,
{
    type Item = N;

    /// Converts the index buffer of a `MeshBuffer` from structured data into
    /// flat data.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::prelude::*;
    /// use plexus::primitive::cube::Cube;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::Trigon;
    ///
    /// type E3 = Point3<f32>;
    ///
    /// let cube = Cube::new();
    /// let buffer = MeshBuffer::<Trigon<usize>, E3>::from_raw_buffers(
    ///     cube.indexing_polygons::<Position>().triangulate(),
    ///     cube.vertices::<Position<E3>>(),
    /// )
    /// .unwrap();
    /// let buffer = buffer.into_flat_index();
    /// for index in buffer.as_index_slice() {
    ///     // ...
    /// }
    /// ```
    fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, 3>, G> {
        let MeshBuffer { indices, vertices } = self;
        MeshBuffer {
            indices: indices
                .into_iter()
                .flat_map(|trigon| trigon.into_vertices())
                .collect(),
            vertices,
        }
    }
}

impl<N, G> IntoFlatIndex<G, 4> for MeshBuffer<Tetragon<N>, G>
where
    N: Copy + Integer + Unsigned,
{
    type Item = N;

    /// Converts the index buffer of a `MeshBuffer` from flat data into
    /// structured data.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::prelude::*;
    /// use plexus::primitive::cube::Cube;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::Tetragon;
    ///
    /// type E3 = Point3<f64>;
    ///
    /// let cube = Cube::new();
    /// let buffer = MeshBuffer::<Tetragon<usize>, E3>::from_raw_buffers(
    ///     cube.indexing_polygons::<Position>(),
    ///     cube.vertices::<Position<E3>>(),
    /// )
    /// .unwrap();
    /// let buffer = buffer.into_flat_index();
    /// for index in buffer.as_index_slice() {
    ///     // ...
    /// }
    /// ```
    fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, 4>, G> {
        let MeshBuffer { indices, vertices } = self;
        MeshBuffer {
            indices: indices
                .into_iter()
                .flat_map(|tetragon| tetragon.into_vertices())
                .collect(),
            vertices,
        }
    }
}

impl<N, G> IntoPolygons for MeshBuffer<Flat3<N>, G>
where
    N: Copy + Integer + NumCast + Unsigned,
    G: Clone,
    Trigon<N>: Grouping<Group = Trigon<N>>,
{
    type Output = vec::IntoIter<Self::Polygon>;
    type Polygon = Trigon<G>;

    /// Converts a triangular flat `MeshBuffer` into an iterator of [`Trigon`]s
    /// containing vertex data.
    ///
    /// [`Trigon`]: crate::primitive::Trigon
    fn into_polygons(self) -> Self::Output {
        let (indices, vertices) = self.into_raw_buffers();
        indices
            .into_iter()
            .chunks(U3::USIZE)
            .into_iter()
            .map(|chunk| {
                // These conversions should never fail.
                Trigon::try_from_iter(chunk.map(|index| {
                    let index = <usize as NumCast>::from(index).expect("index overflow");
                    vertices[index].clone()
                }))
                .expect("inconsistent index buffer")
            })
            .collect::<Vec<_>>()
            .into_iter()
    }
}

impl<N, G> IntoPolygons for MeshBuffer<Flat4<N>, G>
where
    N: Copy + Integer + NumCast + Unsigned,
    G: Clone,
    Trigon<N>: Grouping<Group = Trigon<N>>,
{
    type Output = vec::IntoIter<Self::Polygon>;
    type Polygon = Tetragon<G>;

    /// Converts a quadrilateral flat `MeshBuffer` into an iterator of
    /// [`Tetragon`]s containing vertex data.
    ///
    /// # Examples
    ///
    /// Mapping over the polygons described by a flat buffer:
    ///
    /// ```rust
    /// # extern crate decorum;
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use decorum::R64;
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::graph::MeshGraph;
    /// use plexus::index::Flat4;
    /// use plexus::prelude::*;
    /// use plexus::primitive::cube::Cube;
    /// use plexus::primitive::generate::Position;
    ///
    /// type E3 = Point3<R64>;
    ///
    /// let buffer: MeshBuffer<Flat4, E3> = Cube::new().polygons::<Position<E3>>().collect();
    /// let graph: MeshGraph<E3> = buffer
    ///     .into_polygons()
    ///     .map_vertices(|position| position * R64::assert(2.0))
    ///     .collect();
    /// ```
    ///
    /// [`Tetragon`]: crate::primitive::Tetragon
    fn into_polygons(self) -> Self::Output {
        let (indices, vertices) = self.into_raw_buffers();
        indices
            .into_iter()
            .chunks(U4::USIZE)
            .into_iter()
            .map(|chunk| {
                // These conversions should never fail.
                Tetragon::try_from_iter(chunk.map(|index| {
                    let index = <usize as NumCast>::from(index).expect("index overflow");
                    vertices[index].clone()
                }))
                .expect("inconsistent index buffer")
            })
            .collect::<Vec<_>>()
            .into_iter()
    }
}

impl<P, G> IntoPolygons for MeshBuffer<P, G>
where
    P: Grouping + Polygonal,
    P::Group: Map<G> + Polygonal,
    <P::Group as Map<G>>::Output: Polygonal<Vertex = G>,
    <P::Group as Topological>::Vertex: NumCast,
    P::Vertex: Copy + Integer + NumCast + Unsigned,
    G: Clone,
{
    type Output = vec::IntoIter<Self::Polygon>;
    type Polygon = <P::Group as Map<G>>::Output;

    /// Converts a structured `MeshBuffer` into an iterator of polygons
    /// containing vertex data.
    ///
    /// # Examples
    ///
    /// Mapping over the polygons described by a structured buffer:
    ///
    /// ```rust
    /// # extern crate decorum;
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use decorum::R64;
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::graph::MeshGraph;
    /// use plexus::prelude::*;
    /// use plexus::primitive::generate::Position;
    /// use plexus::primitive::sphere::UvSphere;
    /// use plexus::primitive::BoundedPolygon;
    ///
    /// type E3 = Point3<R64>;
    ///
    /// let buffer: MeshBuffer<BoundedPolygon<usize>, E3> =
    ///     UvSphere::new(8, 8).polygons::<Position<E3>>().collect();
    /// let graph: MeshGraph<E3> = buffer
    ///     .into_polygons()
    ///     .map_vertices(|position| position * R64::assert(2.0))
    ///     .triangulate()
    ///     .collect();
    /// ```
    fn into_polygons(self) -> Self::Output {
        let (indices, vertices) = self.into_raw_buffers();
        indices
            .into_iter()
            .map(|polygon| {
                polygon.map(|index| {
                    // This conversion should never fail.
                    let index = <usize as NumCast>::from(index).expect("index overflow");
                    vertices[index].clone()
                })
            })
            .collect::<Vec<_>>()
            .into_iter()
    }
}

impl<P, G> IntoStructuredIndex<G> for MeshBuffer<P, G>
where
    P: Grouping + Polygonal,
    P::Vertex: Copy + Integer + Unsigned,
{
    type Item = P;

    fn into_structured_index(self) -> MeshBuffer<Self::Item, G> {
        self
    }
}

impl<N, G> IntoStructuredIndex<G> for MeshBuffer<Flat3<N>, G>
where
    N: Copy + Integer + Unsigned,
    Trigon<N>: Grouping<Group = Trigon<N>>,
{
    type Item = Trigon<N>;

    /// Converts the index buffer of a `MeshBuffer` from flat data into
    /// structured data.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer;
    /// use plexus::index::Flat3;
    /// use plexus::prelude::*;
    /// use plexus::primitive::cube::Cube;
    /// use plexus::primitive::generate::Position;
    ///
    /// type E3 = Point3<f64>;
    ///
    /// let cube = Cube::new();
    /// let buffer = MeshBuffer::<Flat3, E3>::from_raw_buffers(
    ///     cube.indexing_polygons::<Position>()
    ///         .triangulate()
    ///         .vertices(),
    ///     cube.vertices::<Position<E3>>(),
    /// )
    /// .unwrap();
    /// let buffer = buffer.into_structured_index();
    /// for trigon in buffer.as_index_slice() {
    ///     // ...
    /// }
    /// ```
    fn into_structured_index(self) -> MeshBuffer<Self::Item, G> {
        let MeshBuffer { indices, vertices } = self;
        let indices = indices
            .into_iter()
            .chunks(U3::USIZE)
            .into_iter()
            .map(<Self::Item as Grouping>::Group::try_from_iter)
            .collect::<Result<Vec<_>, _>>()
            .expect("inconsistent index buffer");
        MeshBuffer { indices, vertices }
    }
}

impl<N, G> IntoStructuredIndex<G> for MeshBuffer<Flat4<N>, G>
where
    N: Copy + Integer + Unsigned,
    Tetragon<N>: Grouping<Group = Tetragon<N>>,
{
    type Item = Tetragon<N>;

    /// Converts the index buffer of a `MeshBuffer` from flat data into
    /// structured data.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate nalgebra;
    /// # extern crate plexus;
    /// #
    /// use nalgebra::Point3;
    /// use plexus::buffer::MeshBuffer4;
    /// use plexus::prelude::*;
    /// use plexus::primitive::cube::Cube;
    /// use plexus::primitive::generate::Position;
    ///
    /// type E3 = Point3<f64>;
    ///
    /// let cube = Cube::new();
    /// let buffer = MeshBuffer4::<usize, E3>::from_raw_buffers(
    ///     cube.indexing_polygons::<Position>(),
    ///     cube.vertices::<Position<E3>>(),
    /// )
    /// .unwrap();
    /// let buffer = buffer.into_structured_index();
    /// for tetragon in buffer.as_index_slice() {
    ///     // ...
    /// }
    /// ```
    fn into_structured_index(self) -> MeshBuffer<Self::Item, G> {
        let MeshBuffer { indices, vertices } = self;
        let indices = indices
            .into_iter()
            .chunks(U4::USIZE)
            .into_iter()
            .map(<Self::Item as Grouping>::Group::try_from_iter)
            .collect::<Result<Vec<_>, _>>()
            .expect("inconsistent index buffer");
        MeshBuffer { indices, vertices }
    }
}

#[cfg(test)]
mod tests {
    use decorum::R64;
    use nalgebra::Point3;

    use crate::buffer::{MeshBuffer, MeshBuffer4, MeshBufferN};
    use crate::graph::MeshGraph;
    use crate::index::Flat3;
    use crate::prelude::*;
    use crate::primitive::cube::Cube;
    use crate::primitive::generate::Position;
    use crate::primitive::sphere::UvSphere;
    use crate::primitive::{BoundedPolygon, UnboundedPolygon};

    type E3 = Point3<R64>;

    #[test]
    fn collect_into_flat_buffer() {
        let buffer: MeshBuffer<Flat3<usize>, E3> = UvSphere::new(3, 2)
            .polygons::<Position<E3>>() // 6 triangles, 18 vertices.
            .triangulate()
            .collect();

        assert_eq!(18, buffer.as_index_slice().len());
        assert_eq!(5, buffer.as_vertex_slice().len());
    }

    #[test]
    fn collect_into_bounded_buffer() {
        let buffer: MeshBuffer<BoundedPolygon<usize>, E3> = UvSphere::new(3, 2)
            .polygons::<Position<E3>>() // 6 triangles, 18 vertices.
            .collect();

        assert_eq!(6, buffer.as_index_slice().len());
        assert_eq!(5, buffer.as_vertex_slice().len());
    }

    #[test]
    fn collect_into_unbounded_buffer() {
        let buffer: MeshBuffer<UnboundedPolygon<usize>, E3> =
            Cube::new().polygons::<Position<E3>>().collect();

        assert_eq!(6, buffer.as_index_slice().len());
        assert_eq!(8, buffer.as_vertex_slice().len());
        for polygon in buffer.as_index_slice() {
            assert_eq!(4, polygon.arity());
        }
    }

    #[test]
    fn append_structured_buffers() {
        let mut buffer: MeshBufferN<usize, E3> = UvSphere::new(3, 2)
            .polygons::<Position<E3>>() // 6 triangles, 18 vertices.
            .collect();
        buffer
            .append(
                &mut Cube::new()
                    .polygons::<Position<E3>>() // 6 quadrilaterals, 24 vertices.
                    .collect::<MeshBuffer4<usize, E3>>(),
            )
            .unwrap();

        assert_eq!(12, buffer.as_index_slice().len());
        assert_eq!(13, buffer.as_vertex_slice().len());
    }

    #[test]
    fn convert_mesh_to_buffer_by_vertex() {
        let graph: MeshGraph<E3> = UvSphere::new(3, 2)
            .polygons::<Position<E3>>() // 6 triangles, 18 vertices.
            .collect();
        let buffer: MeshBufferN<usize, E3> = graph.to_mesh_by_vertex().unwrap();

        assert_eq!(6, buffer.as_index_slice().len());
        assert_eq!(5, buffer.as_vertex_slice().len());
    }

    #[test]
    fn convert_mesh_to_buffer_by_face() {
        let graph: MeshGraph<E3> = UvSphere::new(3, 2)
            .polygons::<Position<E3>>() // 6 triangles, 18 vertices.
            .collect();
        let buffer: MeshBufferN<usize, E3> = graph.to_mesh_by_face().unwrap();

        assert_eq!(6, buffer.as_index_slice().len());
        assert_eq!(18, buffer.as_vertex_slice().len());
    }
}


================================================
FILE: plexus/src/builder.rs
================================================
//! Incremental polygonal mesh construction.
//!
//! This module provides traits for incrementally constructing mesh data
//! structures. This API allows for meshes to be constructed in a way that is
//! agnostic to the specific data structure used to represent the mesh.
//!
//! [`Buildable`] is the primary trait of this API. It is implemented by mesh
//! data structures and exposes various associated types for their associated
//! data.  [`Buildable`] exposes a builder type via its
//! [`builder`][`Buildable::builder`] function. This builder type in turn
//! provides additional builders that can be used to construct a mesh from
//! _surfaces_ and _facets_.
//!
//! # Examples
//!
//! A function that generates a triangle from point geometry using builders:
//!
//! ```rust
//! # extern crate nalgebra;
//! # extern crate plexus;
//! #
//! use nalgebra::Point2;
//! use plexus::buffer::MeshBuffer3;
//! use plexus::builder::Buildable;
//! use plexus::geometry::FromGeometry;
//! use plexus::graph::MeshGraph;
//! use plexus::prelude::*;
//!
//! type E2 = Point2<f64>;
//!
//! fn trigon<B, T>(points: [T; 3]) -> Result<B, B::Error>
//! where
//!     B: Buildable,
//!     B::Vertex: FromGeometry<T>,
//! {
//!     let mut builder = B::builder();
//!     builder.surface_with(|builder| {
//!         let [a, b, c] = points;
//!         let a = builder.insert_vertex(a)?;
//!         let b = builder.insert_vertex(b)?;
//!         let c = builder.insert_vertex(c)?;
//!         builder.facets_with(|builder| builder.insert_facet(&[a, b, c], B::Facet::default()))
//!     })?;
//!     builder.build()
//! }
//!
//! // `MeshBuffer` and `MeshGraph` implement the `Buildable` trait.
//! let graph: MeshGraph<E2> = trigon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]).unwrap();
//! let buffer: MeshBuffer3<usize, E2> = trigon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]).unwrap();
//! ```
//!
//! [`Buildable::builder`]: crate::builder::Buildable::builder
//! [`Buildable`]: crate::builder::Buildable

// TODO: Is it useful to use a separate `FacetBuilder` type?
// TODO: Keys are not opaque. Especially for `MeshBuffer`, it may be possible to
//       "forge" keys. This could be prevented by using a wrapper type that is
//       not exported, but would introduce a performance cost to map and collect
//       slices of keys.

use std::fmt::Debug;
use std::hash::Hash;

use crate::geometry::FromGeometry;
use crate::transact::ClosedInput;

/// Polygonal mesh data structure that can be built incrementally.
///
/// This trait is the primary entrypoint into the builder API. Types that
/// implement this trait expose a [`MeshBuilder`] that can be used to construct
/// an instance of the type from surfaces and facets.
///
/// [`MeshBuilder`]: crate::builder::MeshBuilder
pub trait Buildable: Sized {
    type Builder: MeshBuilder<
        Commit = Self,
        Error = Self::Error,
        Vertex = Self::Vertex,
        Facet = Self::Facet,
    >;
    type Error: Debug;

    /// Vertex data.
    ///
    /// This type represents the data associated with vertices in the mesh.
    /// This typically includes positional data, but no data is required and
    /// this type may be the unit type `()`.
    ///
    /// Each builder trait also exposes such an associated type which is
    /// constrained by the `Builder` type.
    type Vertex;
    /// Facet data.
    ///
    /// This type represents the data associated with facets in the mesh. No
    /// data is required and this type may be the unit type `()`.
    ///
    /// Each builder trait also exposes such an associated type which is
    /// constrained by the `Builder` type.
    type Facet: Default;

    fn builder() -> Self::Builder;
}

/// Incremental polygonal mesh builder.
///
/// This trait exposes types that allow for mesh data structures to be
/// constructed incrementally from _surfaces_ and _facets_. A _surface_ is a
/// collection of vertices and facets connecting those vertices and typically
/// describes a _manifold_. A _facet_ is the connectivity between vertices in a
/// surface. Facets may also include associated data.
///
/// Construction is hierarchical, beginning with a surface and its vertices and
/// then facets. The association between a surface, its vertices, and facets is
/// enforced by the API, which accepts functions that operate on increasingly
/// specific builder types. The [`build`][`MeshBuilder::build`] function is used
/// to complete the construction of a mesh.
///
/// Builders may emit errors at any stage and errors depend on the
/// implementation of the builder types (and by extension the details of the
/// underlying data structure).
///
/// [`MeshBuilder::build`]: crate::builder::MeshBuilder::build
pub trait MeshBuilder: ClosedInput {
    type Builder: SurfaceBuilder<Error = Self::Error, Vertex = Self::Vertex, Facet = Self::Facet>;

    type Vertex;
    type Facet: Default;

    /// Constructs a surface.
    ///
    /// The given function is invoked with a [`SurfaceBuilder`], which can be
    /// used to insert vertices and construct facets.
    ///
    /// [`SurfaceBuilder`]: crate::builder::SurfaceBuilder
    fn surface_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
    where
        Self::Error: From<E>,
        F: FnOnce(&mut Self::Builder) -> Result<T, E>;

    /// Builds the mesh.
    ///
    /// The builder is consumed and a mesh with the constructed surfaces and
    /// facets is produced.
    ///
    /// # Errors
    ///
    /// Returns a latent error if the constructed surfaces and facets are
    /// incompatible with the underlying data structure. May return other
    /// errors depending on the details of the implementation.
    fn build(self) -> Result<Self::Commit, Self::Error> {
        self.commit().map_err(|(_, error)| error)
    }
}

pub trait SurfaceBuilder: ClosedInput {
    type Builder: FacetBuilder<Self::Key, Error = Self::Error, Facet = Self::Facet>;
    /// Vertex key.
    ///
    /// Each vertex is associated with a key of this type. This key is used to
    /// reference a given vertex and is required to insert faces with a
    /// [`FacetBuilder`].
    ///
    /// [`FacetBuilder`]: crate::builder::FacetBuilder
    type Key: Copy + Eq + Hash;

    type Vertex;
    type Facet: Default;

    /// Constructs facets in the surface.
    ///
    /// The given function is invoked with a [`FacetBuilder`], which can be used
    /// to insert facets.
    ///
    /// [`FacetBuilder`]: crate::builder::FacetBuilder
    fn facets_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
    where
        Self::Error: From<E>,
        F: FnOnce(&mut Self::Builder) -> Result<T, E>;

    /// Inserts a vertex into the surface.
    ///
    /// Returns a key that refers to the inserted vertex. This key can be used
    /// to insert facets with a [`FacetBuilder`].
    ///
    /// [`FacetBuilder`]: crate::builder::FacetBuilder
    fn insert_vertex<T>(&mut self, data: T) -> Result<Self::Key, Self::Error>
    where
        Self::Vertex: FromGeometry<T>;
}

pub trait FacetBuilder<K>: ClosedInput
where
    K: Eq + Hash,
{
    /// Facet key.
    ///
    /// Each facet is associated with a key of this type.
    type Key: Copy + Eq + Hash;

    type Facet: Default;

    /// Inserts a facet into the associated surface.
    ///
    /// A facet is formed from connectivity between vertices represented by an
    /// ordered slice of vertex keys from the associated [`SurfaceBuilder`].
    ///
    /// Returns a key that refers to the inserted facet.
    ///
    /// [`SurfaceBuilder`]: crate::builder::SurfaceBuilder
    fn insert_facet<T, U>(&mut self, keys: T, data: U) -> Result<Self::Key, Self::Error>
    where
        Self::Facet: FromGeometry<U>,
        T: AsRef<[K]>;
}


================================================
FILE: plexus/src/constant.rs
================================================
//! Morphisms between constant generics and numeric types.
//!
//! This module provides conversions between `typenum`'s unsigned integer types
//! and `usize` constant generics. These conversions are necessary to perform
//! static computations and comparisons, which cannot yet be done using constant
//! generics alone at the time of writing (e.g., `{N >= 3}`).
//!
//! See discussion on the [Rust internals
//! forum](https://internals.rust-lang.org/t/const-generics-where-restrictions/12742/7).

// TODO: Move this into the `theon` crate as part of its public API.

pub type ConstantOf<N> = <N as ToConstant>::Output;
pub type TypeOf<const N: usize> = <Constant<N> as ToType>::Output;

pub struct Constant<const N: usize>;

pub trait ToConstant {
    type Output;
}

pub trait ToType {
    type Output;
}

macro_rules! impl_morphisms {
    (types => $($n:ident),*$(,)?) => (
        use typenum::Unsigned;

        $(
            impl ToConstant for typenum::$n {
                type Output = Constant<{ typenum::$n::USIZE }>;
            }

            impl ToType for Constant<{ typenum::$n::USIZE }> {
                type Output = typenum::$n;
            }
        )*
    );
}
impl_morphisms!(types =>
    U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19, U21,
    U22, U23, U24, U25, U26, U27, U28, U29, U30, U31, U32,
);


================================================
FILE: plexus/src/encoding/mod.rs
================================================
//! Serialization and encodings.
//!
//! This module provides encoding support enabled via Cargo features. Each
//! enabled encoding has a corresponding sub-module. For example, when [PLY]
//! support is enabled, the `ply` module is exposed. The following table
//! summarizes the encodings supported by Plexus:
//!
//! | Feature        | Default | Encoding | Read | Write |
//! |----------------|---------|----------|------|-------|
//! | `encoding-ply` | No      | [PLY]    | Yes  | No    |
//!
//! This module provides traits used by all encodings. These traits describe the
//! outputs and inputs of decoders and encoders, respectively. Generally, these
//! traits should **not** be used directly. Instead, prefer the conversion
//! traits exposed for specific encodings, such as `FromPly` when using [PLY].
//!
//! [PLY]: https://en.wikipedia.org/wiki/ply_(file_format)

pub mod ply;

use std::fmt::Debug;

pub trait VertexDecoder {
    type Output: IntoIterator<Item = Self::Vertex>;
    type Vertex;
}

pub trait FaceDecoder {
    type Output: IntoIterator<Item = (Self::Index, Self::Face)>;
    type Index: IntoIterator<Item = usize>;
    type Face;
}

// TODO: This trait is a bit limiting. Consider implementing more specific
//       traits like `FromPly` directly. This could allow more specific
//       features to be supported, such as edge geometry for `MeshGraph`s.
pub trait FromEncoding<E>: Sized
where
    E: FaceDecoder + VertexDecoder,
{
    type Error: Debug;

    fn from_encoding(
        vertices: <E as VertexDecoder>::Output,
        faces: <E as FaceDecoder>::Output,
    ) -> Result<Self, Self::Error>;
}


================================================
FILE: plexus/src/encoding/ply.rs
================================================
//! [PLY] encoding.
//!
//! This module provides support for the [PLY] format via the [`FromPly`] and
//! [`ToPly`] traits. These traits can be used with a decoder and encoder to
//! read and write mesh data structures to and from the [PLY] format.
//!
//! [PLY] support is implemented using the [`ply-rs`] crate and some of its
//! types are re-exported here.
//!
//! # Examples
//!
//! Reading a [PLY] file into a [`MeshGraph`]:
//!
//! ```rust
//! # extern crate nalgebra;
//! # extern crate plexus;
//! #
//! use nalgebra::Point3;
//! use plexus::encoding::ply::{FromPly, PositionEncoding};
//! use plexus::graph::MeshGraph;
//! use std::io::Read;
//!
//! type E3 = Point3<f64>;
//!
//! // Read from a file, network, etc.
//! fn read() -> impl Read {
//!     // ...
//!     # let ply: &[u8] = include_bytes!("../../../data/cube.ply");
//!     # ply
//! }
//!
//! let encoding = PositionEncoding::<E3>::default();
//! let (graph, _) = MeshGraph::<E3>::from_ply(encoding, read()).unwrap();
//! ```
//!
//! [PLY]: https://en.wikipedia.org/wiki/PLY_(file_format)
//!
//! [`ply-rs`]: https://crates.io/crates/ply-rs
//!
//! [`FromPly`]: crate::encoding::ply::FromPly
//! [`ToPly`]: crate::encoding::ply::ToPly
//! [`MeshGraph`]: crate::graph::MeshGraph

#![cfg(feature = "encoding-ply")]

use num::cast;
use num::NumCast;
use ply_rs::parser::Parser;
use ply_rs::ply::KeyMap;
use smallvec::SmallVec;
use std::io::{self, Read, Write};
use std::iter::FromIterator;
use std::marker::PhantomData;
use theon::space::{EuclideanSpace, FiniteDimensional};
use thiserror::Error;
use typenum::{NonZero, Unsigned, U2, U3};

use crate::encoding::{FaceDecoder, FromEncoding, VertexDecoder};

pub use ply_rs::ply::{
    ElementDef as ElementDefinition, Property, PropertyDef as PropertyDefinition, PropertyType,
};

// TODO: These traits only allow a single element to be read for each topology
//       (vertices, faces, etc.). It may be useful to allow code to aggregate
//       various elements to produce an output for a single topology.
// TODO: Consider using the newtype pattern to hide underlying types and expose
//       a smaller and more tailored API surface.

pub type Header = KeyMap<ElementDefinition>;
pub type Payload = KeyMap<Vec<Element>>;
pub type Element = KeyMap<Property>;

pub struct Ply {
    pub header: Header,
    pub payload: Payload,
}

impl Ply {
    pub fn parse(mut read: impl Read) -> io::Result<Self> {
        Parser::<Element>::new().read_ply(&mut read).map(|ply| Ply {
            header: ply.header.elements,
            payload: ply.payload,
        })
    }
}

/// Errors concerning the [PLY] encoding.
///
/// [PLY]: https://en.wikipedia.org/wiki/PLY_(file_format)
#[derive(Debug, Error)]
pub enum PlyError {
    #[error("required element not found")]
    ElementNotFound,
    #[error("required property not found")]
    PropertyNotFound,
    /// The type of a property conflicts with a decoding.
    #[error("conflicting property type found")]
    PropertyTypeConflict,
    /// A polygonal mesh data structure is not compatible with encoded PLY data.
    #[error("encoding operation failed")]
    EncodingIncompatible,
    /// An I/O operation (read or write via the `Read` and `Write` traits)
    /// failed.
    #[error("I/O operation failed")]
    Io(io::Error),
}

impl From<io::Error> for PlyError {
    fn from(error: io::Error) -> Self {
        PlyError::Io(error)
    }
}

pub trait ElementExt {
    fn scalar<K, T>(&self, key: K) -> Result<T, PlyError>
    where
        K: AsRef<str>,
        T: NumCast;

    fn list<K, T, I>(&self, key: K) -> Result<I, PlyError>
    where
        K: AsRef<str>,
        T: NumCast,
        I: FromIterator<T>;
}

impl ElementExt for Element {
    fn scalar<K, T>(&self, key: K) -> Result<T, PlyError>
    where
        K: AsRef<str>,
        T: NumCast,
    {
        self.get(key.as_ref())
            .ok_or(PlyError::PropertyNotFound)?
            .clone()
            .into_scalar()
    }

    fn list<K, T, I>(&self, key: K) -> Result<I, PlyError>
    where
        K: AsRef<str>,
        T: NumCast,
        I: FromIterator<T>,
    {
        self.get(key.as_ref())
            .ok_or(PlyError::PropertyNotFound)?
            .clone()
            .into_list()
    }
}

pub trait PropertyExt {
    fn into_scalar<T>(self) -> Result<T, PlyError>
    where
        T: NumCast;

    fn into_list<T, I>(self) -> Result<I, PlyError>
    where
        T: NumCast,
        I: FromIterator<T>;
}

impl PropertyExt for Property {
    fn into_scalar<T>(self) -> Result<T, PlyError>
    where
        T: NumCast,
    {
        match self {
            Property::Char(value) => num_cast_scalar(value),
            Property::UChar(value) => num_cast_scalar(value),
            Property::Short(value) => num_cast_scalar(value),
            Property::UShort(value) => num_cast_scalar(value),
            Property::Int(value) => num_cast_scalar(value),
            Property::UInt(value) => num_cast_scalar(value),
            Property::Float(value) => num_cast_scalar(value),
            Property::Double(value) => num_cast_scalar(value),
            _ => Err(PlyError::PropertyTypeConflict),
        }
    }

    fn into_list<T, I>(self) -> Result<I, PlyError>
    where
        T: NumCast,
        I: FromIterator<T>,
    {
        match self {
            Property::ListChar(values) => num_cast_list(values),
            Property::ListUChar(values) => num_cast_list(values),
            Property::ListShort(values) => num_cast_list(values),
            Property::ListUShort(values) => num_cast_list(values),
            Property::ListInt(values) => num_cast_list(values),
            Property::ListUInt(values) => num_cast_list(values),
            Property::ListFloat(values) => num_cast_list(values),
            Property::ListDouble(values) => num_cast_list(values),
            _ => Err(PlyError::PropertyTypeConflict),
        }
    }
}

pub trait VertexElementDecoder {
    fn decode_vertex_elements<'a>(
        &self,
        definitions: &'a Header,
        elements: &'a Payload,
    ) -> Result<(&'a ElementDefinition, &'a Vec<Element>), PlyError> {
        decode_elements(definitions, elements, "vertex")
    }
}

pub trait VertexPropertyDecoder: VertexDecoder {
    fn decode_vertex_properties<'a, I>(
        &self,
        definition: &'a ElementDefinition,
        elements: I,
    ) -> Result<Self::Output, PlyError>
    where
        I: IntoIterator<Item = &'a Element>;
}

pub trait FaceElementDecoder {
    fn decode_face_elements<'a>(
        &self,
        definitions: &'a Header,
        elements: &'a Payload,
    ) -> Result<(&'a ElementDefinition, &'a Vec<Element>), PlyError> {
        decode_elements(definitions, elements, "face")
    }
}

pub trait FacePropertyDecoder: FaceDecoder {
    fn decode_face_properties<'a, I>(
        &self,
        definition: &'a ElementDefinition,
        elements: I,
    ) -> Result<Self::Output, PlyError>
    where
        I: IntoIterator<Item = &'a Element>;
}

pub trait FromPly<E>: Sized {
    fn from_ply(decoder: E, read: impl Read) -> Result<(Self, Ply), PlyError>;
}

impl<T, E> FromPly<E> for T
where
    T: FromEncoding<E>,
    E: FaceElementDecoder + FacePropertyDecoder + VertexPropertyDecoder + VertexElementDecoder,
{
    fn from_ply(decoder: E, mut read: impl Read) -> Result<(Self, Ply), PlyError> {
        let ply = Ply::parse(&mut read)?;
        let mesh = T::from_encoding(
            decode_vertex_properties(&decoder, &ply.header, &ply.payload)?,
            decode_face_properties(&decoder, &ply.header, &ply.payload)?,
        )
        .map_err(|_| PlyError::EncodingIncompatible)?;
        Ok((mesh, ply))
    }
}

pub trait ToPly<E> {
    fn to_ply(
        &self,
        definitions: &Header,
        encoder: E,
        write: impl Write,
    ) -> Result<usize, PlyError>;
}

pub trait DecodePosition<N>: FiniteDimensional<N = N> + Sized
where
    N: NonZero + Unsigned,
{
    fn decode_position(element: &Element) -> Result<Self, PlyError>;
}

impl<T> DecodePosition<U2> for T
where
    T: EuclideanSpace + FiniteDimensional<N = U2>,
{
    fn decode_position(element: &Element) -> Result<Self, PlyError> {
        let position = EuclideanSpace::from_xy(element.scalar("x")?, element.scalar("y")?);
        Ok(position)
    }
}

impl<T> DecodePosition<U3> for T
where
    T: EuclideanSpace + FiniteDimensional<N = U3>,
{
    fn decode_position(element: &Element) -> Result<Self, PlyError> {
        let position = EuclideanSpace::from_xyz(
            element.scalar("x")?,
            element.scalar("y")?,
            element.scalar("z")?,
        );
        Ok(position)
    }
}

pub struct PositionEncoding<T> {
    phantom: PhantomData<fn() -> T>,
}

impl<T> Default for PositionEncoding<T> {
    fn default() -> Self {
        PositionEncoding {
            phantom: PhantomData,
        }
    }
}

impl<T> FaceDecoder for PositionEncoding<T> {
    type Output = Vec<(Self::Index, Self::Face)>;
    type Index = SmallVec<[usize; 4]>;
    type Face = ();
}

impl<T> FaceElementDecoder for PositionEncoding<T> {}

impl<T> FacePropertyDecoder for PositionEncoding<T> {
    fn decode_face_properties<'a, I>(
        &self,
        _: &'a ElementDefinition,
        elements: I,
    ) -> Result<<Self as FaceDecoder>::Output, PlyError>
    where
        I: IntoIterator<Item = &'a Element>,
    {
        elements
            .into_iter()
            .map(|element| {
                let indices = element.list("vertex_index")?;
                Ok((indices, ()))
            })
            .collect()
    }
}

impl<T> VertexDecoder for PositionEncoding<T> {
    type Output = Vec<Self::Vertex>;
    type Vertex = T;
}

impl<T> VertexElementDecoder for PositionEncoding<T> {}

impl<T, N> VertexPropertyDecoder for PositionEncoding<T>
where
    T: DecodePosition<N> + FiniteDimensional<N = N>,
    N: NonZero + Unsigned,
{
    fn decode_vertex_properties<'a, I>(
        &self,
        _: &'a ElementDefinition,
        elements: I,
    ) -> Result<<Self as VertexDecoder>::Output, PlyError>
    where
        I: IntoIterator<Item = &'a Element>,
    {
        elements
            .into_iter()
            .map(|element| T::decode_position(element))
            .collect()
    }
}

pub fn decode_elements<'a, K>(
    definitions: &'a Header,
    elements: &'a Payload,
    key: K,
) -> Result<(&'a ElementDefinition, &'a Vec<Element>), PlyError>
where
    K: AsRef<str>,
{
    definitions
        .get(key.as_ref())
        .ok_or(PlyError::ElementNotFound)
        .and_then(|definition| {
            elements
                .get(&definition.name)
                .ok_or(PlyError::ElementNotFound)
                .map(|elements| (definition, elements))
        })
}

pub fn decode_vertex_properties<E>(
    decoder: &E,
    definitions: &Header,
    elements: &Payload,
) -> Result<E::Output, PlyError>
where
    E: VertexElementDecoder + VertexPropertyDecoder,
{
    decoder
        .decode_vertex_elements(definitions, elements)
        .and_then(|(definition, elements)| decoder.decode_vertex_properties(definition, elements))
}

pub fn decode_face_properties<E>(
    decoder: &E,
    definitions: &Header,
    elements: &Payload,
) -> Result<E::Output, PlyError>
where
    E: FaceElementDecoder + FacePropertyDecoder,
{
    decoder
        .decode_face_elements(definitions, elements)
        .and_then(|(definition, elements)| decoder.decode_face_properties(definition, elements))
}

fn num_cast_scalar<T, U>(value: T) -> Result<U, PlyError>
where
    T: NumCast,
    U: NumCast,
{
    cast::cast(value).ok_or(PlyError::PropertyTypeConflict)
}

fn num_cast_list<T, U, I>(values: Vec<T>) -> Result<I, PlyError>
where
    T: NumCast,
    U: NumCast,
    I: FromIterator<U>,
{
    values
        .into_iter()
        .map(num_cast_scalar)
        .collect::<Result<_, _>>()
}

#[cfg(test)]
mod tests {
    use nalgebra::Point3;

    use crate::buffer::MeshBuffer;
    use crate::encoding::ply::{FromPly, PositionEncoding};
    use crate::graph::MeshGraph;
    use crate::primitive::Tetragon;

    type E3 = Point3<f64>;

    #[test]
    fn decode_into_buffer() {
        let (buffer, _) = {
            let ply: &[u8] = include_bytes!("../../../data/cube.ply");
            MeshBuffer::<Tetragon<usize>, E3>::from_ply(PositionEncoding::<E3>::default(), ply)
                .unwrap()
        };
        assert_eq!(8, buffer.as_vertex_slice().len());
        assert_eq!(6, buffer.as_index_slice().len());
    }

    #[test]
    fn decode_into_graph() {
        let (graph, _) = {
            let ply: &[u8] = include_bytes!("../../../data/cube.ply");
            MeshGraph::<E3>::from_ply(PositionEncoding::<E3>::default(), ply).unwrap()
        };
        assert_eq!(8, graph.vertex_count());
        assert_eq!(12, graph.edge_count());
        assert_eq!(6, graph.face_count());
    }
}


================================================
FILE: plexus/src/entity/borrow.rs
================================================
pub trait Reborrow {
    type Target;

    fn reborrow(&self) -> &Self::Target;
}

pub trait ReborrowMut: Reborrow {
    fn reborrow_mut(&mut self) -> &mut Self::Target;
}

pub trait ReborrowInto<'a>: Reborrow {
    fn reborrow_into(self) -> &'a Self::Target;
}

impl<T> Reborrow for &'_ T {
    type Target = T;

    fn reborrow(&self) -> &Self::Target {
        self
    }
}

impl<T> Reborrow for &'_ mut T {
    type Target = T;

    fn reborrow(&self) -> &Self::Target {
        self
    }
}

impl<T> ReborrowMut for &'_ mut T {
    fn reborrow_mut(&mut self) -> &mut Self::Target {
        self
    }
}

impl<'a, T> ReborrowInto<'a> for &'a T {
    fn reborrow_into(self) -> &'a Self::Target {
        self
    }
}

impl<'a, T> ReborrowInto<'a> for &'a mut T {
    fn reborrow_into(self) -> &'a Self::Target {
        &*self
    }
}


================================================
FILE: plexus/src/entity/dijkstra.rs
================================================
use derivative::Derivative;
use std::cmp::Reverse;
use std::collections::hash_map::Entry;
use std::collections::{BinaryHeap, HashMap, HashSet};

use crate::entity::storage::{AsStorage, Enumerate, Get};
use crate::entity::traverse::Adjacency;
use crate::entity::view::{Bind, Unbind};
use crate::entity::EntityError;
use crate::geometry::Metric;

pub type MetricTree<K, Q> = HashMap<K, (Option<K>, Q)>;

#[derive(Derivative)]
#[derivative(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
struct KeyedMetric<K, Q>(
    #[derivative(Ord = "ignore", PartialEq = "ignore", PartialOrd = "ignore")] K,
    Q,
)
where
    Q: Eq + Ord;

pub fn metrics_with<'a, M, T, Q, F>(
    from: T,
    to: Option<T::Key>,
    f: F,
) -> Result<MetricTree<T::Key, Q>, EntityError>
where
    M: 'a + AsStorage<T::Entity>,
    T: Adjacency + Bind<&'a M> + Copy + Unbind<&'a M>,
    Q: Copy + Metric,
    F: Fn(T, T) -> Q,
{
    let (storage, from) = from.unbind();
    let capacity = if let Some(key) = to {
        if !storage.as_storage().contains_key(&key) {
            return Err(EntityError::EntityNotFound);
        }
        0
    }
    else {
        storage.as_storage().len()
    };
    let mut buffer = BinaryHeap::new();
    let mut breadcrumbs = HashSet::with_capacity(capacity);
    let mut metrics = HashMap::with_capacity(capacity);

    metrics.insert(from, (None, Q::zero()));
    buffer.push(KeyedMetric(from, Reverse(Q::zero())));
    while let Some(KeyedMetric(key, Reverse(metric))) = buffer.pop() {
        if Some(key) == to {
            break;
        }
        let entity = T::bind(storage, key).ok_or(EntityError::EntityNotFound)?;
        if breadcrumbs.insert(entity.key()) {
            for adjacent in entity
                .adjacency()
                .into_iter()
                .map(|key| T::bind(storage, key))
            {
                let adjacent = adjacent.ok_or(EntityError::EntityNotFound)?;
                let summand = f(entity, adjacent);
                if summand < Q::zero() {
                    return Err(EntityError::Data);
                }
                let metric = metric + summand;
                match metrics.entry(adjacent.key()) {
                    Entry::Occupied(entry) => {
                        if metric < entry.get().1 {
                            entry.into_mut().1 = metric;
                        }
                    }
                    Entry::Vacant(entry) => {
                        entry.insert((Some(entity.key()), metric));
                    }
                }
                buffer.push(KeyedMetric(adjacent.key(), Reverse(metric)));
            }
        }
    }
    Ok(metrics)
}

#[cfg(test)]
mod tests {
    use decorum::R64;
    use nalgebra::Point2;
    use theon::space::InnerSpace;

    use crate::entity::dijkstra::{self, MetricTree};
    use crate::entity::EntityError;
    use crate::graph::MeshGraph;
    use crate::prelude::*;
    use crate::primitive::{Tetragon, Trigon};

    #[test]
    fn decreasing_summand() {
        let graph = MeshGraph::<Point2<f64>>::from_raw_buffers(
            vec![Tetragon::new(0usize, 1, 2, 3)],
            vec![(-1.0, -1.0), (1.0, -1.0), (1.0, 1.0), (-1.0, 1.0)],
        )
        .unwrap();
        let vertex = graph.vertices().next().unwrap();
        assert_eq!(
            Err(EntityError::Data),
            dijkstra::metrics_with(vertex, None, |_, _| -1isize)
        )
    }

    #[test]
    fn logical_metrics() {
        let graph = MeshGraph::<()>::from_raw_buffers(vec![Trigon::new(0usize, 1, 2)], vec![(); 3])
            .unwrap();
        let vertex = graph.vertices().next().unwrap();
        let metrics = dijkstra::metrics_with(vertex, None, |_, _| 1usize).unwrap();
        let a = vertex.key();
        let b = vertex.outgoing_arc().destination_vertex().key();
        let c = vertex.outgoing_arc().next_arc().destination_vertex().key();
        let aq = *metrics.get(&a).unwrap();
        let bq = *metrics.get(&b).unwrap();
        let cq = *metrics.get(&c).unwrap();

        assert_eq!(aq, (None, 0));
        assert_eq!(bq, (Some(a), 1));
        assert_eq!(cq, (Some(a), 1));
    }

    // TODO: Use approximated comparisons in assertions.
    #[test]
    fn euclidean_distance_metrics() {
        let graph = MeshGraph::<Point2<f64>>::from_raw_buffers(
            vec![Tetragon::new(0usize, 1, 2, 3)],
            vec![(-1.0, -1.0), (1.0, -1.0), (1.0, 1.0), (-1.0, 1.0)],
        )
        .unwrap();
        let vertex = graph.vertices().next().unwrap();
        let metrics: MetricTree<_, R64> = dijkstra::metrics_with(vertex, None, |from, to| {
            R64::assert((to.position() - from.position()).magnitude())
        })
        .unwrap();
        let a = vertex.key();
        let b = vertex.outgoing_arc().destination_vertex().key();
        let c = vertex.outgoing_arc().next_arc().destination_vertex().key();
        let d = vertex
            .outgoing_arc()
            .next_arc()
            .next_arc()
            .destination_vertex()
            .key();
        let aq = *metrics.get(&a).unwrap();
        let bq = *metrics.get(&b).unwrap();
        let cq = *metrics.get(&c).unwrap();
        let dq = *metrics.get(&d).unwrap();

        assert_eq!(aq, (None, R64::assert(0.0)));
        assert_eq!(bq, (Some(a), R64::assert(2.0)));
        assert_eq!(cq, (Some(b), R64::assert(4.0)));
        assert_eq!(dq, (Some(a), R64::assert(2.0)));
    }
}


================================================
FILE: plexus/src/entity/mod.rs
================================================
pub mod borrow;
pub mod dijkstra;
pub mod storage;
pub mod traverse;
pub mod view;

use thiserror::Error;

use crate::entity::storage::{Dispatch, Key, Storage};

#[derive(Debug, Eq, Error, PartialEq)]
pub enum EntityError {
    #[error("required entity not found")]
    EntityNotFound,
    #[error("data operation failed")]
    Data,
}

pub trait Entity: Sized {
    type Key: Key;
    type Storage: Default + Dispatch<Self> + Storage<Self>;
}

pub trait Payload: Entity {
    type Data;

    fn get(&self) -> &Self::Data;

    fn get_mut(&mut self) -> &mut Self::Data;
}


================================================
FILE: plexus/src/entity/storage/hash.rs
================================================
use ahash::AHashMap;
use std::hash::Hash;
use std::marker::PhantomData;

use crate::entity::storage::{
    AsStorage, AsStorageMut, DependentStorage, Dispatch, Dynamic, Enumerate, Get, IncrementalKeyer,
    IndependentStorage, InnerKey, Insert, InsertWithKey, Key, Keyer, Mode, Remove, Static,
    StorageTarget,
};
use crate::entity::{Entity, Payload};

// TODO: The `Keyer` parameter `R` of `HashStorage` cannot be parameterized when
//       implementing the `AsStorage` and `Dispatch` traits even if the
//       conflicting implementations use a private local type or the `Keyer`
//       trait is private. Instead, this is implemented more specifically for
//       `IncrementalKeyer`. Perhaps this will be possible in the future.
//
//       See https://github.com/rust-lang/rust/issues/48869

pub struct HashStorage<E, R = (), P = Static>
where
    E: Entity,
    R: Default,
    P: Mode,
{
    inner: AHashMap<InnerKey<<E as Entity>::Key>, E>,
    keyer: R,
    phantom: PhantomData<fn() -> P>,
}

impl<E, R, P> HashStorage<E, R, P>
where
    E: Entity,
    InnerKey<E::Key>: Eq + Hash,
    R: Default,
    P: Mode,
{
    pub fn shrink_to_fit(&mut self) {
        self.inner.shrink_to_fit();
    }
}

impl<E> AsStorage<E> for HashStorage<E, (), Dynamic>
where
    E: Entity<Storage = Self>,
    InnerKey<E::Key>: Eq + Hash,
{
    fn as_storage(&self) -> &StorageTarget<E> {
        self
    }
}

impl<E> AsStorage<E> for HashStorage<E, IncrementalKeyer, Dynamic>
where
    E: Entity<Storage = Self>,
    E::Key: Key<Inner = u64>,
{
    fn as_storage(&self) -> &StorageTarget<E> {
        self
    }
}

impl<E, R> AsStorage<E> for HashStorage<E, R, Static>
where
    E: Entity<Storage = Self>,
    InnerKey<E::Key>: Eq + Hash,
    R: 'static + Default,
{
    fn as_storage(&self) -> &StorageTarget<E> {
        self
    }
}

impl<E> AsStorageMut<E> for HashStorage<E, (), Dynamic>
where
    E: Entity<Storage = Self>,
    InnerKey<E::Key>: Eq + Hash,
{
    fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
        self
    }
}

impl<E> AsStorageMut<E> for HashStorage<E, IncrementalKeyer, Dynamic>
where
    E: Entity<Storage = Self>,
    E::Key: Key<Inner = u64>,
{
    fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
        self
    }
}

impl<E, R> AsStorageMut<E> for HashStorage<E, R, Static>
where
    E: Entity<Storage = Self>,
    InnerKey<E::Key>: Eq + Hash,
    R: 'static + Default,
{
    fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
        self
    }
}

impl<E, R, P> Default for HashStorage<E, R, P>
where
    E: Entity,
    R: Default,
    P: Mode,
{
    fn default() -> Self {
        HashStorage {
            inner: Default::default(),
            keyer: Default::default(),
            phantom: PhantomData,
        }
    }
}

#[rustfmt::skip]
impl<E> Dispatch<E> for HashStorage<E, (), Dynamic>
where
    E: Entity<Storage = Self>,
    InnerKey<E::Key>: Eq + Hash,
{
    type Target<'a> = dyn 'a + DependentStorage<E> where E: 'a;
}

#[rustfmt::skip]
impl<E> Dispatch<E> for HashStorage<E, IncrementalKeyer, Dynamic>
where
    E: Entity<Storage = Self>,
    E::Key: Key<Inner = u64>,
{
    type Target<'a> = dyn 'a + IndependentStorage<E> where E: 'a;
}

#[rustfmt::skip]
impl<E, R> Dispatch<E> for HashStorage<E, R, Static>
where
    E: Entity<Storage = Self>,
    InnerKey<E::Key>: Eq + Hash,
    R: 'static + Default,
{
    type Target<'a> = Self where E: 'a;
}

impl<E, R, P> Enumerate<E> for HashStorage<E, R, P>
where
    E: Entity,
    InnerKey<E::Key>: Eq + Hash,
    R: Default,
    P: Mode,
{
    fn len(&self) -> usize {
        self.inner.len()
    }

    fn iter(&self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ E)>> {
        Box::new(
            self.inner
                .iter()
                .map(|(key, entity)| (E::Key::from_inner(*key), entity)),
        )
    }

    fn iter_mut(&mut self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ mut E::Data)>>
    where
        E: Payload,
    {
        Box::new(
            self.inner
                .iter_mut()
                .map(|(key, entity)| (E::Key::from_inner(*key), entity.get_mut())),
        )
    }
}

impl<E, R, P> Get<E> for HashStorage<E, R, P>
where
    E: Entity,
    InnerKey<E::Key>: Eq + Hash,
    R: Default,
    P: Mode,
{
    fn get(&self, key: &E::Key) -> Option<&E> {
        self.inner.get(&key.into_inner())
    }

    fn get_mut(&mut self, key: &E::Key) -> Option<&mut E> {
        self.inner.get_mut(&key.into_inner())
    }
}

impl<E, R, P> Insert<E> for HashStorage<E, R, P>
where
    E: Entity,
    InnerKey<E::Key>: Eq + Hash,
    R: Keyer<E::Key>,
    P: Mode,
{
    fn insert(&mut self, entity: E) -> E::Key {
        let key = self.keyer.next();
        self.inner.insert(key, entity);
        Key::from_inner(key)
    }
}

impl<E, P> InsertWithKey<E> for HashStorage<E, (), P>
where
    E: Entity,
    InnerKey<E::Key>: Eq + Hash,
    P: Mode,
{
    fn insert_with_key(&mut self, key: &E::Key, entity: E) -> Option<E> {
        self.inner.insert(key.into_inner(), entity)
    }
}

impl<E, R, P> Remove<E> for HashStorage<E, R, P>
where
    E: Entity,
    InnerKey<E::Key>: Eq + Hash,
    R: Default,
    P: Mode,
{
    fn remove(&mut self, key: &E::Key) -> Option<E> {
        self.inner.remove(&key.into_inner())
    }
}


================================================
FILE: plexus/src/entity/storage/mod.rs
================================================
mod hash;

use std::hash::Hash;

use crate::entity::{Entity, Payload};

pub use crate::entity::storage::hash::HashStorage;

pub mod prelude {
    pub use crate::entity::storage::{Enumerate, Get, Insert, InsertWithKey, Remove};
}

pub type StorageTarget<'a, E> = <<E as Entity>::Storage as Dispatch<E>>::Target<'a>;

pub type InnerKey<K> = <K as Key>::Inner;

pub trait Key: Copy + Eq + Hash + Sized {
    type Inner: Copy + Sized;

    fn from_inner(key: Self::Inner) -> Self;

    fn into_inner(self) -> Self::Inner;
}

pub trait Keyer<K>: Clone + Default
where
    K: Key,
{
    fn next(&mut self) -> K::Inner;
}

#[derive(Clone, Copy, Default)]
pub struct IncrementalKeyer {
    key: u64,
}

impl<K> Keyer<K> for IncrementalKeyer
where
    K: Key<Inner = u64>,
{
    fn next(&mut self) -> K::Inner {
        let key = self.key;
        self.key = self.key.checked_add(1).expect("keyspace exhausted");
        key
    }
}

#[rustfmt::skip]
pub trait Dispatch<E>
where
    E: Entity,
{
    type Target<'a>: 'a + ?Sized + Storage<E>
    where
        E: 'a;
}

pub trait Mode {}

pub enum Static {}

impl Mode for Static {}

pub enum Dynamic {}

impl Mode for Dynamic {}

// TODO: GATs cannot yet be used here while still supporting trait objects,
//       because the types cannot be bound in a supertrait. To support trait
//       objects, the associated types must be bound (likely to `Box<dyn ...>`).
//       See https://github.com/rust-lang/rust/issues/67510
pub trait Enumerate<E>
where
    E: Entity,
{
    fn len(&self) -> usize;

    fn iter(&self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ E)>>;

    fn iter_mut(&mut self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ mut E::Data)>>
    where
        E: Payload;
}

pub trait Get<E>
where
    E: Entity,
{
    fn get(&self, key: &E::Key) -> Option<&E>;

    fn get_mut(&mut self, key: &E::Key) -> Option<&mut E>;

    fn contains_key(&self, key: &E::Key) -> bool {
        self.get(key).is_some()
    }
}

pub trait Insert<E>
where
    E: Entity,
{
    fn insert(&mut self, entity: E) -> E::Key;
}

pub trait InsertWithKey<E>
where
    E: Entity,
{
    fn insert_with_key(&mut self, key: &E::Key, entity: E) -> Option<E>;
}

pub trait Remove<E>
where
    E: Entity,
{
    fn remove(&mut self, key: &E::Key) -> Option<E>;
}

pub trait Storage<E>: AsStorage<E> + AsStorageMut<E> + Enumerate<E> + Get<E> + Remove<E>
where
    E: Entity,
{
}

impl<T, E> Storage<E> for T
where
    T: AsStorage<E> + AsStorageMut<E> + Enumerate<E> + Get<E> + Remove<E>,
    E: Entity,
{
}

pub trait DependentStorage<E>: InsertWithKey<E> + Storage<E>
where
    E: Entity,
{
}

impl<T, E> DependentStorage<E> for T
where
    T: InsertWithKey<E> + Storage<E>,
    E: Entity,
{
}

pub trait IndependentStorage<E>: Insert<E> + Storage<E>
where
    E: Entity,
{
}

impl<T, E> IndependentStorage<E> for T
where
    T: Insert<E> + Storage<E>,
    E: Entity,
{
}

pub trait Fuse<M, T>
where
    M: AsStorage<T>,
    T: Entity,
{
    type Output: AsStorage<T>;

    fn fuse(self, source: M) -> Self::Output;
}

// TODO: It may not be possible for storage wrapper types to implement this
//       generally for all underlying storage types when using trait objects. An
//       input type parameter for the wrapped storage type may be required with
//       an implementation for each type that can be wrapped. Is there some way
//       to support blanket implementations?
pub trait AsStorage<E>
where
    E: Entity,
{
    fn as_storage(&self) -> &StorageTarget<E>;
}

impl<E, T> AsStorage<E> for &'_ T
where
    E: Entity,
    T: AsStorage<E> + ?Sized,
{
    fn as_storage(&self) -> &StorageTarget<E> {
        <T as AsStorage<E>>::as_storage(self)
    }
}

impl<E, T> AsStorage<E> for &'_ mut T
where
    E: Entity,
    T: AsStorage<E> + ?Sized,
{
    fn as_storage(&self) -> &StorageTarget<E> {
        <T as AsStorage<E>>::as_storage(self)
    }
}

pub trait AsStorageMut<E>: AsStorage<E>
where
    E: Entity,
{
    fn as_storage_mut(&mut self) -> &mut StorageTarget<E>;
}

impl<E, T> AsStorageMut<E> for &'_ mut T
where
    E: Entity,
    T: AsStorageMut<E> + ?Sized,
{
    fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
        <T as AsStorageMut<E>>::as_storage_mut(self)
    }
}

pub trait AsStorageOf {
    fn as_storage_of<E>(&self) -> &StorageTarget<E>
    where
        E: Entity,
        Self: AsStorage<E>,
    {
        self.as_storage()
    }

    fn as_storage_mut_of<E>(&mut self) -> &mut StorageTarget<E>
    where
        E: Entity,
        Self: AsStorageMut<E>,
    {
        self.as_storage_mut()
    }
}

impl<T> AsStorageOf for T {}


================================================
FILE: plexus/src/entity/traverse.rs
================================================
use std::collections::{HashSet, VecDeque};
use std::hash::Hash;
use std::marker::PhantomData;

use crate::entity::borrow::Reborrow;
use crate::entity::storage::{AsStorage, Enumerate};
use crate::entity::view::{Bind, ClosedView, Unbind};

pub enum Breadth {}
pub enum Depth {}

pub trait Buffer<R, T>: Default + Extend<T>
where
    R: Order<T>,
{
    fn push(&mut self, item: T);
    fn pop(&mut self) -> Option<T>;
}

impl<T> Buffer<Depth, T> for Vec<T> {
    fn push(&mut self, item: T) {
        Vec::<T>::push(self, item)
    }

    fn pop(&mut self) -> Option<T> {
        Vec::<T>::pop(self)
    }
}

impl<T> Buffer<Breadth, T> for VecDeque<T> {
    fn push(&mut self, item: T) {
        VecDeque::<T>::push_back(self, item)
    }

    fn pop(&mut self) -> Option<T> {
        VecDeque::<T>::pop_front(self)
    }
}

/// Traversal ordering.
///
/// Provides a default type implementing [`Buffer`] for the ordering described
/// by `Self`. This reduces the number of required type parameters in types
/// implementing traversals, as only an ordering type is needed to derive the
/// buffer. Note that the item type can typically be derived from other required
/// type parameters.
///
/// See [`Traversal`].
///
/// [`Buffer`]: crate::entity::traverse::Buffer
/// [`Traversal`]: crate::entity::traverse::Traversal
pub trait Order<T>: Sized {
    type Buffer: Buffer<Self, T>;
}

impl<T> Order<T> for Breadth {
    type Buffer = VecDeque<T>;
}

impl<T> Order<T> for Depth {
    type Buffer = Vec<T>;
}

pub trait Adjacency: ClosedView {
    type Output: IntoIterator<Item = Self::Key>;

    fn adjacency(&self) -> Self::Output;
}

#[derive(Debug)]
pub struct Traversal<B, T, R = Depth>
where
    B: Reborrow,
    B::Target: AsStorage<T::Entity>,
    T: Adjacency,
    R: Order<T::Key>,
{
    storage: B,
    breadcrumbs: HashSet<T::Key>,
    buffer: R::Buffer,
    phantom: PhantomData<fn() -> T>,
}

impl<B, T, R> Clone for Traversal<B, T, R>
where
    B: Clone + Reborrow,
    B::Target: AsStorage<T::Entity>,
    T: Adjacency,
    R: Order<T::Key>,
    R::Buffer: Clone,
{
    fn clone(&self) -> Self {
        Traversal {
            storage: self.storage.clone(),
            breadcrumbs: self.breadcrumbs.clone(),
            buffer: self.buffer.clone(),
            phantom: PhantomData,
        }
    }
}

impl<B, T, R> From<T> for Traversal<B, T, R>
where
    B: Reborrow,
    B::Target: AsStorage<T::Entity>,
    T: Adjacency + Unbind<B>,
    R: Order<T::Key>,
{
    fn from(view: T) -> Self {
        let (storage, key) = view.unbind();
        let capacity = storage.reborrow().as_storage().len();
        let mut buffer = R::Buffer::default();
        
Download .txt
gitextract_cu48aqwt/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── continuous-integration.yml
├── .gitignore
├── Cargo.toml
├── LICENSE
├── README.md
├── benches/
│   └── subdivide.rs
├── data/
│   ├── cube.ply
│   ├── plexus.ply
│   └── teapot.ply
├── doc/
│   └── katex-header.html
├── examples/
│   ├── sphere/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── main.rs
│   ├── subdivide/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── main.rs
│   └── teapot/
│       ├── Cargo.toml
│       └── src/
│           └── main.rs
├── pictor/
│   ├── Cargo.toml
│   └── src/
│       ├── camera.rs
│       ├── harness.rs
│       ├── lib.rs
│       ├── pipeline.rs
│       ├── renderer.rs
│       ├── shader.glsl.frag
│       ├── shader.glsl.vert
│       ├── shader.spv.frag
│       └── shader.spv.vert
├── plexus/
│   ├── Cargo.toml
│   └── src/
│       ├── buffer/
│       │   ├── builder.rs
│       │   └── mod.rs
│       ├── builder.rs
│       ├── constant.rs
│       ├── encoding/
│       │   ├── mod.rs
│       │   └── ply.rs
│       ├── entity/
│       │   ├── borrow.rs
│       │   ├── dijkstra.rs
│       │   ├── mod.rs
│       │   ├── storage/
│       │   │   ├── hash.rs
│       │   │   └── mod.rs
│       │   ├── traverse.rs
│       │   └── view.rs
│       ├── geometry/
│       │   ├── mod.rs
│       │   └── partition.rs
│       ├── graph/
│       │   ├── builder.rs
│       │   ├── core.rs
│       │   ├── data.rs
│       │   ├── edge.rs
│       │   ├── face.rs
│       │   ├── geometry.rs
│       │   ├── mod.rs
│       │   ├── mutation/
│       │   │   ├── edge.rs
│       │   │   ├── face.rs
│       │   │   ├── mod.rs
│       │   │   ├── path.rs
│       │   │   └── vertex.rs
│       │   ├── path.rs
│       │   └── vertex.rs
│       ├── index.rs
│       ├── integration/
│       │   ├── cgmath.rs
│       │   ├── glam.rs
│       │   ├── mint.rs
│       │   ├── mod.rs
│       │   ├── nalgebra.rs
│       │   └── ultraviolet.rs
│       ├── lib.rs
│       ├── primitive/
│       │   ├── cube.rs
│       │   ├── decompose.rs
│       │   ├── generate.rs
│       │   ├── mod.rs
│       │   └── sphere.rs
│       └── transact.rs
├── rustdoc.sh
└── rustfmt.toml
Download .txt
SYMBOL INDEX (1716 symbols across 50 files)

FILE: benches/subdivide.rs
  constant DEPTH (line 9) | const DEPTH: usize = 8;
  type E3 (line 11) | type E3 = Point3<f64>;
  type Ambo (line 13) | pub trait Ambo<G> {
    method ambo (line 15) | fn ambo(self) -> Self;
  function ambo (line 25) | fn ambo(self) -> Self {
  function tetragon (line 45) | fn tetragon() -> MeshGraph<E3> {
  function subdivide (line 55) | fn subdivide(mut graph: MeshGraph<E3>) {
  function benchmark (line 66) | fn benchmark(criterion: &mut Criterion) {

FILE: examples/sphere/src/main.rs
  type E3 (line 9) | type E3 = Point3<f32>;
  function main (line 11) | fn main() {

FILE: examples/subdivide/src/main.rs
  type E3 (line 10) | type E3 = Point3<f32>;
  type Ambo (line 12) | pub trait Ambo<G>: ClosedView {
    method ambo (line 14) | fn ambo(self) -> Self;
  function ambo (line 24) | fn ambo(self) -> Self {
  function main (line 44) | fn main() {

FILE: examples/teapot/src/main.rs
  type E3 (line 7) | type E3 = Point3<f32>;
  function main (line 9) | fn main() {

FILE: pictor/src/camera.rs
  type Projection (line 16) | pub enum Projection {
    method perspective (line 22) | pub fn perspective(aspect: f32, fov: f32, near: f32, far: f32) -> Self {
    method orthographic (line 26) | pub fn orthographic(left: f32, right: f32, bottom: f32, top: f32, near...
    method as_ref (line 32) | fn as_ref(&self) -> &Matrix4<f32> {
  type Camera (line 41) | pub struct Camera {
    method look_at (line 47) | pub fn look_at(&mut self, from: &Point3<f32>, to: &Point3<f32>) {
    method reproject (line 51) | pub fn reproject(&mut self, surface: &SurfaceConfiguration) {
    method transform (line 64) | pub fn transform(&self) -> Matrix4<f32> {
    method from (line 70) | fn from(projection: Projection) -> Self {

FILE: pictor/src/harness.rs
  type Executor (line 15) | struct Executor {
    method new (line 21) | pub fn new() -> Self {
    method flush (line 27) | pub fn flush(&mut self) {
    method spawner (line 31) | pub fn spawner(&self) -> &impl LocalSpawn {
  type Activity (line 37) | struct Activity<T> {
  function bind_and_configure (line 47) | pub fn bind_and_configure(window: Window, configuration: T::Configuratio...
  type Harness (line 60) | struct Harness<T, F> {
  function redraw (line 70) | fn redraw(&mut self) {
  function resize (line 83) | fn resize(&mut self, dimensions: PhysicalSize<u32>) {
  function resumed (line 102) | fn resumed(&mut self, reactor: &ActiveEventLoop) {
  function suspended (line 110) | fn suspended(&mut self, _reactor: &ActiveEventLoop) {
  function window_event (line 114) | fn window_event(&mut self, reactor: &ActiveEventLoop, _: WindowId, event...
  type Reaction (line 138) | pub enum Reaction {
  type ConfigureStage (line 144) | pub trait ConfigureStage {
    method device (line 145) | fn device(&self) -> &wgpu::Device;
    method queue (line 147) | fn queue(&self) -> &wgpu::Queue;
    method surface_configuration (line 149) | fn surface_configuration(&self) -> &wgpu::SurfaceConfiguration;
  type RenderStage (line 152) | pub trait RenderStage {
    method device (line 153) | fn device(&self) -> &wgpu::Device;
    method queue (line 155) | fn queue(&self) -> &wgpu::Queue;
  type Application (line 158) | pub trait Application: 'static + Sized {
    method configure (line 162) | fn configure(
    method react (line 167) | fn react(&mut self, event: WindowEvent) -> Reaction {
    method resize (line 172) | fn resize(&mut self, stage: &impl ConfigureStage);
    method render (line 174) | fn render(
  function run (line 182) | pub fn run<T, F>(f: F)

FILE: pictor/src/pipeline.rs
  type Color4 (line 29) | pub struct Color4<T>(pub Vector4<T>)
  function white (line 37) | pub fn white() -> Self
  function random (line 44) | pub fn random() -> Self
  function as_ref (line 59) | fn as_ref(&self) -> &Vector4<T> {
  method default (line 68) | fn default() -> Self {
  function from (line 77) | fn from(vector: Vector4<T>) -> Self {
  function from (line 86) | fn from(color: Color4<T>) -> Self {
  type Vertex (line 95) | pub struct Vertex {
  method hash (line 104) | fn hash<H>(&self, state: &mut H)
  method eq (line 115) | fn eq(&self, other: &Self) -> bool {
  type RenderConfiguration (line 130) | struct RenderConfiguration {
  type RenderApplication (line 137) | struct RenderApplication {
    method configure_depth_buffer (line 150) | fn configure_depth_buffer(stage: &impl ConfigureStage) -> wgpu::Textur...
  type Configuration (line 172) | type Configuration = RenderConfiguration;
  type Error (line 173) | type Error = ();
  method configure (line 175) | fn configure(
  method react (line 350) | fn react(&mut self, event: WindowEvent) -> Reaction {
  method resize (line 365) | fn resize(&mut self, stage: &impl ConfigureStage) {
  method render (line 375) | fn render(&mut self, stage: &impl RenderStage, view: &wgpu::TextureView,...
  function render_mesh_buffer_with (line 414) | pub fn render_mesh_buffer_with<F>(from: Point3<f32>, to: Point3<f32>, mu...

FILE: pictor/src/renderer.rs
  type Renderer (line 7) | pub struct Renderer<'window> {
  function try_from_window (line 17) | pub async fn try_from_window<T>(window: T) -> Result<Self, ()>
  method device (line 59) | fn device(&self) -> &wgpu::Device {
  method queue (line 63) | fn queue(&self) -> &wgpu::Queue {
  method surface_configuration (line 67) | fn surface_configuration(&self) -> &wgpu::SurfaceConfiguration {
  method device (line 73) | fn device(&self) -> &wgpu::Device {
  method queue (line 77) | fn queue(&self) -> &wgpu::Queue {

FILE: plexus/src/buffer/builder.rs
  type VertexKey (line 19) | pub type VertexKey<R> = <Vec<<R as Grouping>::Group> as IndexBuffer<R>>:...
  type BufferBuilder (line 21) | pub struct BufferBuilder<R, G>
  method default (line 34) | fn default() -> Self {
  type Input (line 47) | type Input = ();
  type Facet (line 57) | type Facet = ();
  type Key (line 58) | type Key = ();
  function insert_facet (line 60) | fn insert_facet<T, U>(&mut self, keys: T, _: U) -> Result<Self::Key, Sel...
  type Facet (line 88) | type Facet = ();
  type Key (line 89) | type Key = ();
  function insert_facet (line 91) | fn insert_facet<T, U>(&mut self, keys: T, _: U) -> Result<Self::Key, Sel...
  type Builder (line 113) | type Builder = Self;
  type Vertex (line 115) | type Vertex = G;
  type Facet (line 116) | type Facet = ();
  method surface_with (line 118) | fn surface_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
  type Builder (line 135) | type Builder = Self;
  type Key (line 136) | type Key = VertexKey<R>;
  type Vertex (line 138) | type Vertex = G;
  type Facet (line 139) | type Facet = ();
  method facets_with (line 141) | fn facets_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
  method insert_vertex (line 149) | fn insert_vertex<T>(&mut self, data: T) -> Result<Self::Key, Self::Error>
  type Commit (line 165) | type Commit = MeshBuffer<R, G>;
  type Abort (line 166) | type Abort = ();
  type Error (line 167) | type Error = BufferError;
  function commit (line 169) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 174) | fn abort(self) -> Self::Abort {}

FILE: plexus/src/buffer/mod.rs
  type BufferError (line 119) | pub enum BufferError {
  type MeshBuffer3 (line 166) | pub type MeshBuffer3<N, G> = MeshBuffer<Trigon<N>, G>;
  type MeshBuffer4 (line 178) | pub type MeshBuffer4<N, G> = MeshBuffer<Tetragon<N>, G>;
  type MeshBufferN (line 184) | pub type MeshBufferN<N, G> = MeshBuffer<UnboundedPolygon<N>, G>;
  type FromRawBuffers (line 187) | pub trait FromRawBuffers<N, G>: Sized {
    method from_raw_buffers (line 197) | fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Sel...
  type FromRawBuffersWithArity (line 204) | pub trait FromRawBuffersWithArity<N, G>: Sized {
    method from_raw_buffers_with_arity (line 215) | fn from_raw_buffers_with_arity<I, J>(
  type IntoFlatIndex (line 227) | pub trait IntoFlatIndex<G, const N: usize>
    method into_flat_index (line 234) | fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, N>, G>;
  type IntoStructuredIndex (line 239) | pub trait IntoStructuredIndex<G>
    method into_structured_index (line 245) | fn into_structured_index(self) -> MeshBuffer<Self::Item, G>;
  type MeshBuffer (line 266) | pub struct MeshBuffer<R, G>
  function from_raw_buffers_unchecked (line 279) | pub(in crate::buffer) fn from_raw_buffers_unchecked(
  function new (line 296) | pub fn new() -> Self {
  function into_raw_buffers (line 306) | pub fn into_raw_buffers(self) -> (Vec<R::Group>, Vec<G>) {
  function map_vertices (line 337) | pub fn map_vertices<H, F>(self, f: F) -> MeshBuffer<R, H>
  function as_index_slice (line 349) | pub fn as_index_slice(&self) -> &[R::Group] {
  function as_vertex_slice (line 354) | pub fn as_vertex_slice(&self) -> &[G] {
  type Builder (line 400) | type Builder = BufferBuilder<R, G>;
  type Error (line 401) | type Error = BufferError;
  type Vertex (line 403) | type Vertex = G;
  type Facet (line 404) | type Facet = ();
  method builder (line 406) | fn builder() -> Self::Builder {
  method default (line 416) | fn default() -> Self {
  type Dynamic (line 430) | type Dynamic = <Flat<T, N> as StaticArity>::Static;
  method arity (line 432) | fn arity(&self) -> Self::Dynamic {
  type Dynamic (line 442) | type Dynamic = <P as StaticArity>::Static;
  method arity (line 444) | fn arity(&self) -> Self::Dynamic {
  type Dynamic (line 453) | type Dynamic = MeshArity;
  method arity (line 455) | fn arity(&self) -> Self::Dynamic {
  type Dynamic (line 464) | type Dynamic = MeshArity;
  method arity (line 466) | fn arity(&self) -> Self::Dynamic {
  type Static (line 477) | type Static = <R as StaticArity>::Static;
  constant ARITY (line 479) | const ARITY: Self::Static = R::ARITY;
  function append (line 494) | pub fn append<R, H>(&mut self, buffer: &mut MeshBuffer<R, H>) -> Result<...
  function append (line 524) | pub fn append<R, H>(&mut self, buffer: &mut MeshBuffer<R, H>) -> Result<...
  function from (line 559) | fn from(polygon: P) -> Self {
  type Error (line 582) | type Error = <Self as FromRawBuffers<P, G>>::Error;
  function from_encoding (line 584) | fn from_encoding(
  type Error (line 612) | type Error = <Self as FromRawBuffers<R::Group, G>>::Error;
  function from_indexer (line 614) | fn from_indexer<I, M>(input: I, indexer: M) -> Result<Self, Self::Error>
  function from_iter (line 636) | fn from_iter<I>(input: I) -> Self
  type Error (line 652) | type Error = BufferError;
  function from_raw_buffers (line 692) | fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Buffe...
  type Error (line 726) | type Error = BufferError;
  function from_raw_buffers (line 756) | fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Buffe...
  type Item (line 788) | type Item = T;
  function into_flat_index (line 790) | fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, N>, G> {
  type Item (line 799) | type Item = N;
  function into_flat_index (line 830) | fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, 3>, G> {
  type Item (line 846) | type Item = N;
  function into_flat_index (line 877) | fn into_flat_index(self) -> MeshBuffer<Flat<Self::Item, 4>, G> {
  type Output (line 895) | type Output = vec::IntoIter<Self::Polygon>;
  type Polygon (line 896) | type Polygon = Trigon<G>;
  method into_polygons (line 902) | fn into_polygons(self) -> Self::Output {
  type Output (line 927) | type Output = vec::IntoIter<Self::Polygon>;
  type Polygon (line 928) | type Polygon = Tetragon<G>;
  method into_polygons (line 961) | fn into_polygons(self) -> Self::Output {
  type Output (line 989) | type Output = vec::IntoIter<Self::Polygon>;
  type Polygon (line 990) | type Polygon = <P::Group as Map<G>>::Output;
  method into_polygons (line 1023) | fn into_polygons(self) -> Self::Output {
  type Item (line 1044) | type Item = P;
  function into_structured_index (line 1046) | fn into_structured_index(self) -> MeshBuffer<Self::Item, G> {
  type Item (line 1056) | type Item = Trigon<N>;
  function into_structured_index (line 1089) | fn into_structured_index(self) -> MeshBuffer<Self::Item, G> {
  type Item (line 1107) | type Item = Tetragon<N>;
  function into_structured_index (line 1137) | fn into_structured_index(self) -> MeshBuffer<Self::Item, G> {
  type E3 (line 1164) | type E3 = Point3<R64>;
  function collect_into_flat_buffer (line 1167) | fn collect_into_flat_buffer() {
  function collect_into_bounded_buffer (line 1178) | fn collect_into_bounded_buffer() {
  function collect_into_unbounded_buffer (line 1188) | fn collect_into_unbounded_buffer() {
  function append_structured_buffers (line 1200) | fn append_structured_buffers() {
  function convert_mesh_to_buffer_by_vertex (line 1217) | fn convert_mesh_to_buffer_by_vertex() {
  function convert_mesh_to_buffer_by_face (line 1228) | fn convert_mesh_to_buffer_by_face() {

FILE: plexus/src/builder.rs
  type Buildable (line 74) | pub trait Buildable: Sized {
    method builder (line 101) | fn builder() -> Self::Builder;
  type MeshBuilder (line 123) | pub trait MeshBuilder: ClosedInput {
    method surface_with (line 135) | fn surface_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
    method build (line 150) | fn build(self) -> Result<Self::Commit, Self::Error> {
  type SurfaceBuilder (line 155) | pub trait SurfaceBuilder: ClosedInput {
    method facets_with (line 175) | fn facets_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
    method insert_vertex (line 186) | fn insert_vertex<T>(&mut self, data: T) -> Result<Self::Key, Self::Error>
  type FacetBuilder (line 191) | pub trait FacetBuilder<K>: ClosedInput
    method insert_facet (line 210) | fn insert_facet<T, U>(&mut self, keys: T, data: U) -> Result<Self::Key...

FILE: plexus/src/constant.rs
  type ConstantOf (line 13) | pub type ConstantOf<N> = <N as ToConstant>::Output;
  type TypeOf (line 14) | pub type TypeOf<const N: usize> = <Constant<N> as ToType>::Output;
  type Constant (line 16) | pub struct Constant<const N: usize>;
  type ToConstant (line 18) | pub trait ToConstant {
  type ToType (line 22) | pub trait ToType {

FILE: plexus/src/encoding/mod.rs
  type VertexDecoder (line 23) | pub trait VertexDecoder {
  type FaceDecoder (line 28) | pub trait FaceDecoder {
  type FromEncoding (line 37) | pub trait FromEncoding<E>: Sized
    method from_encoding (line 43) | fn from_encoding(

FILE: plexus/src/encoding/ply.rs
  type Header (line 70) | pub type Header = KeyMap<ElementDefinition>;
  type Payload (line 71) | pub type Payload = KeyMap<Vec<Element>>;
  type Element (line 72) | pub type Element = KeyMap<Property>;
  type Ply (line 74) | pub struct Ply {
    method parse (line 80) | pub fn parse(mut read: impl Read) -> io::Result<Self> {
  type PlyError (line 92) | pub enum PlyError {
    method from (line 110) | fn from(error: io::Error) -> Self {
  type ElementExt (line 115) | pub trait ElementExt {
    method scalar (line 116) | fn scalar<K, T>(&self, key: K) -> Result<T, PlyError>
    method list (line 121) | fn list<K, T, I>(&self, key: K) -> Result<I, PlyError>
    method scalar (line 129) | fn scalar<K, T>(&self, key: K) -> Result<T, PlyError>
    method list (line 140) | fn list<K, T, I>(&self, key: K) -> Result<I, PlyError>
  type PropertyExt (line 153) | pub trait PropertyExt {
    method into_scalar (line 154) | fn into_scalar<T>(self) -> Result<T, PlyError>
    method into_list (line 158) | fn into_list<T, I>(self) -> Result<I, PlyError>
    method into_scalar (line 165) | fn into_scalar<T>(self) -> Result<T, PlyError>
    method into_list (line 182) | fn into_list<T, I>(self) -> Result<I, PlyError>
  type VertexElementDecoder (line 201) | pub trait VertexElementDecoder {
    method decode_vertex_elements (line 202) | fn decode_vertex_elements<'a>(
  type VertexPropertyDecoder (line 211) | pub trait VertexPropertyDecoder: VertexDecoder {
    method decode_vertex_properties (line 212) | fn decode_vertex_properties<'a, I>(
    method decode_vertex_properties (line 352) | fn decode_vertex_properties<'a, I>(
  type FaceElementDecoder (line 221) | pub trait FaceElementDecoder {
    method decode_face_elements (line 222) | fn decode_face_elements<'a>(
  type FacePropertyDecoder (line 231) | pub trait FacePropertyDecoder: FaceDecoder {
    method decode_face_properties (line 232) | fn decode_face_properties<'a, I>(
    method decode_face_properties (line 322) | fn decode_face_properties<'a, I>(
  type FromPly (line 241) | pub trait FromPly<E>: Sized {
    method from_ply (line 242) | fn from_ply(decoder: E, read: impl Read) -> Result<(Self, Ply), PlyErr...
  method from_ply (line 250) | fn from_ply(decoder: E, mut read: impl Read) -> Result<(Self, Ply), PlyE...
  type ToPly (line 261) | pub trait ToPly<E> {
    method to_ply (line 262) | fn to_ply(
  type DecodePosition (line 270) | pub trait DecodePosition<N>: FiniteDimensional<N = N> + Sized
    method decode_position (line 274) | fn decode_position(element: &Element) -> Result<Self, PlyError>;
  method decode_position (line 281) | fn decode_position(element: &Element) -> Result<Self, PlyError> {
  method decode_position (line 291) | fn decode_position(element: &Element) -> Result<Self, PlyError> {
  type PositionEncoding (line 301) | pub struct PositionEncoding<T> {
  method default (line 306) | fn default() -> Self {
  type Output (line 314) | type Output = Vec<(Self::Index, Self::Face)>;
  type Index (line 315) | type Index = SmallVec<[usize; 4]>;
  type Face (line 316) | type Face = ();
  type Output (line 341) | type Output = Vec<Self::Vertex>;
  type Vertex (line 342) | type Vertex = T;
  function decode_elements (line 367) | pub fn decode_elements<'a, K>(
  function decode_vertex_properties (line 386) | pub fn decode_vertex_properties<E>(
  function decode_face_properties (line 399) | pub fn decode_face_properties<E>(
  function num_cast_scalar (line 412) | fn num_cast_scalar<T, U>(value: T) -> Result<U, PlyError>
  function num_cast_list (line 420) | fn num_cast_list<T, U, I>(values: Vec<T>) -> Result<I, PlyError>
  type E3 (line 441) | type E3 = Point3<f64>;
  function decode_into_buffer (line 444) | fn decode_into_buffer() {
  function decode_into_graph (line 455) | fn decode_into_graph() {

FILE: plexus/src/entity/borrow.rs
  type Reborrow (line 1) | pub trait Reborrow {
    method reborrow (line 4) | fn reborrow(&self) -> &Self::Target;
    type Target (line 16) | type Target = T;
    method reborrow (line 18) | fn reborrow(&self) -> &Self::Target {
    type Target (line 24) | type Target = T;
    method reborrow (line 26) | fn reborrow(&self) -> &Self::Target {
  type ReborrowMut (line 7) | pub trait ReborrowMut: Reborrow {
    method reborrow_mut (line 8) | fn reborrow_mut(&mut self) -> &mut Self::Target;
    method reborrow_mut (line 32) | fn reborrow_mut(&mut self) -> &mut Self::Target {
  type ReborrowInto (line 11) | pub trait ReborrowInto<'a>: Reborrow {
    method reborrow_into (line 12) | fn reborrow_into(self) -> &'a Self::Target;
  function reborrow_into (line 38) | fn reborrow_into(self) -> &'a Self::Target {
  function reborrow_into (line 44) | fn reborrow_into(self) -> &'a Self::Target {

FILE: plexus/src/entity/dijkstra.rs
  type MetricTree (line 12) | pub type MetricTree<K, Q> = HashMap<K, (Option<K>, Q)>;
  type KeyedMetric (line 16) | struct KeyedMetric<K, Q>(
  function metrics_with (line 23) | pub fn metrics_with<'a, M, T, Q, F>(
  function decreasing_summand (line 97) | fn decreasing_summand() {
  function logical_metrics (line 111) | fn logical_metrics() {
  function euclidean_distance_metrics (line 130) | fn euclidean_distance_metrics() {

FILE: plexus/src/entity/mod.rs
  type EntityError (line 12) | pub enum EntityError {
  type Entity (line 19) | pub trait Entity: Sized {
  type Payload (line 24) | pub trait Payload: Entity {
    method get (line 27) | fn get(&self) -> &Self::Data;
    method get_mut (line 29) | fn get_mut(&mut self) -> &mut Self::Data;

FILE: plexus/src/entity/storage/hash.rs
  type HashStorage (line 20) | pub struct HashStorage<E, R = (), P = Static>
  function shrink_to_fit (line 38) | pub fn shrink_to_fit(&mut self) {
  function as_storage (line 48) | fn as_storage(&self) -> &StorageTarget<E> {
  function as_storage (line 58) | fn as_storage(&self) -> &StorageTarget<E> {
  function as_storage (line 69) | fn as_storage(&self) -> &StorageTarget<E> {
  function as_storage_mut (line 79) | fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
  function as_storage_mut (line 89) | fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
  function as_storage_mut (line 100) | fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
  method default (line 111) | fn default() -> Self {
  type Target (line 126) | type Target<'a> = dyn 'a + DependentStorage<E> where E: 'a;
  type Target (line 135) | type Target<'a> = dyn 'a + IndependentStorage<E> where E: 'a;
  type Target (line 145) | type Target<'a> = Self where E: 'a;
  function len (line 155) | fn len(&self) -> usize {
  function iter (line 159) | fn iter(&self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ E)>> {
  function iter_mut (line 167) | fn iter_mut(&mut self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ mut ...
  function get (line 186) | fn get(&self, key: &E::Key) -> Option<&E> {
  function get_mut (line 190) | fn get_mut(&mut self, key: &E::Key) -> Option<&mut E> {
  function insert (line 202) | fn insert(&mut self, entity: E) -> E::Key {
  function insert_with_key (line 215) | fn insert_with_key(&mut self, key: &E::Key, entity: E) -> Option<E> {
  function remove (line 227) | fn remove(&mut self, key: &E::Key) -> Option<E> {

FILE: plexus/src/entity/storage/mod.rs
  type StorageTarget (line 13) | pub type StorageTarget<'a, E> = <<E as Entity>::Storage as Dispatch<E>>:...
  type InnerKey (line 15) | pub type InnerKey<K> = <K as Key>::Inner;
  type Key (line 17) | pub trait Key: Copy + Eq + Hash + Sized {
    method from_inner (line 20) | fn from_inner(key: Self::Inner) -> Self;
    method into_inner (line 22) | fn into_inner(self) -> Self::Inner;
  type Keyer (line 25) | pub trait Keyer<K>: Clone + Default
    method next (line 29) | fn next(&mut self) -> K::Inner;
  type IncrementalKeyer (line 33) | pub struct IncrementalKeyer {
    method next (line 41) | fn next(&mut self) -> K::Inner {
  type Dispatch (line 49) | pub trait Dispatch<E>
  type Mode (line 58) | pub trait Mode {}
  type Static (line 60) | pub enum Static {}
  type Dynamic (line 64) | pub enum Dynamic {}
  type Enumerate (line 72) | pub trait Enumerate<E>
    method len (line 76) | fn len(&self) -> usize;
    method iter (line 78) | fn iter(&self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ E)>>;
    method iter_mut (line 80) | fn iter_mut(&mut self) -> Box<dyn '_ + Iterator<Item = (E::Key, &'_ mu...
  type Get (line 85) | pub trait Get<E>
    method get (line 89) | fn get(&self, key: &E::Key) -> Option<&E>;
    method get_mut (line 91) | fn get_mut(&mut self, key: &E::Key) -> Option<&mut E>;
    method contains_key (line 93) | fn contains_key(&self, key: &E::Key) -> bool {
  type Insert (line 98) | pub trait Insert<E>
    method insert (line 102) | fn insert(&mut self, entity: E) -> E::Key;
  type InsertWithKey (line 105) | pub trait InsertWithKey<E>
    method insert_with_key (line 109) | fn insert_with_key(&mut self, key: &E::Key, entity: E) -> Option<E>;
  type Remove (line 112) | pub trait Remove<E>
    method remove (line 116) | fn remove(&mut self, key: &E::Key) -> Option<E>;
  type Storage (line 119) | pub trait Storage<E>: AsStorage<E> + AsStorageMut<E> + Enumerate<E> + Ge...
  type DependentStorage (line 132) | pub trait DependentStorage<E>: InsertWithKey<E> + Storage<E>
  type IndependentStorage (line 145) | pub trait IndependentStorage<E>: Insert<E> + Storage<E>
  type Fuse (line 158) | pub trait Fuse<M, T>
    method fuse (line 165) | fn fuse(self, source: M) -> Self::Output;
  type AsStorage (line 173) | pub trait AsStorage<E>
    method as_storage (line 177) | fn as_storage(&self) -> &StorageTarget<E>;
  function as_storage (line 185) | fn as_storage(&self) -> &StorageTarget<E> {
  function as_storage (line 195) | fn as_storage(&self) -> &StorageTarget<E> {
  type AsStorageMut (line 200) | pub trait AsStorageMut<E>: AsStorage<E>
    method as_storage_mut (line 204) | fn as_storage_mut(&mut self) -> &mut StorageTarget<E>;
  function as_storage_mut (line 212) | fn as_storage_mut(&mut self) -> &mut StorageTarget<E> {
  type AsStorageOf (line 217) | pub trait AsStorageOf {
    method as_storage_of (line 218) | fn as_storage_of<E>(&self) -> &StorageTarget<E>
    method as_storage_mut_of (line 226) | fn as_storage_mut_of<E>(&mut self) -> &mut StorageTarget<E>

FILE: plexus/src/entity/traverse.rs
  type Breadth (line 9) | pub enum Breadth {}
    type Buffer (line 57) | type Buffer = VecDeque<T>;
  type Depth (line 10) | pub enum Depth {}
    type Buffer (line 61) | type Buffer = Vec<T>;
  type Buffer (line 12) | pub trait Buffer<R, T>: Default + Extend<T>
    method push (line 16) | fn push(&mut self, item: T);
    method pop (line 17) | fn pop(&mut self) -> Option<T>;
  function push (line 21) | fn push(&mut self, item: T) {
  function pop (line 25) | fn pop(&mut self) -> Option<T> {
  function push (line 31) | fn push(&mut self, item: T) {
  function pop (line 35) | fn pop(&mut self) -> Option<T> {
  type Order (line 52) | pub trait Order<T>: Sized {
  type Adjacency (line 64) | pub trait Adjacency: ClosedView {
    method adjacency (line 67) | fn adjacency(&self) -> Self::Output;
  type Traversal (line 71) | pub struct Traversal<B, T, R = Depth>
  method clone (line 92) | fn clone(&self) -> Self {
  function from (line 109) | fn from(view: T) -> Self {
  type Item (line 129) | type Item = T;
  method next (line 131) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 141) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Trace (line 153) | pub trait Trace<T> {
    method insert (line 166) | fn insert(&mut self, breadcrumb: T) -> bool;
  type TraceFirst (line 179) | pub struct TraceFirst<T>
  function insert (line 190) | fn insert(&mut self, breadcrumb: T) -> bool {
  type TraceAny (line 208) | pub struct TraceAny<T>
  function insert (line 219) | fn insert(&mut self, breadcrumb: T) -> bool {

FILE: plexus/src/entity/view.rs
  type ClosedView (line 8) | pub trait ClosedView {
    method key (line 12) | fn key(&self) -> Self::Key;
    type Key (line 241) | type Key = E::Key;
    type Entity (line 242) | type Entity = E;
    method key (line 244) | fn key(&self) -> Self::Key {
    type Key (line 376) | type Key = E::Key;
    type Entity (line 377) | type Entity = E;
    method key (line 379) | fn key(&self) -> Self::Key {
  type Bind (line 15) | pub trait Bind<B>: ClosedView + Sized
    method bind (line 19) | fn bind(storage: B, key: Self::Key) -> Option<Self>;
  method bind (line 30) | fn bind(storage: B, key: Self::Key) -> Option<Self> {
  type Rebind (line 35) | pub trait Rebind<B, T>: ClosedView
    method rebind (line 40) | fn rebind(self, key: T::Key) -> Option<T>;
  method rebind (line 50) | fn rebind(self, key: T::Key) -> Option<T> {
  type Unbind (line 55) | pub trait Unbind<B>: ClosedView
    method unbind (line 59) | fn unbind(self) -> (B, Self::Key);
  method unbind (line 68) | fn unbind(self) -> (B, Self::Key) {
  type View (line 73) | pub struct View<B, E>
  function bind (line 89) | pub fn bind(storage: B, key: E::Key) -> Option<Self> {
  function bind_unchecked (line 97) | pub fn bind_unchecked(storage: B, key: E::Key) -> Self {
  function bind_into (line 101) | pub fn bind_into<T>(storage: B, key: E::Key) -> Option<T>
  function unbind (line 108) | pub fn unbind(self) -> (B, E::Key) {
  function rebind (line 113) | pub fn rebind<T>(self, key: T::Key) -> Option<View<B, T>>
  function rebind_into (line 122) | pub fn rebind_into<T, U>(self, key: U::Key) -> Option<T>
  function get (line 131) | pub fn get(&self) -> &E::Data
  function key (line 138) | pub fn key(&self) -> E::Key {
  function to_ref (line 142) | pub fn to_ref(&self) -> View<&B::Target, E> {
  function as_entity (line 146) | fn as_entity(&self) -> &E {
  function to_mut_unchecked (line 171) | pub fn to_mut_unchecked(&mut self) -> View<&mut B::Target, E> {
  function get_mut (line 182) | pub fn get_mut(&mut self) -> &mut E::Data
  function as_entity_mut (line 189) | fn as_entity_mut(&mut self) -> &mut E {
  function into_ref (line 204) | pub fn into_ref(self) -> View<&'a B::Target, E> {
  function as_ref (line 216) | fn as_ref(&self) -> &E::Key {
  method clone (line 227) | fn clone(&self) -> Self {
  type Target (line 263) | type Target = E;
  method deref (line 265) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 276) | fn deref_mut(&mut self) -> &mut Self::Target {
  method hash (line 295) | fn hash<H>(&self, state: &mut H)
  method eq (line 309) | fn eq(&self, other: &Self) -> bool {
  type Orphan (line 314) | pub struct Orphan<'a, E>
  function bind (line 327) | pub fn bind<M>(storage: &'a mut M, key: E::Key) -> Option<Self>
  function bind_unchecked (line 335) | pub fn bind_unchecked(data: &'a mut E::Data, key: E::Key) -> Self {
  function bind_into (line 339) | pub fn bind_into<T, M>(storage: &'a mut M, key: E::Key) -> Option<T>
  function get (line 348) | pub fn get(&self) -> &E::Data {
  function get_mut (line 352) | pub fn get_mut(&mut self) -> &mut E::Data {
  function key (line 356) | pub fn key(&self) -> E::Key {
  function as_ref (line 366) | fn as_ref(&self) -> &E::Key {
  function from (line 390) | fn from(view: View<&'a mut M, E>) -> Self {
  method hash (line 412) | fn hash<H>(&self, state: &mut H)
  method eq (line 425) | fn eq(&self, other: &Self) -> bool {

FILE: plexus/src/geometry/mod.rs
  type FromGeometry (line 17) | pub trait FromGeometry<T> {
    method from_geometry (line 18) | fn from_geometry(other: T) -> Self;
  method from_geometry (line 22) | fn from_geometry(other: T) -> Self {
  function from_geometry (line 32) | fn from_geometry(_: T) -> Self {}
  method from_geometry (line 40) | fn from_geometry(_: ()) -> Self {
  type UnitGeometry (line 70) | pub trait UnitGeometry {}
  type IntoGeometry (line 72) | pub trait IntoGeometry<T> {
    method into_geometry (line 73) | fn into_geometry(self) -> T;
  method into_geometry (line 80) | fn into_geometry(self) -> U {
  type Metric (line 85) | pub trait Metric: Eq + One + Ord + Zero {}

FILE: plexus/src/geometry/partition.rs
  type BinaryPartition (line 13) | pub enum BinaryPartition {
  type PointPartition (line 18) | pub trait PointPartition<S>
    method partition (line 22) | fn partition(&self, point: S) -> Option<BinaryPartition>;
  method partition (line 30) | fn partition(&self, point: S) -> Option<BinaryPartition> {
  function partition (line 45) | fn partition(&self, point: S) -> Option<BinaryPartition> {
  function partition (line 72) | fn partition(&self, point: S) -> Option<BinaryPartition> {

FILE: plexus/src/graph/builder.rs
  type GraphBuilder (line 12) | pub struct GraphBuilder<G>
  method default (line 23) | fn default() -> Self {
  type Input (line 34) | type Input = ();
  type Builder (line 41) | type Builder = Self;
  type Vertex (line 43) | type Vertex = G::Vertex;
  type Facet (line 44) | type Facet = G::Face;
  method surface_with (line 46) | fn surface_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
  type Commit (line 59) | type Commit = MeshGraph<G>;
  type Abort (line 60) | type Abort = ();
  type Error (line 61) | type Error = GraphError;
  function commit (line 63) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 68) | fn abort(self) -> Self::Abort {}
  type Builder (line 75) | type Builder = Self;
  type Key (line 76) | type Key = VertexKey;
  type Vertex (line 78) | type Vertex = G::Vertex;
  type Facet (line 79) | type Facet = G::Face;
  method facets_with (line 81) | fn facets_with<F, T, E>(&mut self, f: F) -> Result<T, Self::Error>
  method insert_vertex (line 89) | fn insert_vertex<T>(&mut self, data: T) -> Result<Self::Key, Self::Error>
  type Facet (line 101) | type Facet = G::Face;
  type Key (line 102) | type Key = FaceKey;
  function insert_facet (line 104) | fn insert_facet<T, U>(&mut self, keys: T, data: U) -> Result<Self::Key, ...

FILE: plexus/src/graph/core.rs
  type OwnedCore (line 11) | pub type OwnedCore<G> = Core<
  type Core (line 40) | pub struct Core<G, V = (), A = (), E = (), F = ()>
  function empty (line 55) | pub fn empty() -> Self {
  function unfuse (line 70) | pub fn unfuse(self) -> (V, A, E, F) {
  function as_storage (line 87) | fn as_storage(&self) -> &StorageTarget<Vertex<G>> {
  function as_storage (line 97) | fn as_storage(&self) -> &StorageTarget<Arc<G>> {
  function as_storage (line 107) | fn as_storage(&self) -> &StorageTarget<Edge<G>> {
  function as_storage (line 117) | fn as_storage(&self) -> &StorageTarget<Face<G>> {
  function as_storage_mut (line 127) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Vertex<G>> {
  function as_storage_mut (line 137) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Arc<G>> {
  function as_storage_mut (line 147) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Edge<G>> {
  function as_storage_mut (line 157) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Face<G>> {
  method default (line 170) | fn default() -> Self {
  type Output (line 186) | type Output = Core<G, V, A, E, F>;
  function fuse (line 188) | fn fuse(self, vertices: V) -> Self::Output {
  type Output (line 207) | type Output = Core<G, V, A, E, F>;
  function fuse (line 209) | fn fuse(self, arcs: A) -> Self::Output {
  type Output (line 231) | type Output = Core<G, V, A, E, F>;
  function fuse (line 233) | fn fuse(self, edges: E) -> Self::Output {
  type Output (line 255) | type Output = Core<G, V, A, E, F>;
  function fuse (line 257) | fn fuse(self, faces: F) -> Self::Output {
  type Data (line 278) | type Data = G;

FILE: plexus/src/graph/data.rs
  type Data (line 3) | pub type Data<M> = <M as Parametric>::Data;
  type GraphData (line 66) | pub trait GraphData: Sized {
    type Vertex (line 74) | type Vertex = ();
    type Arc (line 75) | type Arc = ();
    type Edge (line 76) | type Edge = ();
    type Face (line 77) | type Face = ();
    type Vertex (line 84) | type Vertex = Self;
    type Arc (line 85) | type Arc = ();
    type Edge (line 86) | type Edge = ();
    type Face (line 87) | type Face = ();
    type Vertex (line 94) | type Vertex = Self;
    type Arc (line 95) | type Arc = ();
    type Edge (line 96) | type Edge = ();
    type Face (line 97) | type Face = ();
    type Vertex (line 104) | type Vertex = Self;
    type Arc (line 105) | type Arc = ();
    type Edge (line 106) | type Edge = ();
    type Face (line 107) | type Face = ();
    type Vertex (line 114) | type Vertex = Self;
    type Arc (line 115) | type Arc = ();
    type Edge (line 116) | type Edge = ();
    type Face (line 117) | type Face = ();
  type Parametric (line 120) | pub trait Parametric {
    type Data (line 129) | type Data = <B::Target as Parametric>::Data;

FILE: plexus/src/graph/edge.rs
  type Mutation (line 28) | type Mutation<M> = mutation::Mutation<Immediate<M>>;
  type ToArc (line 30) | pub trait ToArc<B>: Sized
    method into_arc (line 35) | fn into_arc(self) -> ArcView<B>;
    method arc (line 37) | fn arc(&self) -> ArcView<&B::Target>;
  type Arc (line 49) | pub struct Arc<G>
  function new (line 70) | pub fn new(data: G::Arc) -> Self {
  type Data (line 93) | type Data = G::Arc;
  method get (line 95) | fn get(&self) -> &Self::Data {
  method get_mut (line 99) | fn get_mut(&mut self) -> &mut Self::Data {
  type ArcKey (line 106) | pub struct ArcKey(VertexKey, VertexKey);
    method into_opposite (line 109) | pub(in crate::graph) fn into_opposite(self) -> ArcKey {
    method from (line 116) | fn from(key: (VertexKey, VertexKey)) -> Self {
  function from (line 122) | fn from(key: ArcKey) -> Self {
  type Inner (line 128) | type Inner = (VertexKey, VertexKey);
  method from_inner (line 130) | fn from_inner(key: Self::Inner) -> Self {
  method into_inner (line 134) | fn into_inner(self) -> Self::Inner {
  type ArcView (line 187) | pub struct ArcView<B>
  function to_ref (line 200) | pub fn to_ref(&self) -> ArcView<&M> {
  function is_boundary_arc (line 207) | pub fn is_boundary_arc(&self) -> bool {
  function to_mut_unchecked (line 221) | pub(in crate::graph) fn to_mut_unchecked(&mut self) -> ArcView<&mut M> {
  function into_ref (line 265) | pub fn into_ref(self) -> ArcView<&'a M> {
  function get (line 276) | pub fn get<'a>(&'a self) -> &'a G::Arc
  function get_mut (line 290) | pub fn get_mut<'a>(&'a mut self) -> &'a mut G::Arc
  function into_reachable_boundary_arc (line 305) | pub(in crate::graph) fn into_reachable_boundary_arc(self) -> Option<Self> {
  function into_reachable_opposite_arc (line 315) | pub(in crate::graph) fn into_reachable_opposite_arc(self) -> Option<Self> {
  function into_reachable_next_arc (line 320) | pub(in crate::graph) fn into_reachable_next_arc(self) -> Option<Self> {
  function into_reachable_previous_arc (line 325) | pub(in crate::graph) fn into_reachable_previous_arc(self) -> Option<Self> {
  function into_ring (line 338) | pub fn into_ring(self) -> Ring<B> {
  function into_boundary_arc (line 343) | pub fn into_boundary_arc(self) -> Option<Self> {
  function into_opposite_arc (line 350) | pub fn into_opposite_arc(self) -> Self {
  function into_next_arc (line 357) | pub fn into_next_arc(self) -> Self {
  function into_previous_arc (line 364) | pub fn into_previous_arc(self) -> Self {
  function ring (line 369) | pub fn ring(&self) -> Ring<&M> {
  function boundary_arc (line 374) | pub fn boundary_arc(&self) -> Option<ArcView<&M>> {
  function opposite_arc (line 379) | pub fn opposite_arc(&self) -> ArcView<&M> {
  function next_arc (line 384) | pub fn next_arc(&self) -> ArcView<&M> {
  function previous_arc (line 389) | pub fn previous_arc(&self) -> ArcView<&M> {
  function into_reachable_source_vertex (line 401) | pub(in crate::graph) fn into_reachable_source_vertex(self) -> Option<Ver...
  function into_reachable_destination_vertex (line 406) | pub(in crate::graph) fn into_reachable_destination_vertex(self) -> Optio...
  function into_path (line 418) | pub fn into_path(self) -> Path<'static, B> {
  function path (line 424) | pub fn path(&self) -> Path<&M> {
  function into_source_vertex (line 429) | pub fn into_source_vertex(self) -> VertexView<B> {
  function into_destination_vertex (line 434) | pub fn into_destination_vertex(self) -> VertexView<B> {
  function source_vertex (line 439) | pub fn source_vertex(&self) -> VertexView<&M> {
  function destination_vertex (line 444) | pub fn destination_vertex(&self) -> VertexView<&M> {
  function into_reachable_edge (line 456) | pub(in crate::graph) fn into_reachable_edge(self) -> Option<EdgeView<B>> {
  function into_edge (line 469) | pub fn into_edge(self) -> EdgeView<B> {
  function edge (line 474) | pub fn edge(&self) -> EdgeView<&M> {
  function into_reachable_face (line 486) | pub(in crate::graph) fn into_reachable_face(self) -> Option<FaceView<B>> {
  function into_face (line 501) | pub fn into_face(self) -> Option<FaceView<B>> {
  function face (line 508) | pub fn face(&self) -> Option<FaceView<&M>> {
  function normal (line 519) | pub fn normal(&self) -> Vector<VertexPosition<G>>
  function midpoint (line 538) | pub fn midpoint(&self) -> VertexPosition<G>
  function into_adjacent_vertices (line 553) | pub fn into_adjacent_vertices(
  function adjacent_vertices (line 567) | pub fn adjacent_vertices(
  function into_adjacent_faces (line 580) | pub fn into_adjacent_faces(self) -> impl Clone + ExactSizeIterator<Item ...
  function adjacent_faces (line 592) | pub fn adjacent_faces(&self) -> impl Clone + ExactSizeIterator<Item = Fa...
  function into_adjacent_vertex_orphans (line 601) | pub fn into_adjacent_vertex_orphans(
  function adjacent_vertex_orphans (line 614) | pub fn adjacent_vertex_orphans(
  function into_adjacent_face_orphans (line 625) | pub fn into_adjacent_face_orphans(
  function adjacent_face_orphans (line 638) | pub fn adjacent_face_orphans(&mut self) -> impl ExactSizeIterator<Item =...
  function split_with (line 690) | pub fn split_with<F>(self, f: F) -> VertexView<&'a mut M>
  function split_at_midpoint (line 746) | pub fn split_at_midpoint(self) -> VertexView<&'a mut M>
  function bridge (line 835) | pub fn bridge(
  function extrude_with_offset (line 900) | pub fn extrude_with_offset<T>(self, offset: T) -> Result<Self, GraphError>
  function extrude_with_translation (line 922) | pub fn extrude_with_translation(
  function extrude_with (line 945) | pub fn extrude_with<F>(self, f: F) -> Result<Self, GraphError>
  function remove (line 966) | pub fn remove(self) -> Option<VertexView<&'a mut M>> {
  function borrow (line 984) | fn borrow(&self) -> &ArcKey {
  method clone (line 996) | fn clone(&self) -> Self {
  type Key (line 1009) | type Key = ArcKey;
  type Entity (line 1010) | type Entity = Arc<G>;
  method key (line 1013) | fn key(&self) -> Self::Key {
  type Target (line 1033) | type Target = Arc<G>;
  method deref (line 1035) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 1046) | fn deref_mut(&mut self) -> &mut Self::Target {
  function from (line 1065) | fn from(ring: Ring<B>) -> Self {
  function from (line 1076) | fn from(view: View<B, Arc<G>>) -> Self {
  function from (line 1087) | fn from(arc: ArcView<B>) -> Self {
  method hash (line 1099) | fn hash<H>(&self, state: &mut H)
  method eq (line 1113) | fn eq(&self, other: &Self) -> bool {
  function into_arc (line 1124) | fn into_arc(self) -> ArcView<B> {
  function arc (line 1128) | fn arc(&self) -> ArcView<&M> {
  type ArcOrphan (line 1134) | pub struct ArcOrphan<'a, G>
  function get (line 1145) | pub fn get(&self) -> &G::Arc {
  function get_mut (line 1149) | pub fn get_mut(&mut self) -> &mut G::Arc {
  function borrow (line 1158) | fn borrow(&self) -> &ArcKey {
  type Key (line 1167) | type Key = ArcKey;
  type Entity (line 1168) | type Entity = Arc<G>;
  method key (line 1170) | fn key(&self) -> Self::Key {
  function from (line 1181) | fn from(arc: ArcView<&'a mut M>) -> Self {
  function from (line 1190) | fn from(inner: Orphan<'a, Arc<G>>) -> Self {
  function from (line 1199) | fn from(view: View<&'a mut M, Arc<M::Data>>) -> Self {
  method hash (line 1208) | fn hash<H>(&self, state: &mut H)
  method eq (line 1220) | fn eq(&self, other: &Self) -> bool {
  type Edge (line 1228) | pub struct Edge<G>
  function new (line 1243) | pub fn new(arc: ArcKey, data: G::Edge) -> Self {
  type Data (line 1260) | type Data = G::Edge;
  method get (line 1262) | fn get(&self) -> &Self::Data {
  method get_mut (line 1266) | fn get_mut(&mut self) -> &mut Self::Data {
  type EdgeKey (line 1273) | pub struct EdgeKey(u64);
  type Inner (line 1276) | type Inner = u64;
  method from_inner (line 1278) | fn from_inner(key: Self::Inner) -> Self {
  method into_inner (line 1282) | fn into_inner(self) -> Self::Inner {
  type EdgeView (line 1295) | pub struct EdgeView<B>
  function to_ref (line 1308) | pub fn to_ref(&self) -> EdgeView<&M> {
  function into_ref (line 1319) | pub fn into_ref(self) -> EdgeView<&'a M> {
  function get (line 1330) | pub fn get<'a>(&'a self) -> &'a G::Edge
  function get_mut (line 1344) | pub fn get_mut<'a>(&'a mut self) -> &'a mut G::Edge
  function into_reachable_arc (line 1359) | pub(in crate::graph) fn into_reachable_arc(self) -> Option<ArcView<B>> {
  function into_arc (line 1371) | pub fn into_arc(self) -> ArcView<B> {
  function arc (line 1375) | pub fn arc(&self) -> ArcView<&M> {
  function is_boundary_edge (line 1379) | pub fn is_boundary_edge(&self) -> bool {
  function midpoint (line 1395) | pub fn midpoint(&self) -> VertexPosition<G>
  function borrow (line 1409) | fn borrow(&self) -> &EdgeKey {
  method clone (line 1421) | fn clone(&self) -> Self {
  type Key (line 1434) | type Key = EdgeKey;
  type Entity (line 1435) | type Entity = Edge<G>;
  method key (line 1438) | fn key(&self) -> Self::Key {
  type Target (line 1458) | type Target = Edge<G>;
  method deref (line 1460) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 1471) | fn deref_mut(&mut self) -> &mut Self::Target {
  function from (line 1490) | fn from(view: View<B, Edge<G>>) -> Self {
  function from (line 1501) | fn from(edge: EdgeView<B>) -> Self {
  method hash (line 1513) | fn hash<H>(&self, state: &mut H)
  method eq (line 1527) | fn eq(&self, other: &Self) -> bool {
  function into_arc (line 1538) | fn into_arc(self) -> ArcView<B> {
  function arc (line 1542) | fn arc(&self) -> ArcView<&M> {
  type EdgeOrphan (line 1548) | pub struct EdgeOrphan<'a, G>
  function get (line 1559) | pub fn get(&self) -> &G::Edge {
  function get_mut (line 1563) | pub fn get_mut(&mut self) -> &mut G::Edge {
  function borrow (line 1572) | fn borrow(&self) -> &EdgeKey {
  type Key (line 1581) | type Key = EdgeKey;
  type Entity (line 1582) | type Entity = Edge<G>;
  method key (line 1584) | fn key(&self) -> Self::Key {
  function from (line 1595) | fn from(edge: EdgeView<&'a mut M>) -> Self {
  function from (line 1604) | fn from(inner: Orphan<'a, Edge<G>>) -> Self {
  function from (line 1613) | fn from(view: View<&'a mut M, Edge<M::Data>>) -> Self {
  method hash (line 1622) | fn hash<H>(&self, state: &mut H)
  method eq (line 1634) | fn eq(&self, other: &Self) -> bool {
  type VertexCirculator (line 1639) | pub struct VertexCirculator<B>
  type Entity (line 1654) | type Entity = Vertex<G>;
    type Key (line 85) | type Key = ArcKey;
    type Storage (line 86) | type Storage = HashStorage<Self>;
    type Key (line 1252) | type Key = EdgeKey;
    type Storage (line 1253) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 1656) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  function from (line 1667) | fn from(arc: ArcView<B>) -> Self {
  method clone (line 1683) | fn clone(&self) -> Self {
  type Item (line 1705) | type Item = VertexView<&'a M>;
  method next (line 1707) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1711) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Item (line 1720) | type Item = VertexOrphan<'a, M::Data>;
  method next (line 1722) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1726) | fn size_hint(&self) -> (usize, Option<usize>) {
  function target (line 1735) | fn target(&mut self) -> &mut M {
  function target (line 1744) | fn target(&self) -> &'a M {
  type FaceCirculator (line 1749) | pub struct FaceCirculator<B>
  type Entity (line 1764) | type Entity = Face<G>;
    type Key (line 85) | type Key = ArcKey;
    type Storage (line 86) | type Storage = HashStorage<Self>;
    type Key (line 1252) | type Key = EdgeKey;
    type Storage (line 1253) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 1766) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 1777) | fn clone(&self) -> Self {
  function from (line 1800) | fn from(arc: ArcView<B>) -> Self {
  type Item (line 1821) | type Item = FaceView<&'a M>;
  method next (line 1823) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1827) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Item (line 1836) | type Item = FaceOrphan<'a, M::Data>;
  method next (line 1838) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1842) | fn size_hint(&self) -> (usize, Option<usize>) {
  function target (line 1851) | fn target(&mut self) -> &mut M {
  function target (line 1860) | fn target(&self) -> &'a M {
  type E2 (line 1878) | type E2 = Point2<R64>;
  type E3 (line 1879) | type E3 = Point3<R64>;
  function find_arc (line 1881) | fn find_arc<G, T>(graph: &MeshGraph<G>, data: (T, T)) -> Option<ArcKey>
  function extrude_arc (line 1903) | fn extrude_arc() {
  function bridge_arcs (line 1922) | fn bridge_arcs() {
  function split_edge (line 1948) | fn split_edge() {
  function remove_edge (line 1969) | fn remove_edge() {

FILE: plexus/src/graph/face.rs
  type Mutation (line 38) | type Mutation<M> = mutation::Mutation<Immediate<M>>;
  type ToRing (line 40) | pub trait ToRing<B>: DynamicArity<Dynamic = usize> + Sized
    method into_ring (line 45) | fn into_ring(self) -> Ring<B>;
    method ring (line 47) | fn ring(&self) -> Ring<&B::Target>;
  type Face (line 53) | pub struct Face<G>
  function new (line 68) | pub fn new(arc: ArcKey, data: G::Face) -> Self {
  type Data (line 85) | type Data = G::Face;
  method get (line 87) | fn get(&self) -> &Self::Data {
  method get_mut (line 91) | fn get_mut(&mut self) -> &mut Self::Data {
  type FaceKey (line 98) | pub struct FaceKey(u64);
  type Inner (line 101) | type Inner = u64;
  method from_inner (line 103) | fn from_inner(key: Self::Inner) -> Self {
  method into_inner (line 107) | fn into_inner(self) -> Self::Inner {
  type FaceView (line 124) | pub struct FaceView<B>
  function to_ref (line 137) | pub fn to_ref(&self) -> FaceView<&M> {
  function to_mut_unchecked (line 150) | fn to_mut_unchecked(&mut self) -> FaceView<&mut M> {
  function into_ref (line 191) | pub fn into_ref(self) -> FaceView<&'a M> {
  function get (line 202) | pub fn get<'a>(&'a self) -> &'a G::Face
  function get_mut (line 216) | pub fn get_mut<'a>(&'a mut self) -> &'a mut G::Face
  function into_reachable_arc (line 231) | pub(in crate::graph) fn into_reachable_arc(self) -> Option<ArcView<B>> {
  function into_ring (line 244) | pub fn into_ring(self) -> Ring<B> {
  function into_arc (line 249) | pub fn into_arc(self) -> ArcView<B> {
  function ring (line 254) | pub fn ring(&self) -> Ring<&M> {
  function arc (line 259) | pub fn arc(&self) -> ArcView<&M> {
  function centroid (line 274) | pub fn centroid(&self) -> VertexPosition<G>
  function normal (line 282) | pub fn normal(&self) -> Result<Vector<VertexPosition<G>>, GraphError>
  function plane (line 290) | pub fn plane(&self) -> Result<Plane<VertexPosition<G>>, GraphError>
  function flatten (line 317) | pub fn flatten(&mut self) -> Result<(), GraphError>
  function into_adjacent_arcs (line 351) | pub fn into_adjacent_arcs(self) -> impl Clone + Iterator<Item = ArcView<...
  function into_adjacent_faces (line 355) | pub fn into_adjacent_faces(self) -> impl Clone + Iterator<Item = FaceVie...
  function adjacent_arcs (line 367) | pub fn adjacent_arcs(&self) -> impl Clone + Iterator<Item = ArcView<&B::...
  function adjacent_faces (line 372) | pub fn adjacent_faces(&self) -> impl Clone + Iterator<Item = FaceView<&B...
  function into_adjacent_vertices (line 388) | pub fn into_adjacent_vertices(self) -> impl Clone + Iterator<Item = Vert...
  function adjacent_vertices (line 404) | pub fn adjacent_vertices(&self) -> impl Clone + Iterator<Item = VertexVi...
  function into_adjacent_arc_orphans (line 413) | pub fn into_adjacent_arc_orphans(self) -> impl Iterator<Item = ArcOrphan...
  function adjacent_arc_orphans (line 424) | pub fn adjacent_arc_orphans(&mut self) -> impl Iterator<Item = ArcOrphan...
  function into_adjacent_face_orphans (line 433) | pub fn into_adjacent_face_orphans(self) -> impl Iterator<Item = FaceOrph...
  function adjacent_face_orphans (line 444) | pub fn adjacent_face_orphans(&mut self) -> impl Iterator<Item = FaceOrph...
  function into_adjacent_vertex_orphans (line 457) | pub fn into_adjacent_vertex_orphans(self) -> impl Iterator<Item = Vertex...
  function adjacent_vertex_orphans (line 472) | pub fn adjacent_vertex_orphans(&mut self) -> impl Iterator<Item = Vertex...
  function traverse_by_breadth (line 488) | pub fn traverse_by_breadth(&self) -> impl Clone + Iterator<Item = FaceVi...
  function traverse_by_depth (line 497) | pub fn traverse_by_depth(&self) -> impl Clone + Iterator<Item = FaceView...
  function split (line 556) | pub fn split(
  function merge (line 624) | pub fn merge(self, destination: impl Into<Selector<FaceKey>>) -> Result<...
  function bridge (line 663) | pub fn bridge(self, destination: FaceKey) -> Result<(), GraphError> {
  function triangulate (line 680) | pub fn triangulate(self) -> Self {
  function poke_with (line 732) | pub fn poke_with<F>(self, f: F) -> VertexView<&'a mut M>
  function poke_at_centroid (line 750) | pub fn poke_at_centroid(self) -> VertexView<&'a mut M>
  function poke_with_offset (line 802) | pub fn poke_with_offset<T>(self, offset: T) -> Result<VertexView<&'a mut...
  function extrude_with_offset (line 824) | pub fn extrude_with_offset<T>(self, offset: T) -> Result<Self, GraphError>
  function extrude_with_translation (line 841) | pub fn extrude_with_translation(self, translation: Vector<VertexPosition...
  function extrude_with (line 858) | pub fn extrude_with<F>(self, f: F) -> Self
  function remove (line 875) | pub fn remove(self) -> Option<Ring<&'a mut M>> {
  type Output (line 894) | type Output = SmallVec<[Self::Key; 8]>;
  method adjacency (line 896) | fn adjacency(&self) -> Self::Output {
  function borrow (line 906) | fn borrow(&self) -> &FaceKey {
  method clone (line 918) | fn clone(&self) -> Self {
  type Key (line 931) | type Key = FaceKey;
  type Entity (line 932) | type Entity = Face<G>;
  method key (line 935) | fn key(&self) -> Self::Key {
  type Target (line 955) | type Target = Face<G>;
  method deref (line 957) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 968) | fn deref_mut(&mut self) -> &mut Self::Target {
  type Dynamic (line 979) | type Dynamic = usize;
  method arity (line 983) | fn arity(&self) -> Self::Dynamic {
  function from (line 1002) | fn from(view: View<B, Face<G>>) -> Self {
  function from (line 1013) | fn from(face: FaceView<B>) -> Self {
  method hash (line 1025) | fn hash<H>(&self, state: &mut H)
  method eq (line 1039) | fn eq(&self, other: &Self) -> bool {
  type Static (line 1050) | type Static = <MeshGraph<G> as StaticArity>::Static;
  constant ARITY (line 1052) | const ARITY: Self::Static = MeshGraph::<G>::ARITY;
  function into_ring (line 1061) | fn into_ring(self) -> Ring<B> {
  function ring (line 1065) | fn ring(&self) -> Ring<&M> {
  type FaceOrphan (line 1071) | pub struct FaceOrphan<'a, G>
  function get (line 1082) | pub fn get(&self) -> &G::Face {
  function get_mut (line 1086) | pub fn get_mut(&mut self) -> &mut G::Face {
  type Key (line 1095) | type Key = FaceKey;
  type Entity (line 1096) | type Entity = Face<G>;
  method key (line 1098) | fn key(&self) -> Self::Key {
  function from (line 1109) | fn from(face: FaceView<&'a mut M>) -> Self {
  function from (line 1118) | fn from(inner: Orphan<'a, Face<G>>) -> Self {
  function from (line 1127) | fn from(view: View<&'a mut M, Face<M::Data>>) -> Self {
  method eq (line 1136) | fn eq(&self, other: &Self) -> bool {
  type Ring (line 1151) | pub struct Ring<B>
  function to_ref (line 1165) | pub fn to_ref(&self) -> Ring<&M> {
  function to_mut_unchecked (line 1179) | fn to_mut_unchecked(&mut self) -> Ring<&mut M> {
  function into_ref (line 1190) | pub fn into_ref(self) -> Ring<&'a M> {
  function into_arc (line 1202) | pub fn into_arc(self) -> ArcView<B> {
  function arc (line 1207) | pub fn arc(&self) -> ArcView<&M> {
  function into_path (line 1218) | pub fn into_path(self) -> Path<'static, B> {
  function path (line 1222) | pub fn path(&self) -> Path<'static, &M> {
  function shortest_logical_metric (line 1233) | pub fn shortest_logical_metric(
  function into_face (line 1272) | pub fn into_face(self) -> Option<FaceView<B>> {
  function face (line 1281) | pub fn face(&self) -> Option<FaceView<&M>> {
  function into_arcs (line 1292) | pub fn into_arcs(self) -> impl Clone + Iterator<Item = ArcView<&'a M>> {
  function arcs (line 1304) | pub fn arcs(&self) -> impl Clone + Iterator<Item = ArcView<&B::Target>> {
  function into_vertices (line 1315) | pub fn into_vertices(self) -> impl Clone + Iterator<Item = VertexView<&'...
  function vertices (line 1327) | pub fn vertices(&self) -> impl Clone + Iterator<Item = VertexView<&B::Ta...
  function into_arc_orphans (line 1336) | pub fn into_arc_orphans(self) -> impl Iterator<Item = ArcOrphan<'a, M::D...
  function arc_orphans (line 1347) | pub fn arc_orphans(&mut self) -> impl Iterator<Item = ArcOrphan<Data<B>>> {
  function into_vertex_orphans (line 1356) | pub fn into_vertex_orphans(self) -> impl Iterator<Item = VertexOrphan<'a...
  function vertex_orphans (line 1367) | pub fn vertex_orphans(&mut self) -> impl Iterator<Item = VertexOrphan<Da...
  function get_or_insert_face (line 1381) | pub fn get_or_insert_face(self) -> FaceView<&'a mut M> {
  function get_or_insert_face_with (line 1392) | pub fn get_or_insert_face_with<F>(self, f: F) -> FaceView<&'a mut M>
  type Dynamic (line 1421) | type Dynamic = usize;
  method arity (line 1425) | fn arity(&self) -> Self::Dynamic {
  function from (line 1436) | fn from(arc: ArcView<B>) -> Self {
  method eq (line 1447) | fn eq(&self, other: &Self) -> bool {
  type Static (line 1459) | type Static = <MeshGraph<G> as StaticArity>::Static;
  constant ARITY (line 1461) | const ARITY: Self::Static = MeshGraph::<G>::ARITY;
  function into_ring (line 1470) | fn into_ring(self) -> Ring<B> {
  function ring (line 1474) | fn ring(&self) -> Ring<&M> {
  type VertexCirculator (line 1479) | pub struct VertexCirculator<B>
  type Entity (line 1493) | type Entity = Vertex<G>;
    type Key (line 77) | type Key = FaceKey;
    type Storage (line 78) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 1495) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 1510) | fn clone(&self) -> Self {
  function from (line 1523) | fn from(inner: ArcCirculator<B>) -> Self {
  type Item (line 1533) | type Item = VertexView<&'a M>;
  method next (line 1535) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1539) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Item (line 1550) | type Item = VertexOrphan<'a, M::Data>;
  method next (line 1552) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1556) | fn size_hint(&self) -> (usize, Option<usize>) {
  function target (line 1567) | fn target(&mut self) -> &mut M {
  function target (line 1576) | fn target(&self) -> &'a M {
  type ArcCirculator (line 1581) | pub struct ArcCirculator<B>
  type Entity (line 1597) | type Entity = Arc<G>;
    type Key (line 77) | type Key = FaceKey;
    type Storage (line 78) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 1599) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 1619) | fn clone(&self) -> Self {
  function from (line 1634) | fn from(ring: Ring<B>) -> Self {
  type Item (line 1649) | type Item = ArcView<&'a M>;
  method next (line 1651) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1655) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Item (line 1666) | type Item = ArcOrphan<'a, M::Data>;
  method next (line 1668) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 1672) | fn size_hint(&self) -> (usize, Option<usize>) {
  function target (line 1683) | fn target(&mut self) -> &mut M {
  function target (line 1693) | fn target(&self) -> &'a M {
  type FaceCirculator (line 1698) | pub struct FaceCirculator<B>
  type Entity (line 1712) | type Entity = Face<G>;
    type Key (line 77) | type Key = FaceKey;
    type Storage (line 78) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 1714) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 1742) | fn clone(&self) -> Self {
  function from (line 1755) | fn from(inner: ArcCirculator<B>) -> Self {
  type Item (line 1765) | type Item = FaceView<&'a M>;
  method next (line 1767) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 1776) | type Item = FaceOrphan<'a, M::Data>;
  method next (line 1778) | fn next(&mut self) -> Option<Self::Item> {
  function target (line 1787) | fn target(&mut self) -> &mut M {
  function target (line 1797) | fn target(&self) -> &'a M {
  type E2 (line 1815) | type E2 = Point2<R64>;
  type E3 (line 1816) | type E3 = Point3<R64>;
  function circulate_over_arcs (line 1819) | fn circulate_over_arcs() {
  function circulate_over_faces (line 1830) | fn circulate_over_faces() {
  function remove_face (line 1842) | fn remove_face() {
  function split_face (line 1865) | fn split_face() {
  function extrude_face (line 1888) | fn extrude_face() {
  function merge_faces (line 1920) | fn merge_faces() {
  function poke_face (line 1950) | fn poke_face() {
  function triangulate_mesh (line 1972) | fn triangulate_mesh() {
  function logical_metrics (line 1988) | fn logical_metrics() {

FILE: plexus/src/graph/geometry.rs
  type VertexPosition (line 26) | pub type VertexPosition<G> = Position<<G as GraphData>::Vertex>;
  type VertexCentroid (line 28) | pub trait VertexCentroid: GraphData
    method centroid (line 32) | fn centroid<B>(vertex: VertexView<B>) -> Result<VertexPosition<Self>, ...
    method centroid (line 44) | fn centroid<B>(vertex: VertexView<B>) -> Result<VertexPosition<Self>, ...
  type VertexNormal (line 59) | pub trait VertexNormal: FaceNormal
    method normal (line 63) | fn normal<B>(vertex: VertexView<B>) -> Result<Vector<VertexPosition<Se...
    method normal (line 78) | fn normal<B>(vertex: VertexView<B>) -> Result<Vector<VertexPosition<Se...
  type ArcNormal (line 99) | pub trait ArcNormal: GraphData
    method normal (line 103) | fn normal<B>(arc: ArcView<B>) -> Result<Vector<VertexPosition<Self>>, ...
    method normal (line 117) | fn normal<B>(arc: ArcView<B>) -> Result<Vector<VertexPosition<Self>>, ...
  type EdgeMidpoint (line 136) | pub trait EdgeMidpoint: GraphData
    method midpoint (line 140) | fn midpoint<B, T>(edge: T) -> Result<VertexPosition<Self>, GraphError>
    method midpoint (line 157) | fn midpoint<B, T>(edge: T) -> Result<VertexPosition<Self>, GraphError>
  type FaceCentroid (line 177) | pub trait FaceCentroid: GraphData
    method centroid (line 181) | fn centroid<B, T>(ring: T) -> Result<VertexPosition<Self>, GraphError>
    method centroid (line 194) | fn centroid<B, T>(ring: T) -> Result<VertexPosition<Self>, GraphError>
  type FaceNormal (line 209) | pub trait FaceNormal: GraphData
    method normal (line 213) | fn normal<B, T>(ring: T) -> Result<Vector<VertexPosition<Self>>, Graph...
    method normal (line 228) | fn normal<B, T>(ring: T) -> Result<Vector<VertexPosition<Self>>, Graph...
  type FacePlane (line 249) | pub trait FacePlane: GraphData
    method plane (line 254) | fn plane<B, T>(ring: T) -> Result<Plane<VertexPosition<Self>>, GraphEr...

FILE: plexus/src/graph/mod.rs
  type Mutation (line 315) | type Mutation<M> = mutation::Mutation<Immediate<M>>;
  type GraphError (line 321) | pub enum GraphError {
    method from (line 360) | fn from(error: BufferError) -> Self {
    method from (line 371) | fn from(error: EntityError) -> Self {
  type OptionExt (line 379) | trait OptionExt<T> {
    method expect_consistent (line 380) | fn expect_consistent(self) -> T;
  function expect_consistent (line 384) | fn expect_consistent(self) -> T {
  type ResultExt (line 389) | trait ResultExt<T, E> {
    method expect_consistent (line 390) | fn expect_consistent(self) -> T
  function expect_consistent (line 396) | fn expect_consistent(self) -> T
  type Circulator (line 404) | trait Circulator<B>
    method next (line 411) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key>;
  type ViewCirculator (line 414) | trait ViewCirculator<'a, M>: Circulator<&'a M>
    method target (line 418) | fn target(&self) -> &'a M;
    method bind_next_view (line 420) | fn bind_next_view<T>(&mut self) -> Option<T>
  type OrphanCirculator (line 429) | trait OrphanCirculator<'a, M>: Circulator<&'a mut M>
    method target (line 433) | fn target(&mut self) -> &mut M;
    method bind_next_orphan (line 455) | unsafe fn bind_next_orphan<T>(&mut self) -> Option<T>
  type Selector (line 514) | pub enum Selector<K> {
  function key_or_else (line 522) | pub fn key_or_else<E, F>(self, f: F) -> Result<K, GraphError>
  function index_or_else (line 535) | pub fn index_or_else<E, F>(self, f: F) -> Result<usize, GraphError>
  function from (line 551) | fn from(key: K) -> Self {
  function from (line 557) | fn from(index: usize) -> Self {
  type GraphKey (line 563) | pub enum GraphKey {
    method from (line 571) | fn from(key: VertexKey) -> Self {
    method from (line 577) | fn from(key: ArcKey) -> Self {
    method from (line 583) | fn from(key: EdgeKey) -> Self {
    method from (line 589) | fn from(key: FaceKey) -> Self {
  type MeshGraph (line 613) | pub struct MeshGraph<G = (R64, R64, R64)>
  function new (line 633) | pub fn new() -> Self {
  function vertex_count (line 638) | pub fn vertex_count(&self) -> usize {
  function vertex (line 643) | pub fn vertex(&self, key: VertexKey) -> Option<VertexView<&Self>> {
  function vertex_mut (line 648) | pub fn vertex_mut(&mut self, key: VertexKey) -> Option<VertexView<&mut S...
  function vertices (line 654) | pub fn vertices(&self) -> impl Iterator<Item = VertexView<&Self>> {
  function vertex_orphans (line 664) | pub fn vertex_orphans(&mut self) -> impl Iterator<Item = VertexOrphan<G>> {
  function arc_count (line 673) | pub fn arc_count(&self) -> usize {
  function arc (line 678) | pub fn arc(&self, key: ArcKey) -> Option<ArcView<&Self>> {
  function arc_mut (line 683) | pub fn arc_mut(&mut self, key: ArcKey) -> Option<ArcView<&mut Self>> {
  function arcs (line 689) | pub fn arcs(&self) -> impl Iterator<Item = ArcView<&Self>> {
  function arc_orphans (line 699) | pub fn arc_orphans(&mut self) -> impl Iterator<Item = ArcOrphan<G>> {
  function edge_count (line 708) | pub fn edge_count(&self) -> usize {
  function edge (line 713) | pub fn edge(&self, key: EdgeKey) -> Option<EdgeView<&Self>> {
  function edge_mut (line 718) | pub fn edge_mut(&mut self, key: EdgeKey) -> Option<EdgeView<&mut Self>> {
  function edges (line 724) | pub fn edges(&self) -> impl Iterator<Item = EdgeView<&Self>> {
  function edge_orphans (line 734) | pub fn edge_orphans(&mut self) -> impl Iterator<Item = EdgeOrphan<G>> {
  function face_count (line 743) | pub fn face_count(&self) -> usize {
  function face (line 748) | pub fn face(&self, key: FaceKey) -> Option<FaceView<&Self>> {
  function face_mut (line 753) | pub fn face_mut(&mut self, key: FaceKey) -> Option<FaceView<&mut Self>> {
  function faces (line 759) | pub fn faces(&self) -> impl Iterator<Item = FaceView<&Self>> {
  function face_orphans (line 769) | pub fn face_orphans(&mut self) -> impl Iterator<Item = FaceOrphan<G>> {
  function path (line 782) | pub fn path<I>(&self, keys: I) -> Result<Path<'static, &Self>, GraphError>
  function path_mut (line 795) | pub fn path_mut<I>(&mut self, keys: I) -> Result<Path<'static, &mut Self...
  function aabb (line 804) | pub fn aabb(&self) -> Aabb<VertexPosition<G>>
  function triangulate (line 820) | pub fn triangulate(&mut self) {
  function smooth (line 865) | pub fn smooth<T>(&mut self, factor: T)
  function split_at_path (line 924) | pub fn split_at_path(path: Path<&mut Self>) -> Result<(), GraphError> {
  function disjoint_subgraph_vertices (line 967) | pub fn disjoint_subgraph_vertices(&self) -> impl ExactSizeIterator<Item ...
  function into_disjoint_subgraphs (line 985) | pub fn into_disjoint_subgraphs(self) -> Vec<Self> {
  function shrink_to_fit (line 991) | pub fn shrink_to_fit(&mut self) {
  function to_mesh_by_vertex (line 1042) | pub fn to_mesh_by_vertex<B>(&self) -> Result<B, B::Error>
  function to_mesh_by_vertex_with (line 1063) | pub fn to_mesh_by_vertex_with<B, F>(&self, mut f: F) -> Result<B, B::Error>
  function to_mesh_by_face (line 1103) | pub fn to_mesh_by_face<B>(&self) -> Result<B, B::Error>
  function to_mesh_by_face_with (line 1166) | pub fn to_mesh_by_face_with<B, F>(&self, mut f: F) -> Result<B, B::Error>
  function as_storage (line 1193) | fn as_storage(&self) -> &StorageTarget<Vertex<G>> {
  function as_storage (line 1202) | fn as_storage(&self) -> &StorageTarget<Arc<G>> {
  function as_storage (line 1211) | fn as_storage(&self) -> &StorageTarget<Edge<G>> {
  function as_storage (line 1220) | fn as_storage(&self) -> &StorageTarget<Face<G>> {
  function as_storage_mut (line 1229) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Vertex<G>> {
  function as_storage_mut (line 1238) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Arc<G>> {
  function as_storage_mut (line 1247) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Edge<G>> {
  function as_storage_mut (line 1256) | fn as_storage_mut(&mut self) -> &mut StorageTarget<Face<G>> {
  type Builder (line 1298) | type Builder = GraphBuilder<G>;
  type Error (line 1299) | type Error = GraphError;
  type Vertex (line 1301) | type Vertex = G::Vertex;
  type Facet (line 1302) | type Facet = G::Face;
  method builder (line 1304) | fn builder() -> Self::Builder {
  method default (line 1315) | fn default() -> Self {
  type Dynamic (line 1324) | type Dynamic = MeshArity;
  method arity (line 1326) | fn arity(&self) -> Self::Dynamic {
  function from (line 1337) | fn from(polygon: P) -> Self {
  function from (line 1348) | fn from(core: OwnedCore<G>) -> Self {
  function from (line 1357) | fn from(graph: MeshGraph<G>) -> Self {
  type Error (line 1370) | type Error = GraphError;
  function from_encoding (line 1372) | fn from_encoding(
  type Error (line 1402) | type Error = GraphError;
  function from_indexer (line 1404) | fn from_indexer<I, N>(input: I, indexer: N) -> Result<Self, Self::Error>
  function from_iter (line 1436) | fn from_iter<I>(input: I) -> Self
  type Error (line 1451) | type Error = GraphError;
  function from_raw_buffers (line 1453) | fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Self:...
  type Error (line 1482) | type Error = GraphError;
  function from_raw_buffers_with_arity (line 1517) | fn from_raw_buffers_with_arity<I, J>(
  type Output (line 1564) | type Output = vec::IntoIter<Self::Polygon>;
  type Polygon (line 1565) | type Polygon = UnboundedPolygon<G::Vertex>;
  method into_polygons (line 1567) | fn into_polygons(self) -> Self::Output {
  type Data (line 1588) | type Data = G;
  type Static (line 1595) | type Static = (usize, Option<usize>);
  constant ARITY (line 1597) | const ARITY: Self::Static = (3, None);
  type Error (line 1609) | type Error = GraphError;
  function try_from (line 1644) | fn try_from(buffer: MeshBuffer<Flat<T, A>, H>) -> Result<Self, Self::Err...
  type Error (line 1659) | type Error = GraphError;
  function try_from (line 1693) | fn try_from(buffer: MeshBuffer<P, H>) -> Result<Self, Self::Error> {
  type E2 (line 1712) | type E2 = Point2<R64>;
  type E3 (line 1713) | type E3 = Point3<R64>;
  function collect (line 1716) | fn collect() {
  function iterate (line 1727) | fn iterate() {
  function isolate_disjoint_subgraphs (line 1747) | fn isolate_disjoint_subgraphs() {
  function non_manifold_error_deferred (line 1777) | fn non_manifold_error_deferred() {
  function error_on_non_manifold (line 1788) | fn error_on_non_manifold() {
  function read_write_mutable_circulator (line 1804) | fn read_write_mutable_circulator() {

FILE: plexus/src/graph/mutation/edge.rs
  type CompositeEdge (line 19) | pub type CompositeEdge<G> = (Edge<G>, (Arc<G>, Arc<G>));
  type CompositeEdgeData (line 20) | pub type CompositeEdgeData<G> = (
  type CompositeEdgeKey (line 24) | pub type CompositeEdgeKey = (EdgeKey, (ArcKey, ArcKey));
  type ModalCore (line 26) | type ModalCore<P> = Core<
  type RefCore (line 33) | type RefCore<'a, G> = Core<
  type EdgeMutation (line 41) | pub struct EdgeMutation<P>
  function to_ref_core (line 54) | pub fn to_ref_core(&self) -> RefCore<Data<P::Graph>> {
  function connect_adjacent_arcs (line 61) | pub fn connect_adjacent_arcs(&mut self, ab: ArcKey, bc: ArcKey) -> Resul...
  function disconnect_next_arc (line 67) | pub fn disconnect_next_arc(&mut self, ab: ArcKey) -> Result<Option<ArcKe...
  function disconnect_previous_arc (line 76) | pub fn disconnect_previous_arc(&mut self, ab: ArcKey) -> Result<Option<A...
  function connect_arc_to_edge (line 85) | pub fn connect_arc_to_edge(&mut self, ab: ArcKey, ab_ba: EdgeKey) -> Res...
  function connect_arc_to_face (line 89) | pub fn connect_arc_to_face(&mut self, ab: ArcKey, abc: FaceKey) -> Resul...
  function disconnect_arc_from_face (line 93) | pub fn disconnect_arc_from_face(&mut self, ab: ArcKey) -> Result<Option<...
  function with_arc_mut (line 97) | fn with_arc_mut<T, F>(&mut self, ab: ArcKey, mut f: F) -> Result<T, Grap...
  function as_storage (line 115) | fn as_storage(&self) -> &StorageTarget<Arc<Data<P::Graph>>> {
  function as_storage (line 124) | fn as_storage(&self) -> &StorageTarget<Edge<Data<P::Graph>>> {
  function bypass (line 133) | fn bypass(self) -> Self::Commit {
  type Target (line 148) | type Target = VertexMutation<P>;
  method deref (line 150) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 159) | fn deref_mut(&mut self) -> &mut Self::Target {
  function from (line 168) | fn from(core: ModalCore<P>) -> Self {
  type Commit (line 181) | type Commit = ModalCore<Immediate<M>>;
  type Abort (line 182) | type Abort = ();
  type Error (line 183) | type Error = GraphError;
  function commit (line 185) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 201) | fn abort(self) -> Self::Abort {}
  type ArcRemoveCache (line 204) | struct ArcRemoveCache {
    method from_arc (line 212) | pub fn from_arc<B>(arc: ArcView<B>) -> Result<Self, GraphError>
  type EdgeRemoveCache (line 244) | pub struct EdgeRemoveCache {
    method from_arc (line 253) | pub fn from_arc<B>(arc: ArcView<B>) -> Result<Self, GraphError>
  type EdgeSplitCache (line 276) | pub struct EdgeSplitCache {
    method from_arc (line 285) | pub fn from_arc<B>(arc: ArcView<B>) -> Result<Self, GraphError>
  type ArcBridgeCache (line 319) | pub struct ArcBridgeCache {
    method from_arc (line 327) | pub fn from_arc<B>(arc: ArcView<B>, destination: ArcKey) -> Result<Sel...
    method from_storage (line 370) | pub fn from_storage<B>(
  type ArcExtrudeCache (line 386) | pub struct ArcExtrudeCache {
    method from_arc (line 391) | pub fn from_arc<B>(arc: ArcView<B>) -> Result<Self, GraphError>
  function get_or_insert_with (line 409) | pub fn get_or_insert_with<N, P, F>(
  function remove (line 475) | pub fn remove<N, P>(
  function split_with (line 543) | pub fn split_with<N, P, F>(
  function bridge (line 648) | pub fn bridge<N, P>(mut mutation: N, cache: ArcBridgeCache) -> Result<Fa...
  function extrude_with (line 661) | pub fn extrude_with<N, P, F>(

FILE: plexus/src/graph/mutation/face.rs
  type ModalCore (line 21) | type ModalCore<P> = Core<
  type RefCore (line 28) | pub type RefCore<'a, G> = Core<
  type FaceMutation (line 36) | pub struct FaceMutation<P>
  function to_ref_core (line 48) | pub fn to_ref_core(&self) -> RefCore<Data<P::Graph>> {
  function connect_face_to_arc (line 54) | pub fn connect_face_to_arc(&mut self, ab: ArcKey, abc: FaceKey) -> Resul...
  function connect_face_interior (line 58) | fn connect_face_interior(&mut self, arcs: &[ArcKey], face: FaceKey) -> R...
  function disconnect_face_interior (line 66) | fn disconnect_face_interior(&mut self, arcs: &[ArcKey]) -> Result<(), Gr...
  function connect_face_exterior (line 73) | fn connect_face_exterior(
  function with_face_mut (line 131) | fn with_face_mut<T, F>(&mut self, abc: FaceKey, mut f: F) -> Result<T, G...
  function as_storage (line 148) | fn as_storage(&self) -> &StorageTarget<Face<Data<P::Graph>>> {
  function bypass (line 157) | fn bypass(self) -> Self::Commit {
  type Target (line 172) | type Target = EdgeMutation<P>;
  method deref (line 174) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 183) | fn deref_mut(&mut self) -> &mut Self::Target {
  function from (line 192) | fn from(core: ModalCore<P>) -> Self {
  type Commit (line 205) | type Commit = ModalCore<Immediate<M>>;
  type Abort (line 206) | type Abort = ();
  type Error (line 207) | type Error = GraphError;
  function commit (line 210) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 219) | fn abort(self) -> Self::Abort {}
  type FaceInsertCache (line 222) | pub struct FaceInsertCache {
    method from_ring (line 231) | pub fn from_ring<B, T>(ring: T) -> Result<Self, GraphError>
    method from_storage (line 246) | pub fn from_storage<B, K>(storage: B, perimeter: K) -> Result<Self, Gr...
  type FaceRemoveCache (line 317) | pub struct FaceRemoveCache {
    method from_face (line 324) | pub fn from_face<B>(face: FaceView<B>) -> Result<Self, GraphError>
  type FaceSplitCache (line 341) | pub struct FaceSplitCache {
    method from_face (line 348) | pub fn from_face<B>(
  type FacePokeCache (line 420) | pub struct FacePokeCache {
    method from_face (line 426) | pub fn from_face<B>(face: FaceView<B>) -> Result<Self, GraphError>
  type FaceBridgeCache (line 443) | pub struct FaceBridgeCache {
    method from_face (line 450) | pub fn from_face<B>(face: FaceView<B>, destination: FaceKey) -> Result...
  type FaceExtrudeCache (line 479) | pub struct FaceExtrudeCache {
    method from_face (line 485) | pub fn from_face<B>(face: FaceView<B>) -> Result<Self, GraphError>
  function insert_with (line 501) | pub fn insert_with<N, P, F>(
  function remove (line 548) | pub fn remove<N, P>(
  function split (line 568) | pub fn split<N, P>(mut mutation: N, cache: FaceSplitCache) -> Result<Arc...
  function poke_with (line 584) | pub fn poke_with<N, P, F>(
  function bridge (line 607) | pub fn bridge<N, P>(mut mutation: N, cache: FaceBridgeCache) -> Result<(...
  function extrude_with (line 633) | pub fn extrude_with<N, P, F>(

FILE: plexus/src/graph/mutation/mod.rs
  type Consistent (line 44) | pub trait Consistent {}
  type Mode (line 50) | pub trait Mode {
    type Graph (line 69) | type Graph = M;
    type VertexStorage (line 70) | type VertexStorage = <Vertex<Data<M>> as Entity>::Storage;
    type ArcStorage (line 71) | type ArcStorage = <Arc<Data<M>> as Entity>::Storage;
    type EdgeStorage (line 72) | type EdgeStorage = <Edge<Data<M>> as Entity>::Storage;
    type FaceStorage (line 73) | type FaceStorage = <Face<Data<M>> as Entity>::Storage;
  type Immediate (line 58) | pub struct Immediate<M>
  type Mutation (line 77) | pub struct Mutation<P>
  function as_ref (line 90) | fn as_ref(&self) -> &Self {
  function as_mut (line 100) | fn as_mut(&mut self) -> &mut Self {
  function as_storage (line 110) | fn as_storage(&self) -> &StorageTarget<Arc<Data<P::Graph>>> {
  function as_storage (line 120) | fn as_storage(&self) -> &StorageTarget<Edge<Data<P::Graph>>> {
  function as_storage (line 130) | fn as_storage(&self) -> &StorageTarget<Face<Data<P::Graph>>> {
  function as_storage (line 140) | fn as_storage(&self) -> &StorageTarget<Vertex<Data<P::Graph>>> {
  function bypass (line 149) | fn bypass(self) -> Self::Commit {
  type Target (line 160) | type Target = FaceMutation<P>;
  method deref (line 162) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 172) | fn deref_mut(&mut self) -> &mut Self::Target {
  function from (line 181) | fn from(graph: M) -> Self {
  type Data (line 193) | type Data = Data<P::Graph>;
  type Commit (line 200) | type Commit = M;
  type Abort (line 201) | type Abort = ();
  type Error (line 202) | type Error = GraphError;
  function commit (line 204) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 208) | fn abort(self) -> Self::Abort {}
  type Mutable (line 211) | pub trait Mutable:

FILE: plexus/src/graph/mutation/path.rs
  type PathExtrudeCache (line 17) | pub struct PathExtrudeCache {
    method from_path (line 23) | pub fn from_path<B>(path: Path<B>) -> Result<Self, GraphError>
  function extrude_contour_with (line 43) | pub fn extrude_contour_with<N, P, F>(

FILE: plexus/src/graph/mutation/vertex.rs
  type ModalCore (line 13) | type ModalCore<P> = Core<Data<<P as Mode>::Graph>, <P as Mode>::VertexSt...
  type RefCore (line 14) | type RefCore<'a, G> = Core<G, &'a StorageTarget<'a, Vertex<G>>, (), (), ...
  type VertexMutation (line 16) | pub struct VertexMutation<P>
  function to_ref_core (line 27) | pub fn to_ref_core(&self) -> RefCore<Data<P::Graph>> {
  function connect_outgoing_arc (line 31) | pub fn connect_outgoing_arc(&mut self, a: VertexKey, ab: ArcKey) -> Resu...
  function disconnect_outgoing_arc (line 35) | pub fn disconnect_outgoing_arc(&mut self, a: VertexKey) -> Result<Option...
  function with_vertex_mut (line 39) | fn with_vertex_mut<T, F>(&mut self, a: VertexKey, mut f: F) -> Result<T,...
  function as_storage (line 56) | fn as_storage(&self) -> &StorageTarget<Vertex<Data<P::Graph>>> {
  function bypass (line 65) | fn bypass(self) -> Self::Commit {
  function from (line 77) | fn from(core: ModalCore<P>) -> Self {
  type Commit (line 87) | type Commit = ModalCore<Immediate<M>>;
  type Abort (line 88) | type Abort = ();
  type Error (line 89) | type Error = GraphError;
  function commit (line 91) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 104) | fn abort(self) -> Self::Abort {}
  type VertexRemoveCache (line 107) | pub struct VertexRemoveCache {
    method from_vertex (line 112) | pub fn from_vertex<B>(vertex: VertexView<B>) -> Result<Self, GraphError>
  function insert (line 122) | pub fn insert<N, P>(mut mutation: N, data: <Data<P::Graph> as GraphData>...
  function remove (line 135) | pub fn remove<N, P>(

FILE: plexus/src/graph/path.rs
  type Mutation (line 20) | type Mutation<M> = mutation::Mutation<Immediate<M>>;
  type Path (line 38) | pub struct Path<'k, B>
  function bind (line 56) | pub(in crate::graph) fn bind<I>(storage: B, keys: I) -> Result<Self, Gra...
  function bind_unchecked (line 76) | fn bind_unchecked<I>(storage: B, keys: I) -> Self
  function to_ref (line 92) | pub fn to_ref(&self) -> Path<&M> {
  function into_opposite_path (line 100) | pub fn into_opposite_path(self) -> Path<'static, B> {
  function opposite_path (line 109) | pub fn opposite_path(&self) -> Path<'static, &M> {
  function push_back (line 129) | pub fn push_back(
  function push_previous_arc (line 171) | pub fn push_previous_arc(&mut self) -> Result<ArcKey, GraphError> {
  function pop_back (line 181) | pub fn pop_back(&mut self) -> Option<ArcKey> {
  function push_front (line 207) | pub fn push_front(
  function push_next_arc (line 250) | pub fn push_next_arc(&mut self) -> Result<ArcKey, GraphError> {
  function pop_front (line 260) | pub fn pop_front(&mut self) -> Option<ArcKey> {
  function back (line 271) | pub fn back(&self) -> VertexView<&M> {
  function front (line 277) | pub fn front(&self) -> VertexView<&M> {
  function shortest_metric_with (line 282) | pub fn shortest_metric_with<Q, F>(
  function is_open (line 304) | pub fn is_open(&self) -> bool {
  function is_closed (line 312) | pub fn is_closed(&self) -> bool {
  function terminals (line 317) | fn terminals(&self) -> (VertexKey, VertexKey) {
  function shortest_subpath_terminals (line 323) | fn shortest_subpath_terminals(
  function into_ref (line 368) | pub fn into_ref(self) -> Path<'k, &'a M> {
  function split (line 397) | pub fn split(
  function vertices (line 435) | pub fn vertices(&self) -> impl Clone + Iterator<Item = VertexView<&B::Ta...
  function arcs (line 448) | pub fn arcs(&self) -> impl Clone + ExactSizeIterator<Item = ArcView<&B::...
  function extrude_contour_with (line 483) | pub fn extrude_contour_with<F>(self, f: F) -> Result<FaceView<&'a mut M>...
  function extrude_surface_with (line 497) | pub fn extrude_surface_with<F>(self, f: F) -> Result<Self, GraphError>
  function from (line 512) | fn from(ring: Ring<B>) -> Self {
  method eq (line 525) | fn eq(&self, other: &Self) -> bool {
  function truncate (line 531) | fn truncate<T>(
  type E2 (line 555) | type E2 = Point2<f64>;
  function open_close (line 558) | fn open_close() {
  function logical_metrics (line 584) | fn logical_metrics() {
  function split (line 611) | fn split() {

FILE: plexus/src/graph/vertex.rs
  type Mutation (line 32) | type Mutation<M> = mutation::Mutation<Immediate<M>>;
  type Vertex (line 37) | pub struct Vertex<G>
  function new (line 52) | pub fn new(data: G::Vertex) -> Self {
  type Data (line 69) | type Data = G::Vertex;
  method get (line 71) | fn get(&self) -> &Self::Data {
  method get_mut (line 75) | fn get_mut(&mut self) -> &mut Self::Data {
  type VertexKey (line 82) | pub struct VertexKey(u64);
  type Inner (line 85) | type Inner = u64;
  method from_inner (line 87) | fn from_inner(key: Self::Inner) -> Self {
  method into_inner (line 91) | fn into_inner(self) -> Self::Inner {
  type VertexView (line 101) | pub struct VertexView<B>
  function to_ref (line 114) | pub fn to_ref(&self) -> VertexView<&M> {
  function to_mut_unchecked (line 127) | fn to_mut_unchecked(&mut self) -> VertexView<&mut M> {
  function into_ref (line 167) | pub fn into_ref(self) -> VertexView<&'a M> {
  function get (line 178) | pub fn get<'a>(&'a self) -> &'a G::Vertex
  function position (line 185) | pub fn position<'a>(&'a self) -> &'a VertexPosition<G>
  function get_mut (line 200) | pub fn get_mut<'a>(&'a mut self) -> &'a mut G::Vertex
  function into_reachable_outgoing_arc (line 215) | pub(in crate::graph) fn into_reachable_outgoing_arc(self) -> Option<ArcV...
  function into_outgoing_arc (line 228) | pub fn into_outgoing_arc(self) -> ArcView<B> {
  function outgoing_arc (line 233) | pub fn outgoing_arc(&self) -> ArcView<&M> {
  function shortest_path (line 237) | pub fn shortest_path(&self, key: VertexKey) -> Result<Path<'static, &M>,...
  function into_shortest_path (line 241) | pub fn into_shortest_path(self, key: VertexKey) -> Result<Path<'static, ...
  function shortest_path_with (line 245) | pub fn shortest_path_with<Q, F>(
  function into_shortest_path_with (line 257) | pub fn into_shortest_path_with<Q, F>(
  function valence (line 284) | pub fn valence(&self) -> usize {
  function centroid (line 288) | pub fn centroid(&self) -> VertexPosition<G>
  function normal (line 307) | pub fn normal(&self) -> Result<Vector<VertexPosition<G>>, GraphError>
  function into_reachable_incoming_arcs (line 323) | pub(in crate::graph) fn into_reachable_incoming_arcs(
  function into_reachable_outgoing_arcs (line 330) | pub(in crate::graph) fn into_reachable_outgoing_arcs(
  function reachable_incoming_arcs (line 346) | pub(in crate::graph) fn reachable_incoming_arcs(
  function reachable_outgoing_arcs (line 352) | pub(in crate::graph) fn reachable_outgoing_arcs(
  function into_adjacent_vertices (line 365) | pub fn into_adjacent_vertices(self) -> impl Clone + Iterator<Item = Vert...
  function into_incoming_arcs (line 369) | pub fn into_incoming_arcs(self) -> impl Clone + Iterator<Item = ArcView<...
  function into_outgoing_arcs (line 373) | pub fn into_outgoing_arcs(self) -> impl Clone + Iterator<Item = ArcView<...
  function adjacent_vertices (line 384) | pub fn adjacent_vertices(&self) -> impl Clone + Iterator<Item = VertexVi...
  function incoming_arcs (line 392) | pub fn incoming_arcs(&self) -> impl Clone + Iterator<Item = ArcView<&B::...
  function outgoing_arcs (line 400) | pub fn outgoing_arcs(&self) -> impl Clone + Iterator<Item = ArcView<&B::...
  function traverse_by_breadth (line 409) | pub fn traverse_by_breadth(&self) -> impl Clone + Iterator<Item = Vertex...
  function traverse_by_depth (line 418) | pub fn traverse_by_depth(&self) -> impl Clone + Iterator<Item = VertexVi...
  function into_adjacent_faces (line 434) | pub fn into_adjacent_faces(self) -> impl Clone + Iterator<Item = FaceVie...
  function adjacent_faces (line 453) | pub fn adjacent_faces(&self) -> impl Clone + Iterator<Item = FaceView<&B...
  function into_adjacent_vertex_orphans (line 462) | pub fn into_adjacent_vertex_orphans(self) -> impl Iterator<Item = Vertex...
  function adjacent_vertex_orphans (line 472) | pub fn adjacent_vertex_orphans(&mut self) -> impl Iterator<Item = Vertex...
  function into_incoming_arc_orphans (line 481) | pub fn into_incoming_arc_orphans(self) -> impl Iterator<Item = ArcOrphan...
  function incoming_arc_orphans (line 495) | pub fn incoming_arc_orphans(&mut self) -> impl Iterator<Item = ArcOrphan...
  function into_adjacent_face_orphans (line 508) | pub fn into_adjacent_face_orphans(self) -> impl Iterator<Item = FaceOrph...
  function adjacent_face_orphans (line 526) | pub fn adjacent_face_orphans(&mut self) -> impl Iterator<Item = FaceOrph...
  function remove (line 574) | pub fn remove(self) {
  type Output (line 592) | type Output = SmallVec<[Self::Key; 8]>;
  method adjacency (line 594) | fn adjacency(&self) -> Self::Output {
  function borrow (line 604) | fn borrow(&self) -> &VertexKey {
  method clone (line 616) | fn clone(&self) -> Self {
  type Key (line 629) | type Key = VertexKey;
  type Entity (line 630) | type Entity = Vertex<G>;
  method key (line 632) | fn key(&self) -> Self::Key {
  type Target (line 652) | type Target = Vertex<G>;
  method deref (line 654) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 665) | fn deref_mut(&mut self) -> &mut Self::Target {
  function from (line 684) | fn from(view: View<B, Vertex<G>>) -> Self {
  function from (line 695) | fn from(vertex: VertexView<B>) -> Self {
  method hash (line 707) | fn hash<H>(&self, state: &mut H)
  method eq (line 721) | fn eq(&self, other: &Self) -> bool {
  type VertexOrphan (line 727) | pub struct VertexOrphan<'a, G>
  function position (line 738) | pub fn position(&self) -> &VertexPosition<G>
  function get (line 750) | pub fn get(&self) -> &G::Vertex {
  function get_mut (line 754) | pub fn get_mut(&mut self) -> &mut G::Vertex {
  function borrow (line 763) | fn borrow(&self) -> &VertexKey {
  type Key (line 772) | type Key = VertexKey;
  type Entity (line 773) | type Entity = Vertex<G>;
  method key (line 775) | fn key(&self) -> Self::Key {
  function from (line 786) | fn from(inner: Orphan<'a, Vertex<G>>) -> Self {
  function from (line 795) | fn from(view: View<&'a mut M, Vertex<M::Data>>) -> Self {
  function from (line 804) | fn from(vertex: VertexView<&'a mut M>) -> Self {
  method hash (line 813) | fn hash<H>(&self, state: &mut H)
  method eq (line 825) | fn eq(&self, other: &Self) -> bool {
  type VertexCirculator (line 830) | pub struct VertexCirculator<P, B>
  type Entity (line 846) | type Entity = Vertex<G>;
    type Key (line 61) | type Key = VertexKey;
    type Storage (line 62) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 848) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 863) | fn clone(&self) -> Self {
  function from (line 877) | fn from(inner: ArcCirculator<P, B>) -> Self {
  type Item (line 887) | type Item = VertexView<&'a M>;
  method next (line 889) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 898) | type Item = VertexOrphan<'a, M::Data>;
  method next (line 900) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 909) | type Item = VertexOrphan<'a, M::Data>;
  method next (line 911) | fn next(&mut self) -> Option<Self::Item> {
  function target (line 921) | fn target(&mut self) -> &mut M {
  function target (line 931) | fn target(&self) -> &'a M {
  type ArcCirculator (line 936) | pub struct ArcCirculator<P, B>
  type Entity (line 954) | type Entity = Arc<G>;
    type Key (line 61) | type Key = VertexKey;
    type Storage (line 62) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 956) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 982) | fn clone(&self) -> Self {
  function from (line 998) | fn from(vertex: VertexView<B>) -> Self {
  type Item (line 1014) | type Item = ArcView<&'a M>;
  method next (line 1016) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 1025) | type Item = ArcOrphan<'a, M::Data>;
  method next (line 1027) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 1036) | type Item = ArcOrphan<'a, M::Data>;
  method next (line 1038) | fn next(&mut self) -> Option<Self::Item> {
  function target (line 1048) | fn target(&mut self) -> &mut M {
  function target (line 1058) | fn target(&self) -> &'a M {
  type FaceCirculator (line 1063) | pub struct FaceCirculator<P, B>
  type Entity (line 1079) | type Entity = Face<G>;
    type Key (line 61) | type Key = VertexKey;
    type Storage (line 62) | type Storage = HashStorage<Self, IncrementalKeyer>;
  function next (line 1081) | fn next(&mut self) -> Option<<Self::Entity as Entity>::Key> {
  method clone (line 1110) | fn clone(&self) -> Self {
  function from (line 1124) | fn from(inner: ArcCirculator<P, B>) -> Self {
  type Item (line 1134) | type Item = FaceView<&'a M>;
  method next (line 1136) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 1145) | type Item = FaceOrphan<'a, M::Data>;
  method next (line 1147) | fn next(&mut self) -> Option<Self::Item> {
  type Item (line 1156) | type Item = FaceOrphan<'a, M::Data>;
  method next (line 1158) | fn next(&mut self) -> Option<Self::Item> {
  function target (line 1168) | fn target(&mut self) -> &mut M {
  function target (line 1178) | fn target(&self) -> &'a M {
  type E3 (line 1195) | type E3 = Point3<R64>;
  function circulate_over_arcs (line 1198) | fn circulate_over_arcs() {
  function reachable_shortest_path (line 1211) | fn reachable_shortest_path() {
  function unreachable_shortest_path (line 1227) | fn unreachable_shortest_path() {
  function traverse_by_breadth (line 1252) | fn traverse_by_breadth() {
  function traverse_by_depth (line 1262) | fn traverse_by_depth() {

FILE: plexus/src/index.rs
  type BufferOf (line 94) | pub(crate) type BufferOf<R> = Vec<<R as Grouping>::Group>;
  type IndexOf (line 95) | pub(crate) type IndexOf<R> = <BufferOf<R> as IndexBuffer<R>>::Index;
  type IndexBuffer (line 109) | pub trait IndexBuffer<R>
  type Index (line 128) | type Index = T;
  type Index (line 136) | type Index = P::Vertex;
  type Push (line 139) | pub trait Push<R, P>: IndexBuffer<R>
    method push (line 145) | fn push(&mut self, index: P);
  function push (line 155) | fn push(&mut self, index: P) {
  function push (line 169) | fn push(&mut self, index: Q) {
  type Grouping (line 174) | pub trait Grouping: StaticArity {
    type Group (line 228) | type Group = T;
    type Group (line 283) | type Group = P;
  type Flat (line 211) | pub struct Flat<T, const N: usize>
  type Static (line 245) | type Static = usize;
  constant ARITY (line 247) | const ARITY: Self::Static = crate::n_arity(N);
  type Flat3 (line 251) | pub type Flat3<T = usize> = Flat<T, 3>;
  type Flat4 (line 253) | pub type Flat4<T = usize> = Flat<T, 4>;
  type Indexer (line 290) | pub trait Indexer<T, K>
    method index (line 299) | fn index<F>(&mut self, vertex: T::Vertex, f: F) -> (usize, Option<T::V...
  type HashIndexer (line 337) | pub struct HashIndexer<T, K>
  function new (line 353) | pub fn new() -> Self {
  method default (line 367) | fn default() -> Self {
  function index (line 377) | fn index<F>(&mut self, input: T::Vertex, f: F) -> (usize, Option<T::Vert...
  type LruIndexer (line 424) | pub struct LruIndexer<T, K>
  function new (line 441) | pub fn new() -> Self {
  function with_capacity (line 449) | pub fn with_capacity(capacity: usize) -> Self {
  function find (line 459) | fn find(&self, key: &K) -> Option<(usize, usize)> {
  method default (line 473) | fn default() -> Self {
  function index (line 483) | fn index<F>(&mut self, input: T::Vertex, f: F) -> (usize, Option<T::Vert...
  type GroupedIndexVertices (line 518) | pub trait GroupedIndexVertices<R, P>: Sized
    method index_vertices_with (line 523) | fn index_vertices_with<N, K, F>(self, indexer: N, f: F) -> (Vec<R::Gro...
    method index_vertices (line 528) | fn index_vertices<N>(self, indexer: N) -> (Vec<R::Group>, Vec<P::Vertex>)
  method index_vertices_with (line 545) | fn index_vertices_with<N, K, F>(self, mut indexer: N, f: F) -> (Vec<R::G...
  type IndexVertices (line 602) | pub trait IndexVertices<P>
    method index_vertices_with (line 608) | fn index_vertices_with<R, N, K, F>(self, indexer: N, f: F) -> (Vec<R::...
    method index_vertices (line 643) | fn index_vertices<R, N>(self, indexer: N) -> (Vec<R::Group>, Vec<P::Ve...
  type FromIndexer (line 660) | pub trait FromIndexer<P, Q>: Sized
    method from_indexer (line 667) | fn from_indexer<I, N>(input: I, indexer: N) -> Result<Self, Self::Error>
  type CollectWithIndexer (line 684) | pub trait CollectWithIndexer<P, Q>
    method collect_with_indexer (line 718) | fn collect_with_indexer<T, N>(self, indexer: N) -> Result<T, T::Error>
  method collect_with_indexer (line 730) | fn collect_with_indexer<T, N>(self, indexer: N) -> Result<T, T::Error>

FILE: plexus/src/integration/cgmath.rs
  function from_geometry (line 15) | fn from_geometry(other: (U, U)) -> Self {
  function from_geometry (line 25) | fn from_geometry(other: Vector2<T>) -> Self {
  function from_geometry (line 35) | fn from_geometry(other: (U, U, U)) -> Self {
  function from_geometry (line 49) | fn from_geometry(other: Vector3<T>) -> Self {
  function from_geometry (line 63) | fn from_geometry(other: (U, U)) -> Self {
  function from_geometry (line 73) | fn from_geometry(other: Point2<T>) -> Self {
  function from_geometry (line 85) | fn from_geometry(other: (U, U, U)) -> Self {
  function from_geometry (line 99) | fn from_geometry(other: Point3<T>) -> Self {
  type Vertex (line 112) | type Vertex = Self;
  type Arc (line 113) | type Arc = ();
  type Edge (line 114) | type Edge = ();
  type Face (line 115) | type Face = ();
  type Vertex (line 122) | type Vertex = Self;
  type Arc (line 123) | type Arc = ();
  type Edge (line 124) | type Edge = ();
  type Face (line 125) | type Face = ();

FILE: plexus/src/integration/glam.rs
  method from_geometry (line 9) | fn from_geometry(other: (f32, f32)) -> Self {
  method from_geometry (line 15) | fn from_geometry(other: (f32, f32, f32)) -> Self {
  method from_geometry (line 21) | fn from_geometry(other: (f32, f32, f32)) -> Self {
  type Vertex (line 27) | type Vertex = Self;
  type Arc (line 28) | type Arc = ();
  type Edge (line 29) | type Edge = ();
  type Face (line 30) | type Face = ();
  type Vertex (line 34) | type Vertex = Self;
  type Arc (line 35) | type Arc = ();
  type Edge (line 36) | type Edge = ();
  type Face (line 37) | type Face = ();
  type Vertex (line 41) | type Vertex = Self;
  type Arc (line 42) | type Arc = ();
  type Edge (line 43) | type Edge = ();
  type Face (line 44) | type Face = ();

FILE: plexus/src/integration/mint.rs
  function from_geometry (line 15) | fn from_geometry(other: (U, U)) -> Self {
  function from_geometry (line 28) | fn from_geometry(other: Vector2<T>) -> Self {
  function from_geometry (line 38) | fn from_geometry(other: (U, U, U)) -> Self {
  function from_geometry (line 52) | fn from_geometry(other: Vector3<T>) -> Self {
  function from_geometry (line 66) | fn from_geometry(other: (U, U)) -> Self {
  function from_geometry (line 79) | fn from_geometry(other: Point2<T>) -> Self {
  function from_geometry (line 91) | fn from_geometry(other: (U, U, U)) -> Self {
  function from_geometry (line 105) | fn from_geometry(other: Point3<T>) -> Self {
  type Vertex (line 118) | type Vertex = Self;
  type Arc (line 119) | type Arc = ();
  type Edge (line 120) | type Edge = ();
  type Face (line 121) | type Face = ();
  type Vertex (line 128) | type Vertex = Self;
  type Arc (line 129) | type Arc = ();
  type Edge (line 130) | type Edge = ();
  type Face (line 131) | type Face = ();

FILE: plexus/src/integration/nalgebra.rs
  function from_geometry (line 18) | fn from_geometry(other: (U, U)) -> Self {
  function from_geometry (line 28) | fn from_geometry(other: Vector2<T>) -> Self {
  function from_geometry (line 39) | fn from_geometry(other: (U, U, U)) -> Self {
  function from_geometry (line 53) | fn from_geometry(other: Vector3<T>) -> Self {
  function from_geometry (line 68) | fn from_geometry(other: (U, U)) -> Self {
  function from_geometry (line 78) | fn from_geometry(other: Point2<T>) -> Self {
  function from_geometry (line 89) | fn from_geometry(other: (U, U, U)) -> Self {
  function from_geometry (line 103) | fn from_geometry(other: Point3<T>) -> Self {
  type Vertex (line 120) | type Vertex = Self;
  type Arc (line 121) | type Arc = ();
  type Edge (line 122) | type Edge = ();
  type Face (line 123) | type Face = ();

FILE: plexus/src/integration/ultraviolet.rs
  method from_geometry (line 9) | fn from_geometry(other: (f32, f32)) -> Self {
  method from_geometry (line 15) | fn from_geometry(other: (f32, f32, f32)) -> Self {
  type Vertex (line 21) | type Vertex = Self;
  type Arc (line 22) | type Arc = ();
  type Edge (line 23) | type Edge = ();
  type Face (line 24) | type Face = ();
  type Vertex (line 28) | type Vertex = Self;
  type Arc (line 29) | type Arc = ();
  type Edge (line 30) | type Edge = ();
  type Face (line 31) | type Face = ();

FILE: plexus/src/lib.rs
  type Arity (line 105) | pub trait Arity: Copy {
    method into_interval (line 106) | fn into_interval(self) -> (usize, Option<usize>);
    method into_interval (line 111) | fn into_interval(self) -> (usize, Option<usize>) {
    method into_interval (line 121) | fn into_interval(self) -> (usize, Option<usize>) {
    method into_interval (line 134) | fn into_interval(self) -> (usize, Option<usize>) {
    method into_interval (line 227) | fn into_interval(self) -> (usize, Option<usize>) {
  type StaticArity (line 146) | pub trait StaticArity {
    constant ARITY (line 149) | const ARITY: Self::Static;
  type DynamicArity (line 159) | pub trait DynamicArity: StaticArity {
    method arity (line 162) | fn arity(&self) -> Self::Dynamic;
  type Monomorphic (line 178) | pub trait Monomorphic: StaticArity<Static = usize> {}
  type MeshArity (line 189) | pub enum MeshArity {
    method from_components (line 208) | pub fn from_components<T, I>(components: I) -> Self
  type TryFromIterator (line 235) | pub trait TryFromIterator<T>: Sized {
    method try_from_iter (line 238) | fn try_from_iter<I>(items: I) -> Result<Self, Self::Error>
  type Error (line 244) | type Error = ();
  function try_from_iter (line 246) | fn try_from_iter<I>(items: I) -> Result<Self, Self::Error>
  type IteratorExt (line 301) | pub trait IteratorExt: Iterator + Sized {
    method perimeter (line 307) | fn perimeter(self) -> Perimeter<Self>
    method keys (line 356) | fn keys(self) -> Keys<Self>
    method has_at_least (line 388) | fn has_at_least(self, n: usize) -> Option<MultiPeek<Self>> {
    method has_exactly (line 395) | fn has_exactly(self, n: usize) -> Option<MultiPeek<Self>> {
    method try_collect (line 404) | fn try_collect<T>(self) -> Result<T, T::Error>
  type Perimeter (line 425) | pub struct Perimeter<I>
  function new (line 440) | fn new(mut input: I) -> Self {
  type Item (line 456) | type Item = (I::Item, I::Item);
  method next (line 458) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 469) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Keys (line 481) | pub struct Keys<I>
  function new (line 494) | fn new(input: I) -> Self {
  type Item (line 504) | type Item = <I::Item as ClosedView>::Key;
  method next (line 506) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 510) | fn size_hint(&self) -> (usize, Option<usize>) {
  function peek_n (line 515) | fn peek_n<I>(input: I, n: usize) -> Option<MultiPeek<I>>
  function n_arity (line 532) | const fn n_arity(n: usize) -> usize {

FILE: plexus/src/primitive/cube.rs
  type Plane (line 35) | pub enum Plane {
    method normal (line 45) | pub fn normal<S>(self) -> Unit<S>
  type Bounds (line 63) | pub struct Bounds<S>
  function with_radius (line 75) | pub fn with_radius(radius: Scalar<S>) -> Self {
  function with_width (line 82) | pub fn with_width(width: Scalar<S>) -> Self {
  function unit_radius (line 86) | pub fn unit_radius() -> Self {
  function unit_width (line 90) | pub fn unit_width() -> Self {
  method default (line 99) | fn default() -> Self {
  type Cube (line 105) | pub struct Cube;
    method new (line 108) | pub fn new() -> Self {
    type State (line 129) | type State = ();
    type Output (line 136) | type Output = Unit<Vector<S>>;
    method vertex_count (line 138) | fn vertex_count(&self) -> usize {
    method vertex_from (line 142) | fn vertex_from(&self, _: &Self::State, index: usize) -> Self::Output {
    type Output (line 151) | type Output = Tetragon<Unit<Vector<S>>>;
    method polygon_from (line 153) | fn polygon_from(&self, state: &Self::State, index: usize) -> Self::Out...
    type Output (line 160) | type Output = Tetragon<usize>;
    method indexing_polygon (line 162) | fn indexing_polygon(&self, index: usize) -> Self::Output {
    type State (line 172) | type State = Bounds<S>;
    type Output (line 179) | type Output = S;
    method vertex_count (line 181) | fn vertex_count(&self) -> usize {
    method vertex_from (line 185) | fn vertex_from(&self, state: &Self::State, index: usize) -> Self::Outp...
    type Output (line 212) | type Output = Tetragon<S>;
    method polygon_from (line 214) | fn polygon_from(&self, state: &Self::State, index: usize) -> Self::Out...
    type Output (line 221) | type Output = Tetragon<usize>;
    method indexing_polygon (line 223) | fn indexing_polygon(&self, index: usize) -> Self::Output {
    type State (line 237) | type State = ();
    type Output (line 241) | type Output = Plane;
    method vertex_count (line 243) | fn vertex_count(&self) -> usize {
    method vertex_from (line 247) | fn vertex_from(&self, _: &Self::State, index: usize) -> Self::Output {
    type Output (line 261) | type Output = Tetragon<Plane>;
    method polygon_from (line 263) | fn polygon_from(&self, state: &Self::State, index: usize) -> Self::Out...
    type Output (line 270) | type Output = Tetragon<usize>;
    method indexing_polygon (line 272) | fn indexing_polygon(&self, index: usize) -> Self::Output {
  method default (line 114) | fn default() -> Self {
  method polygon_count (line 120) | fn polygon_count(&self) -> usize {

FILE: plexus/src/primitive/decompose.rs
  type Decompose (line 82) | pub struct Decompose<I, P, Q, R>
  function new (line 95) | pub(in crate::primitive) fn new(input: I, f: fn(P) -> R) -> Self {
  function remap (line 135) | pub fn remap(self, n: usize) -> Decompose<impl Iterator<Item = P>, P, P,...
  type Item (line 146) | type Item = Q;
  method next (line 148) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 162) | fn size_hint(&self) -> (usize, Option<usize>) {
  type IntoVertices (line 168) | pub trait IntoVertices: Topological {
    method into_vertices (line 171) | fn into_vertices(self) -> Self::Output;
    type Output (line 178) | type Output = <T as IntoIterator>::IntoIter;
    method into_vertices (line 180) | fn into_vertices(self) -> Self::Output {
  type IntoEdges (line 185) | pub trait IntoEdges: Topological {
    method into_edges (line 188) | fn into_edges(self) -> Self::Output;
    type Output (line 218) | type Output = Vec<Edge<Self::Vertex>>;
    method into_edges (line 220) | fn into_edges(self) -> Self::Output {
    type Output (line 240) | type Output = Vec<Edge<Self::Vertex>>;
    method into_edges (line 242) | fn into_edges(self) -> Self::Output {
    type Output (line 254) | type Output = Vec<Edge<Self::Vertex>>;
    method into_edges (line 256) | fn into_edges(self) -> Self::Output {
  type IntoTrigons (line 191) | pub trait IntoTrigons: Polygonal {
    method into_trigons (line 194) | fn into_trigons(self) -> Self::Output;
    type Output (line 265) | type Output = ArrayVec<Trigon<Self::Vertex>, 1>;
    method into_trigons (line 267) | fn into_trigons(self) -> Self::Output {
    type Output (line 276) | type Output = ArrayVec<Trigon<Self::Vertex>, 2>;
    method into_trigons (line 278) | fn into_trigons(self) -> Self::Output {
    type Output (line 288) | type Output = Vec<Trigon<Self::Vertex>>;
    method into_trigons (line 290) | fn into_trigons(self) -> Self::Output {
  type IntoSubdivisions (line 197) | pub trait IntoSubdivisions: Polygonal {
    method into_subdivisions (line 200) | fn into_subdivisions(self) -> Self::Output;
    type Output (line 302) | type Output = ArrayVec<Trigon<Self::Vertex>, 2>;
    method into_subdivisions (line 304) | fn into_subdivisions(self) -> Self::Output {
    type Output (line 315) | type Output = ArrayVec<Tetragon<Self::Vertex>, 4>;
    method into_subdivisions (line 317) | fn into_subdivisions(self) -> Self::Output {
    type Output (line 353) | type Output = Vec<Self>;
    method into_subdivisions (line 355) | fn into_subdivisions(self) -> Self::Output {
  type IntoTetrahedrons (line 203) | pub trait IntoTetrahedrons: Polygonal {
    method into_tetrahedrons (line 204) | fn into_tetrahedrons(self) -> ArrayVec<Trigon<Self::Vertex>, 4>;
    method into_tetrahedrons (line 337) | fn into_tetrahedrons(self) -> ArrayVec<Trigon<Self::Vertex>, 4> {
  type Vertices (line 371) | pub trait Vertices<P>: Sized
    method vertices (line 375) | fn vertices(self) -> Decompose<Self, P, P::Vertex, P::Output>;
  method vertices (line 383) | fn vertices(self) -> Decompose<Self, P, P::Vertex, P::Output> {
  type Edges (line 388) | pub trait Edges<P>: Sized
    method edges (line 392) | fn edges(self) -> Decompose<Self, P, Edge<P::Vertex>, P::Output>;
  method edges (line 401) | fn edges(self) -> Decompose<Self, P, Edge<P::Vertex>, P::Output> {
  type Triangulate (line 406) | pub trait Triangulate<P>: Sized
    method triangulate (line 410) | fn triangulate(self) -> Decompose<Self, P, Trigon<P::Vertex>, P::Output>;
  method triangulate (line 418) | fn triangulate(self) -> Decompose<Self, P, Trigon<P::Vertex>, P::Output> {
  type Subdivide (line 423) | pub trait Subdivide<P>: Sized
    method subdivide (line 427) | fn subdivide(self) -> Decompose<Self, P, P, P::Output>;
  method subdivide (line 435) | fn subdivide(self) -> Decompose<Self, P, P, P::Output> {
  type Tetrahedrons (line 440) | pub trait Tetrahedrons<T>: Sized {
    method tetrahedrons (line 441) | fn tetrahedrons(self) -> Decompose<Self, Tetragon<T>, Trigon<T>, Array...
  method tetrahedrons (line 449) | fn tetrahedrons(self) -> Decompose<Self, Tetragon<T>, Trigon<T>, ArrayVe...
  function remap (line 454) | fn remap<I, P, R, F>(n: usize, ngons: I, f: F) -> Vec<P>

FILE: plexus/src/primitive/generate.rs
  type Attribute (line 62) | pub trait Attribute {}
  type Normal (line 94) | pub struct Normal<S = ()> {
  type Position (line 132) | pub struct Position<S = ()> {
  type Generate (line 139) | pub struct Generate<'a, G, S, P>
  function new (line 153) | fn new(generator: &'a G, state: S, n: usize, f: fn(&'a G, &S, usize) -> ...
  type Item (line 167) | type Item = P;
  method next (line 169) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 175) | fn size_hint(&self) -> (usize, Option<usize>) {
  type PolygonGenerator (line 180) | pub trait PolygonGenerator {
    method polygon_count (line 181) | fn polygon_count(&self) -> usize;
  type AttributeGenerator (line 184) | pub trait AttributeGenerator<A>
  type AttributePolygonGenerator (line 191) | pub trait AttributePolygonGenerator<A>: AttributeGenerator<A> + PolygonG...
    method polygon_from (line 197) | fn polygon_from(&self, state: &Self::State, index: usize) -> Self::Out...
  type AttributeVertexGenerator (line 200) | pub trait AttributeVertexGenerator<A>: AttributeGenerator<A>
    method vertex_count (line 206) | fn vertex_count(&self) -> usize;
    method vertex_from (line 208) | fn vertex_from(&self, state: &Self::State, index: usize) -> Self::Output;
  type IndexingPolygonGenerator (line 211) | pub trait IndexingPolygonGenerator<A>: PolygonGenerator
    method indexing_polygon (line 217) | fn indexing_polygon(&self, index: usize) -> Self::Output;
  type Generator (line 221) | pub trait Generator: Sized {
    method vertices (line 258) | fn vertices<A>(
    method vertices_from (line 268) | fn vertices_from<A>(
    method polygons (line 300) | fn polygons<A>(
    method polygons_from (line 310) | fn polygons_from<A>(
    method indexing_polygons (line 357) | fn indexing_polygons<A>(&self) -> Generate<Self, (), Self::Output>

FILE: plexus/src/primitive/mod.rs
  type Topological (line 118) | pub trait Topological:
    method try_from_slice (line 128) | fn try_from_slice<T>(vertices: T) -> Option<Self>
    method embed_into_e3_xy (line 160) | fn embed_into_e3_xy<P>(ngon: P, z: Scalar<Self::Vertex>) -> Self
    method embed_into_e3_xy_with (line 170) | fn embed_into_e3_xy_with<P, F>(ngon: P, z: Scalar<Position<Self::Verte...
    method embed_into_e3_plane (line 214) | fn embed_into_e3_plane<P>(ngon: P, plane: Plane<Self::Vertex>) -> Self
    method embed_into_e3_plane_with (line 224) | fn embed_into_e3_plane_with<P, F>(ngon: P, _: Plane<Position<Self::Ver...
    method project_into_plane (line 243) | fn project_into_plane(mut self, plane: Plane<Position<Self::Vertex>>) ...
    method edges (line 268) | fn edges(&self) -> Vec<Edge<&Self::Vertex>> {
    type Vertex (line 620) | type Vertex = G;
    method try_from_slice (line 622) | fn try_from_slice<I>(vertices: I) -> Option<Self>
    type Vertex (line 1027) | type Vertex = G;
    method try_from_slice (line 1029) | fn try_from_slice<I>(vertices: I) -> Option<Self>
    type Vertex (line 1189) | type Vertex = G;
    method try_from_slice (line 1191) | fn try_from_slice<I>(vertices: I) -> Option<Self>
  type Polygonal (line 292) | pub trait Polygonal: Topological {
    method is_convex (line 297) | fn is_convex(&self) -> bool
  type IntoIndexed (line 316) | pub trait IntoIndexed<N>: Polygonal
    method into_indexed (line 322) | fn into_indexed(self) -> Self::Indexed;
  type Indexed (line 331) | type Indexed = Q;
  method into_indexed (line 333) | fn into_indexed(self) -> Self::Indexed {
  type IntoPolygons (line 343) | pub trait IntoPolygons: Sized {
    method into_polygons (line 347) | fn into_polygons(self) -> Self::Output;
  type Rotate (line 350) | pub trait Rotate {
    method rotate (line 352) | fn rotate(self, n: isize) -> Self;
    method rotate (line 787) | fn rotate(self, n: isize) -> Self {
    method rotate (line 821) | fn rotate(self, n: isize) -> Self {
    method rotate (line 849) | fn rotate(self, n: isize) -> Self {
    method rotate (line 1012) | fn rotate(self, n: isize) -> Self {
  type Zip (line 355) | pub trait Zip {
    method zip (line 358) | fn zip(self) -> Self::Output;
  type MapVertices (line 361) | pub trait MapVertices<T, U>: Sized {
    method map_vertices (line 362) | fn map_vertices<F>(self, f: F) -> InteriorMap<Self, U, F>
  method map_vertices (line 373) | fn map_vertices<F>(self, f: F) -> InteriorMap<Self, U, F>
  type InteriorMap (line 381) | pub struct InteriorMap<I, T, F> {
  function new (line 388) | fn new(input: I, f: F) -> Self {
  type Item (line 404) | type Item = <I::Item as Map<T>>::Output;
  method next (line 406) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 410) | fn size_hint(&self) -> (usize, Option<usize>) {
  type NGon (line 443) | pub struct NGon<G, const N: usize>(pub [G; N]);
  function into_array (line 446) | pub fn into_array(self) -> [G; N] {
  function positions (line 450) | pub fn positions(&self) -> NGon<&Position<G>, N>
  function cloned (line 470) | pub fn cloned(self) -> NGon<G, N>
  function as_ref (line 479) | fn as_ref(&self) -> &[G] {
  function as_mut (line 485) | fn as_mut(&mut self) -> &mut [G] {
  type Item (line 491) | type Item = G;
  method converged (line 498) | fn converged(vertex: G) -> Self {
  type Dynamic (line 508) | type Dynamic = usize;
  method arity (line 510) | fn arity(&self) -> Self::Dynamic {
  method fold (line 519) | fn fold<U, F>(self, mut seed: U, mut f: F) -> U
  function from (line 531) | fn from(array: [G; N]) -> Self {
  method from_items (line 537) | fn from_items<I>(items: I) -> Option<Self>
  type Output (line 546) | type Output = G;
  function index (line 548) | fn index(&self, index: usize) -> &Self::Output {
  function index_mut (line 554) | fn index_mut(&mut self, index: usize) -> &mut Self::Output {
  type Output (line 560) | type Output = <Self as IntoIterator>::IntoIter;
  method into_items (line 562) | fn into_items(self) -> Self::Output {
  type Item (line 568) | type Item = G;
  type IntoIter (line 569) | type IntoIter = array::IntoIter<G, N>;
  method into_iter (line 571) | fn into_iter(self) -> Self::IntoIter {
  type Output (line 577) | type Output = NGon<H, N>;
  function map (line 579) | fn map<F>(self, f: F) -> Self::Output
  type Static (line 610) | type Static = usize;
  constant ARITY (line 612) | const ARITY: Self::Static = crate::n_arity(N);
  type Error (line 632) | type Error = ();
  function try_from_iter (line 634) | fn try_from_iter<I>(vertices: I) -> Result<Self, Self::Error>
  type Output (line 647) | type Output = NGon<H, N>;
  function zip_map (line 649) | fn zip_map<F>(self, other: Self, mut f: F) -> Self::Output
  type Edge (line 684) | pub type Edge<G> = NGon<G, 2>;
  function new (line 687) | pub fn new(a: G, b: G) -> Self {
  function line (line 691) | pub fn line(&self) -> Option<Line<Position<G>>>
  function is_bisected (line 699) | pub fn is_bisected(&self, other: &Self) -> bool
  type EdgeEdge (line 723) | pub enum EdgeEdge<S>
  function into_point (line 735) | pub fn into_point(self) -> Option<S> {
  function into_edge (line 742) | pub fn into_edge(self) -> Option<Edge<S>> {
  method fmt (line 755) | fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
  type Output (line 768) | type Output = EdgeEdge<Position<T>>;
  function intersection (line 773) | fn intersection(&self, other: &Edge<T>) -> Option<Self::Output> {
  type Trigon (line 799) | pub type Trigon<G> = NGon<G, 3>;
  function new (line 802) | pub fn new(a: G, b: G, c: G) -> Self {
  function plane (line 806) | pub fn plane(&self) -> Option<Plane<Position<G>>>
  type Tetragon (line 838) | pub type Tetragon<G> = NGon<G, 4>;
  function new (line 841) | pub fn new(a: G, b: G, c: G, d: G) -> Self {
  type BoundedPolygon (line 881) | pub enum BoundedPolygon<G> {
  function as_ref (line 887) | fn as_ref(&self) -> &[G] {
  function as_mut (line 896) | fn as_mut(&mut self) -> &mut [G] {
  type Item (line 905) | type Item = G;
  type Dynamic (line 909) | type Dynamic = usize;
  method arity (line 911) | fn arity(&self) -> Self::Dynamic {
  method fold (line 920) | fn fold<U, F>(self, mut seed: U, mut f: F) -> U
  function from (line 932) | fn from(array: [G; 3]) -> Self {
  function from (line 938) | fn from(array: [G; 4]) -> Self {
  function from (line 944) | fn from(trigon: Trigon<G>) -> Self {
  function from (line 950) | fn from(tetragon: Tetragon<G>) -> Self {
  type Output (line 956) | type Output = G;
  function index (line 958) | fn index(&self, index: usize) -> &Self::Output {
  function index_mut (line 967) | fn index_mut(&mut self, index: usize) -> &mut Self::Output {
  type Output (line 976) | type Output = SmallVec<[G; 4]>;
  method into_items (line 978) | fn into_items(self) -> Self::Output {
  type Item (line 987) | type Item = G;
  type IntoIter (line 988) | type IntoIter = <<Self as IntoItems>::Output as IntoIterator>::IntoIter;
  method into_iter (line 990) | fn into_iter(self) -> Self::IntoIter {
  type Output (line 996) | type Output = BoundedPolygon<U>;
  function map (line 998) | fn map<F>(self, f: F) -> Self::Output
  type Static (line 1021) | type Static = (usize, usize);
  constant ARITY (line 1023) | const ARITY: Self::Static = (3, 4);
  type UnboundedPolygon (line 1057) | pub struct UnboundedPolygon<G>(SmallVec<[G; 4]>);
  function trigon (line 1060) | pub fn trigon(a: G, b: G, c: G) -> Self {
  function tetragon (line 1064) | pub fn tetragon(a: G, b: G, c: G, d: G) -> Self {
  function positions (line 1068) | pub fn positions(&self) -> UnboundedPolygon<&Position<G>>
  function cloned (line 1080) | pub fn cloned(self) -> UnboundedPolygon<G> {
  type Item (line 1086) | type Item = G;
  function as_ref (line 1090) | fn as_ref(&self) -> &[G] {
  function as_mut (line 1096) | fn as_mut(&mut self) -> &mut [G] {
  type Dynamic (line 1102) | type Dynamic = usize;
  method arity (line 1104) | fn arity(&self) -> Self::Dynamic {
  function from (line 1113) | fn from(polygon: BoundedPolygon<G>) -> Self {
  function from (line 1124) | fn from(ngon: NGon<G, N>) -> Self {
  method from_items (line 1130) | fn from_items<I>(items: I) -> Option<Self>
  type Output (line 1139) | type Output = G;
  function index (line 1141) | fn index(&self, index: usize) -> &Self::Output {
  function index_mut (line 1147) | fn index_mut(&mut self, index: usize) -> &mut Self::Output {
  type Output (line 1153) | type Output = SmallVec<[G; 4]>;
  method into_items (line 1155) | fn into_items(self) -> Self::Output {
  type IntoIter (line 1161) | type IntoIter = <SmallVec<[G; 4]> as IntoIterator>::IntoIter;
  type Item (line 1162) | type Item = G;
  method into_iter (line 1164) | fn into_iter(self) -> Self::IntoIter {
  type Output (line 1170) | type Output = UnboundedPolygon<U>;
  function map (line 1172) | fn map<F>(self, f: F) -> Self::Output
  type Static (line 1183) | type Static = (usize, Option<usize>);
  constant ARITY (line 1185) | const ARITY: Self::Static = (3, None);
  type Error (line 1207) | type Error = ();
  function try_from_iter (line 1209) | fn try_from_iter<I>(vertices: I) -> Result<Self, Self::Error>
  function zip_vertices (line 1259) | pub fn zip_vertices<T, U>(
  function angles (line 1284) | fn angles<P>(polygon: &P) -> impl '_ + Clone + Iterator<Item = Scalar<Po...
  function umod (line 1317) | fn umod<T>(n: T, m: T) -> T
  type E2 (line 1332) | type E2 = Point2<f64>;
  function convexity (line 1335) | fn convexity() {

FILE: plexus/src/primitive/sphere.rs
  type Bounds (line 44) | pub struct Bounds<S>
  function with_radius (line 55) | pub fn with_radius(radius: Scalar<S>) -> Self {
  function with_width (line 59) | pub fn with_width(width: Scalar<S>) -> Self {
  function unit_radius (line 63) | pub fn unit_radius() -> Self {
  function unit_width (line 67) | pub fn unit_width() -> Self {
  method default (line 76) | fn default() -> Self {
  type UvSphere (line 82) | pub struct UvSphere {
    method new (line 88) | pub fn new(nu: usize, nv: usize) -> Self {
    method vertex_with_position_from (line 95) | fn vertex_with_position_from<S>(
    method index_for_position (line 117) | fn index_for_position(&self, u: usize, v: usize) -> usize {
    method map_polygon_index (line 129) | fn map_polygon_index(&self, index: usize) -> (usize, usize) {
    type State (line 150) | type State = ();
    type Output (line 158) | type Output = Unit<Vector<S>>;
    method vertex_count (line 160) | fn vertex_count(&self) -> usize {
    method vertex_from (line 164) | fn vertex_from(&self, _: &Self::State, index: usize) -> Self::Output {
    type Output (line 176) | type Output = BoundedPolygon<Unit<Vector<S>>>;
    method polygon_from (line 178) | fn polygon_from(&self, _: &Self::State, index: usize) -> Self::Output {
    type Output (line 187) | type Output = BoundedPolygon<usize>;
    method indexing_polygon (line 189) | fn indexing_polygon(&self, index: usize) -> Self::Output {
    type State (line 198) | type State = Bounds<S>;
    type Output (line 206) | type Output = S;
    method vertex_count (line 208) | fn vertex_count(&self) -> usize {
    method vertex_from (line 212) | fn vertex_from(&self, state: &Self::State, index: usize) -> Self::Outp...
    type Output (line 232) | type Output = BoundedPolygon<S>;
    method polygon_from (line 234) | fn polygon_from(&self, state: &Self::State, index: usize) -> Self::Out...
    type Output (line 287) | type Output = BoundedPolygon<usize>;
    method indexing_polygon (line 289) | fn indexing_polygon(&self, index: usize) -> Self::Output {
  method default (line 135) | fn default() -> Self {
  method polygon_count (line 141) | fn polygon_count(&self) -> usize {
  function into_scalar (line 315) | fn into_scalar<T, S>(value: T) -> Scalar<S>
  type E3 (line 332) | type E3 = Point3<f64>;
  function vertex_count (line 335) | fn vertex_count() {
  function polygon_vertex_count (line 345) | fn polygon_vertex_count() {
  function position_index_to_vertex_mapping (line 356) | fn position_index_to_vertex_mapping() {

FILE: plexus/src/transact.rs
  type Transact (line 4) | pub trait Transact<T = ()>: Sized {
    method commit (line 9) | fn commit(self) -> Result<Self::Commit, (Self::Abort, Self::Error)>;
    method commit_with (line 14) | fn commit_with<F, U, E>(mut self, f: F) -> Result<(Self::Commit, U), (...
    method abort (line 25) | fn abort(self) -> Self::Abort;
  type Bypass (line 28) | pub trait Bypass<T>: Transact<T> {
    method bypass (line 29) | fn bypass(self) -> Self::Commit;
  type BypassOrCommit (line 32) | pub trait BypassOrCommit<T>: Bypass<T> {
    method bypass_or_commit (line 33) | fn bypass_or_commit(self) -> Result<Self::Commit, (Self::Abort, Self::...
    method bypass_or_commit_with (line 38) | fn bypass_or_commit_with<F, X, E>(
  method bypass_or_commit (line 52) | fn bypass_or_commit(self) -> Result<T::Commit, (T::Abort, T::Error)> {
  method bypass_or_commit_with (line 56) | fn bypass_or_commit_with<F, X, E>(self, f: F) -> Result<(T::Commit, X), ...
  method bypass_or_commit (line 70) | fn bypass_or_commit(self) -> Result<T::Commit, (T::Abort, T::Error)> {
  method bypass_or_commit_with (line 74) | fn bypass_or_commit_with<F, X, E>(
  type Mutate (line 89) | pub trait Mutate<T>: Transact<T, Commit = T> {
    method replace (line 90) | fn replace(target: &mut T, replacement: T) -> Swapped<T, Self>
    method take (line 97) | fn take(target: &mut T) -> Swapped<T, Self>
  type ClosedInput (line 108) | pub trait ClosedInput: Transact<<Self as ClosedInput>::Input> {
  type Drain (line 112) | trait Drain<T> {
    method as_option_mut (line 113) | fn as_option_mut(&mut self) -> &mut Option<T>;
    method drain (line 115) | fn drain(&mut self) -> T {
    method undrain (line 119) | fn undrain(&mut self, value: T) {
    method try_swap_or (line 129) | fn try_swap_or<F, U, E>(&mut self, value: T, mut f: F) -> Result<U, E>
  type Swapped (line 146) | pub struct Swapped<'a, T, M>
  function replace (line 157) | pub fn replace(target: &'a mut T, replacement: T) -> Self {
  function take (line 164) | pub fn take(target: &'a mut T) -> Self
  function drain_and_commit (line 171) | fn drain_and_commit(
  function drain_and_abort (line 184) | fn drain_and_abort(&mut self) -> &'a mut T {
  function drain_and_bypass (line 195) | pub fn drain_and_bypass(&mut self) -> &'a mut T {
  function as_ref (line 206) | fn as_ref(&self) -> &M {
  function as_mut (line 215) | fn as_mut(&mut self) -> &mut M {
  function bypass (line 224) | fn bypass(mut self) -> Self::Commit {
  function as_option_mut (line 235) | fn as_option_mut(&mut self) -> &mut Option<(&'a mut T, M)> {
  method drop (line 244) | fn drop(&mut self) {
  function from (line 254) | fn from(target: &'a mut T) -> Self {
  type Commit (line 263) | type Commit = &'a mut T;
  type Abort (line 264) | type Abort = &'a mut T;
  type Error (line 265) | type Error = <M as Transact<T>>::Error;
  function commit (line 267) | fn commit(mut self) -> Result<Self::Commit, (Self::Abort, Self::Error)> {
  function abort (line 273) | fn abort(mut self) -> Self::Abort {
Condensed preview — 73 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (685K chars).
[
  {
    "path": ".github/dependabot.yml",
    "chars": 110,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"cargo\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n"
  },
  {
    "path": ".github/workflows/continuous-integration.yml",
    "chars": 1622,
    "preview": "name: CI\non: [pull_request, push]\njobs:\n  rustfmt:\n    name: Format\n    runs-on: ubuntu-latest\n    steps:\n      - uses: "
  },
  {
    "path": ".gitignore",
    "chars": 43,
    "preview": ".idea/\ntarget/\n**/*.rs.bk\n*.iml\nCargo.lock\n"
  },
  {
    "path": "Cargo.toml",
    "chars": 141,
    "preview": "[workspace]\nmembers = [\n    \"examples/sphere\",\n    \"examples/subdivide\",\n    \"examples/teapot\",\n    \"pictor\",\n    \"plexu"
  },
  {
    "path": "LICENSE",
    "chars": 1046,
    "preview": "The MIT License (MIT)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and"
  },
  {
    "path": "README.md",
    "chars": 6849,
    "preview": "<div align=\"center\">\n    <img alt=\"Plexus\" src=\"https://raw.githubusercontent.com/olson-sean-k/plexus/master/doc/plexus."
  },
  {
    "path": "benches/subdivide.rs",
    "chars": 2185,
    "preview": "use criterion::{criterion_group, criterion_main, BatchSize, Criterion};\nuse nalgebra::Point3;\nuse plexus::geometry::AsPo"
  },
  {
    "path": "data/cube.ply",
    "chars": 263,
    "preview": "ply\nformat ascii 1.0\nelement vertex 8\nproperty float x\nproperty float y\nproperty float z\nelement face 6\nproperty list ui"
  },
  {
    "path": "data/plexus.ply",
    "chars": 1182,
    "preview": "ply\nformat ascii 1.0\ncomment 0 1 3 4 5 10 12 14 20 21 27 28 35 36 43 44 53 54\nelement vertex 55\nproperty float x\npropert"
  },
  {
    "path": "data/teapot.ply",
    "chars": 59698,
    "preview": "ply\nformat ascii 1.0\nelement vertex 1177\nproperty float32 x\nproperty float32 y\nproperty float32 z\nelement face 2256\nprop"
  },
  {
    "path": "doc/katex-header.html",
    "chars": 1040,
    "preview": "<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css\" integrity=\"sha384-zB1R0rpPzHq"
  },
  {
    "path": "examples/sphere/Cargo.toml",
    "chars": 380,
    "preview": "[package]\nname = \"example-sphere\"\nversion = \"0.0.0\"\nedition = \"2021\"\nauthors = [\"Sean Olson <olson.sean.k@gmail.com>\"]\nl"
  },
  {
    "path": "examples/sphere/src/main.rs",
    "chars": 886,
    "preview": "use nalgebra::Point3;\nuse pictor::pipeline::{self, Vertex};\nuse plexus::prelude::*;\nuse plexus::primitive;\nuse plexus::p"
  },
  {
    "path": "examples/subdivide/Cargo.toml",
    "chars": 376,
    "preview": "[package]\nname = \"example-subdivide\"\nversion = \"0.0.0\"\nedition = \"2021\"\nauthors = [\"Sean Olson <olson.sean.k@gmail.com>\""
  },
  {
    "path": "examples/subdivide/src/main.rs",
    "chars": 2478,
    "preview": "use nalgebra::Point3;\nuse pictor::pipeline::{self, Vertex};\nuse plexus::geometry::AsPositionMut;\nuse plexus::graph::{Clo"
  },
  {
    "path": "examples/teapot/Cargo.toml",
    "chars": 380,
    "preview": "[package]\nname = \"example-teapot\"\nversion = \"0.0.0\"\nedition = \"2021\"\nauthors = [\"Sean Olson <olson.sean.k@gmail.com>\"]\nl"
  },
  {
    "path": "examples/teapot/src/main.rs",
    "chars": 985,
    "preview": "use nalgebra::Point3;\nuse pictor::pipeline::{self, Vertex};\nuse plexus::encoding::ply::{FromPly, PositionEncoding};\nuse "
  },
  {
    "path": "pictor/Cargo.toml",
    "chars": 666,
    "preview": "[package]\nname = \"pictor\"\nversion = \"0.0.0\"\nedition = \"2021\"\nrust-version = \"1.81.0\"\nauthors = [\"Sean Olson <olson.sean."
  },
  {
    "path": "pictor/src/camera.rs",
    "chars": 2467,
    "preview": "use nalgebra::{Isometry3, Matrix4, Orthographic3, Perspective3, Point3, Vector3};\nuse std::sync::LazyLock;\nuse wgpu::Sur"
  },
  {
    "path": "pictor/src/harness.rs",
    "chars": 5113,
    "preview": "use futures::executor::{self, LocalPool, LocalSpawner};\nuse futures::task::LocalSpawn;\nuse std::cmp;\nuse std::fmt::Debug"
  },
  {
    "path": "pictor/src/lib.rs",
    "chars": 199,
    "preview": "mod camera;\nmod harness;\npub mod pipeline;\nmod renderer;\n\npub use crate::camera::*;\npub use crate::harness::*;\n\n// TODO:"
  },
  {
    "path": "pictor/src/pipeline.rs",
    "chars": 14920,
    "preview": "use bytemuck::{self, Pod, Zeroable};\nuse decorum::cmp::CanonicalEq;\nuse decorum::hash::CanonicalHash;\nuse futures::task:"
  },
  {
    "path": "pictor/src/renderer.rs",
    "chars": 2335,
    "preview": "use std::borrow::Borrow;\nuse winit::window::Window;\n\nuse crate::harness::{ConfigureStage, RenderStage};\n\n#[derive(Debug)"
  },
  {
    "path": "pictor/src/shader.glsl.frag",
    "chars": 136,
    "preview": "#version 450\n\nlayout(location = 0) in vec4 v_color;\n\nlayout(location = 0) out vec4 f_target0;\n\nvoid main() {\n    f_targe"
  },
  {
    "path": "pictor/src/shader.glsl.vert",
    "chars": 497,
    "preview": "#version 450\n\nlayout(location = 0) in vec4 a_position;\nlayout(location = 1) in vec4 a_normal;\nlayout(location = 2) in ve"
  },
  {
    "path": "plexus/Cargo.toml",
    "chars": 2341,
    "preview": "[package]\nname = \"plexus\"\nversion = \"0.0.11\"\nedition = \"2021\"\nrust-version = \"1.81.0\"\nauthors = [\"Sean Olson <olson.sean"
  },
  {
    "path": "plexus/src/buffer/builder.rs",
    "chars": 4765,
    "preview": "use num::{Integer, NumCast, Unsigned};\nuse std::hash::Hash;\nuse typenum::NonZero;\n\nuse crate::buffer::{BufferError, Mesh"
  },
  {
    "path": "plexus/src/buffer/mod.rs",
    "chars": 38974,
    "preview": "//! Linear representations of polygonal meshes.\n//!\n//! This module provides types and traits that describe polygonal me"
  },
  {
    "path": "plexus/src/builder.rs",
    "chars": 7741,
    "preview": "//! Incremental polygonal mesh construction.\n//!\n//! This module provides traits for incrementally constructing mesh dat"
  },
  {
    "path": "plexus/src/constant.rs",
    "chars": 1373,
    "preview": "//! Morphisms between constant generics and numeric types.\n//!\n//! This module provides conversions between `typenum`'s "
  },
  {
    "path": "plexus/src/encoding/mod.rs",
    "chars": 1635,
    "preview": "//! Serialization and encodings.\n//!\n//! This module provides encoding support enabled via Cargo features. Each\n//! enab"
  },
  {
    "path": "plexus/src/encoding/ply.rs",
    "chars": 12859,
    "preview": "//! [PLY] encoding.\n//!\n//! This module provides support for the [PLY] format via the [`FromPly`] and\n//! [`ToPly`] trai"
  },
  {
    "path": "plexus/src/entity/borrow.rs",
    "chars": 838,
    "preview": "pub trait Reborrow {\n    type Target;\n\n    fn reborrow(&self) -> &Self::Target;\n}\n\npub trait ReborrowMut: Reborrow {\n   "
  },
  {
    "path": "plexus/src/entity/dijkstra.rs",
    "chars": 5424,
    "preview": "use derivative::Derivative;\nuse std::cmp::Reverse;\nuse std::collections::hash_map::Entry;\nuse std::collections::{BinaryH"
  },
  {
    "path": "plexus/src/entity/mod.rs",
    "chars": 572,
    "preview": "pub mod borrow;\npub mod dijkstra;\npub mod storage;\npub mod traverse;\npub mod view;\n\nuse thiserror::Error;\n\nuse crate::en"
  },
  {
    "path": "plexus/src/entity/storage/hash.rs",
    "chars": 5285,
    "preview": "use ahash::AHashMap;\nuse std::hash::Hash;\nuse std::marker::PhantomData;\n\nuse crate::entity::storage::{\n    AsStorage, As"
  },
  {
    "path": "plexus/src/entity/storage/mod.rs",
    "chars": 4602,
    "preview": "mod hash;\n\nuse std::hash::Hash;\n\nuse crate::entity::{Entity, Payload};\n\npub use crate::entity::storage::hash::HashStorag"
  },
  {
    "path": "plexus/src/entity/traverse.rs",
    "chars": 5730,
    "preview": "use std::collections::{HashSet, VecDeque};\nuse std::hash::Hash;\nuse std::marker::PhantomData;\n\nuse crate::entity::borrow"
  },
  {
    "path": "plexus/src/entity/view.rs",
    "chars": 8589,
    "preview": "use std::hash::{Hash, Hasher};\nuse std::ops::{Deref, DerefMut};\n\nuse crate::entity::borrow::{Reborrow, ReborrowInto, Reb"
  },
  {
    "path": "plexus/src/geometry/mod.rs",
    "chars": 2369,
    "preview": "//! Geometric traits and computational geometry.\n//!\n//! Plexus uses the [`theon`] crate to abstract over types that rep"
  },
  {
    "path": "plexus/src/geometry/partition.rs",
    "chars": 2247,
    "preview": "use approx::abs_diff_eq;\nuse num::traits::real::Real;\nuse num::Zero;\nuse std::cmp::Ordering;\nuse theon::query::{Line, Pl"
  },
  {
    "path": "plexus/src/graph/builder.rs",
    "chars": 2720,
    "preview": "use crate::builder::{FacetBuilder, MeshBuilder, SurfaceBuilder};\nuse crate::geometry::{FromGeometry, IntoGeometry};\nuse "
  },
  {
    "path": "plexus/src/graph/core.rs",
    "chars": 6623,
    "preview": "use std::marker::PhantomData;\n\nuse crate::entity::storage::{AsStorage, AsStorageMut, Fuse, StorageTarget};\nuse crate::en"
  },
  {
    "path": "plexus/src/graph/data.rs",
    "chars": 2839,
    "preview": "use crate::entity::borrow::Reborrow;\n\npub type Data<M> = <M as Parametric>::Data;\n\n/// Graph data.\n///\n/// Specifies the"
  },
  {
    "path": "plexus/src/graph/edge.rs",
    "chars": 51912,
    "preview": "use arrayvec::ArrayVec;\nuse derivative::Derivative;\nuse std::borrow::Borrow;\nuse std::hash::{Hash, Hasher};\nuse std::ops"
  },
  {
    "path": "plexus/src/graph/face.rs",
    "chars": 58180,
    "preview": "use derivative::Derivative;\nuse smallvec::SmallVec;\nuse std::borrow::Borrow;\nuse std::cmp;\nuse std::collections::HashSet"
  },
  {
    "path": "plexus/src/graph/geometry.rs",
    "chars": 9294,
    "preview": "//! Geometric graph traits.\n\n// Geometric traits like `FaceNormal` and `EdgeMidpoint` are defined in such a\n// way to re"
  },
  {
    "path": "plexus/src/graph/mod.rs",
    "chars": 61478,
    "preview": "//! Half-edge graph representation of polygonal meshes.\n//!\n//! This module provides a flexible representation of polygo"
  },
  {
    "path": "plexus/src/graph/mutation/edge.rs",
    "chars": 20299,
    "preview": "use std::ops::{Deref, DerefMut};\n\nuse crate::entity::borrow::Reborrow;\nuse crate::entity::storage::prelude::*;\nuse crate"
  },
  {
    "path": "plexus/src/graph/mutation/face.rs",
    "chars": 21264,
    "preview": "use smallvec::SmallVec;\nuse std::borrow::Borrow;\nuse std::collections::{HashMap, HashSet};\nuse std::ops::{Deref, DerefMu"
  },
  {
    "path": "plexus/src/graph/mutation/mod.rs",
    "chars": 6307,
    "preview": "pub mod edge;\npub mod face;\npub mod path;\npub mod vertex;\n\nuse std::marker::PhantomData;\nuse std::ops::{Deref, DerefMut}"
  },
  {
    "path": "plexus/src/graph/mutation/path.rs",
    "chars": 2190,
    "preview": "use smallvec::SmallVec;\n\nuse crate::entity::borrow::Reborrow;\nuse crate::entity::storage::AsStorage;\nuse crate::entity::"
  },
  {
    "path": "plexus/src/graph/mutation/vertex.rs",
    "chars": 3957,
    "preview": "use crate::entity::borrow::Reborrow;\nuse crate::entity::storage::prelude::*;\nuse crate::entity::storage::{AsStorage, AsS"
  },
  {
    "path": "plexus/src/graph/path.rs",
    "chars": 21247,
    "preview": "use itertools::Itertools;\nuse std::borrow::{Borrow, Cow};\nuse std::cmp;\nuse std::collections::{HashSet, VecDeque};\n\nuse "
  },
  {
    "path": "plexus/src/graph/vertex.rs",
    "chars": 33690,
    "preview": "use derivative::Derivative;\nuse smallvec::SmallVec;\nuse std::borrow::Borrow;\nuse std::hash::{Hash, Hasher};\nuse std::ops"
  },
  {
    "path": "plexus/src/index.rs",
    "chars": 21771,
    "preview": "//! Indexing and aggregation.\n//!\n//! This module provides types and traits that describe _index buffers_ and\n//! _index"
  },
  {
    "path": "plexus/src/integration/cgmath.rs",
    "chars": 4181,
    "preview": "#![cfg(feature = \"geometry-cgmath\")]\n\nuse cgmath::{Point2, Point3, Vector2, Vector3};\nuse decorum::{ExtendedReal, Primit"
  },
  {
    "path": "plexus/src/integration/glam.rs",
    "chars": 978,
    "preview": "#![cfg(feature = \"geometry-glam\")]\n\nuse glam::{Vec2, Vec3, Vec3A};\n\nuse crate::geometry::{FromGeometry, UnitGeometry};\nu"
  },
  {
    "path": "plexus/src/integration/mint.rs",
    "chars": 6007,
    "preview": "#![cfg(feature = \"geometry-mint\")]\n\nuse decorum::{ExtendedReal, Primitive, Real, Total};\nuse mint::{Point2, Point3, Vect"
  },
  {
    "path": "plexus/src/integration/mod.rs",
    "chars": 323,
    "preview": "//! Integration of external crates and foreign types.\n//!\n//! This module provides implementations of traits in Plexus f"
  },
  {
    "path": "plexus/src/integration/nalgebra.rs",
    "chars": 4816,
    "preview": "#![cfg(feature = \"geometry-nalgebra\")]\n\nuse decorum::{ExtendedReal, Primitive, Real, Total};\nuse nalgebra::base::allocat"
  },
  {
    "path": "plexus/src/integration/ultraviolet.rs",
    "chars": 708,
    "preview": "#![cfg(feature = \"geometry-ultraviolet\")]\n\nuse ultraviolet::vec::{Vec2, Vec3};\n\nuse crate::geometry::{FromGeometry, Unit"
  },
  {
    "path": "plexus/src/lib.rs",
    "chars": 16159,
    "preview": "//! **Plexus** is a highly composable library for polygonal mesh processing.\n//!\n//! Versions of Plexus in the `0.0.*` s"
  },
  {
    "path": "plexus/src/primitive/cube.rs",
    "chars": 7015,
    "preview": "//! Cube primitives.\n//!\n//! # Examples\n//!\n//! ```rust\n//! # extern crate decorum;\n//! # extern crate nalgebra;\n//! # e"
  },
  {
    "path": "plexus/src/primitive/decompose.rs",
    "chars": 12548,
    "preview": "//! Decomposition and tessellation.\n//!\n//! The [`Decompose`] iterator uses various traits to decompose and tessellate\n/"
  },
  {
    "path": "plexus/src/primitive/generate.rs",
    "chars": 10772,
    "preview": "//! Polytope generation.\n//!\n//! This module provides a generic iterator and traits for generating polygons\n//! and vert"
  },
  {
    "path": "plexus/src/primitive/mod.rs",
    "chars": 39928,
    "preview": "//! Primitive topological structures.\n//!\n//! This module provides composable primitives that describe polygonal\n//! str"
  },
  {
    "path": "plexus/src/primitive/sphere.rs",
    "chars": 10174,
    "preview": "//! Sphere primitives.\n//!\n//! # Examples\n//!\n//! Generating a graph from the positional data of a $uv$-sphere.\n//!\n//! "
  },
  {
    "path": "plexus/src/transact.rs",
    "chars": 6560,
    "preview": "use std::fmt::Debug;\nuse std::mem;\n\npub trait Transact<T = ()>: Sized {\n    type Commit;\n    type Abort;\n    type Error:"
  },
  {
    "path": "rustdoc.sh",
    "chars": 370,
    "preview": "#! /usr/bin/env bash\n\n# TODO: This script sets the `RUSTDOCFLAGS` environment variable to configure\n#       the KaTeX he"
  },
  {
    "path": "rustfmt.toml",
    "chars": 75,
    "preview": "control_brace_style = \"ClosingNextLine\"\nformat_code_in_doc_comments = true\n"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the olson-sean-k/plexus GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 73 files (640.4 KB), approximately 197.6k tokens, and a symbol index with 1716 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!