1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
//! Half-edge graph representation of meshes.
//!
//! This module provides a flexible representation of meshes as a [half-edge
//! graph](https://en.wikipedia.org/wiki/doubly_connected_edge_list). Meshes
//! can store arbitrary geometric data associated with any topological
//! structure, including vertices, half-edges, and faces.
//!
//! # Representation
//!
//! `Mesh`es store topological data using associative collections. Keys are
//! exposed as strongly typed and opaque values, which can be used to refer to
//! a topological structure, such as `VertexKey`. Topology is typically
//! manipulated using a view.
//!
//! A `Mesh` is conceptually composed of vertices, half-edges, and faces.
//! Half-edges are directed and join vertices. Every half-edge is paired with
//! an opposite half-edge with the opposite direction. Given a half-edge that
//! connects a vertex `a` to a vertex `b`, that half-edge will have an opposite
//! half-edge from `b` to `a`. Together, these half-edges form a composite
//! edge. When the term "edge" is used alone, it generally refers to a
//! half-edge.
//!
//! Half-edges are connected to their neighbors, known as "next" and "previous"
//! half-edges. When a face is present in the region formed by a perimeter of
//! vertices and their half-edges, the half-edges will refer to that face and
//! the face will refer to one of the half-edges in the interior circuit.
//!
//! Together with vertices and faces, the connectivity of half-edges allows for
//! effecient traversal of topology. For example, it becomes trivial to find
//! neighboring topologies, such as the faces that share a given vertex or the
//! neighboring faces of a given face.
//!
//! # Topological Views
//!
//! `Mesh`es expose views over their topological structures (vertices, edges,
//! and faces). Views are accessed via keys or iteration and behave similarly
//! to references. They provide the primary API for interacting with a mesh's
//! topology and geometry. There are three types summarized below:
//!
//! | Type | Traversal | Exclusive | Geometry | Topology |
//! |-----------|-----------|-----------|-----------|-----------|
//! | Immutable | Yes | No | Immutable | Immutable |
//! | Mutable | Yes | Yes | Mutable | Mutable |
//! | Orphan | No | No | Mutable | N/A |
//!
//! Immutable and mutable views are much like references. Immutable views
//! cannot mutate a mesh in any way and it is possible to obtain multiple such
//! views at the same time. Mutable views are exclusive, but allow for
//! mutations.
//!
//! Orphan views are similar to mutable views, but they only have access to the
//! geometry of a specific topological structure in a mesh. Because they do not
//! know about other vertices, edges, or faces, an orphan view cannot traverse
//! the topology of a mesh in any way. These views are most useful for
//! modifying the geometry of a mesh and, unlike mutable views, multiple orphan
//! views can be obtained at the same time. Orphan views are mostly used by
//! circulators (iterators).
//!
//! Immutable and mutable views are represented by a single type constructor,
//! such as `FaceView`. Orphan views are represented by their own type, such
//! as `OrphanFace`.
//!
//! # Circulators
//!
//! Topological views allow for traversals of a mesh's topology. One useful
//! type of traversal uses a circulator, which is a type of iterator that
//! examines the neighbors of a topological structure. For example, the face
//! circulator of a vertex yields all faces that share that vertex in order.
//!
//! Mutable circulators emit orphan views, not mutable views. This is because
//! it is not possible to instantiate more than one mutable view at a time. If
//! multiple mutable views are needed, it is possible to use an immutable
//! circulator to collect the keys of the target topology and then lookup each
//! mutable view using those keys.
//!
//! # Examples
//!
//! Generating a mesh from a primitive:
//!
//! ```rust
//! # extern crate nalgebra;
//! # extern crate plexus;
//! use nalgebra::Point3;
//! use plexus::graph::Mesh;
//! use plexus::prelude::*;
//! use plexus::primitive::sphere::UvSphere;
//!
//! # fn main() {
//! let mut mesh = UvSphere::new(16, 16)
//! .polygons_with_position()
//! .collect::<Mesh<Point3<f32>>>();
//! # }
//! ```
//!
//! Manipulating a face in a mesh:
//!
//! ```rust
//! # extern crate nalgebra;
//! # extern crate plexus;
//! use nalgebra::Point3;
//! use plexus::graph::Mesh;
//! use plexus::prelude::*;
//! use plexus::primitive::sphere::UvSphere;
//!
//! # fn main() {
//! let mut mesh = UvSphere::new(16, 16)
//! .polygons_with_position()
//! .collect::<Mesh<Point3<f32>>>();
//! let key = mesh.faces().nth(0).unwrap().key(); // Get the key of the first face.
//! mesh.face_mut(key).unwrap().extrude(1.0).unwrap(); // Extrude the face.
//! # }
//! ```
//!
//! Traversing and circulating over a mesh:
//!
//! ```rust
//! # extern crate nalgebra;
//! # extern crate plexus;
//! use nalgebra::Point2;
//! use plexus::graph::Mesh;
//! use plexus::prelude::*;
//!
//! # fn main() {
//! let mut mesh = Mesh::<Point2<f32>>::from_raw_buffers(
//! vec![0, 1, 2, 3],
//! vec![(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)],
//! 4,
//! ).unwrap();
//! mesh.triangulate().unwrap();
//!
//! // Traverse an edge and use a circulator to get the faces of a nearby vertex.
//! let key = mesh.edges().nth(0).unwrap().key();
//! let mut vertex = mesh
//! .edge_mut(key)
//! .unwrap()
//! .into_opposite_edge()
//! .into_next_edge()
//! .into_destination_vertex();
//! for face in vertex.neighboring_orphan_faces() {
//! // `face.geometry` is mutable here.
//! }
//! # }
//! ```
use Error;
pub use Mesh;
pub use ;
// TODO: It's unclear how view types should be exposed to users. Type aliases
// for mutable, immutable, and orphan views over a `Mesh` would be
// simpler and help insulate users from the complexity of views, but it
// is currently not possible to document such aliases. See:
// https://github.com/rust-lang/rust/issues/39437
//
// Moreover, in the future it may be tenable to expose the internal
// mutation APIs, and exposing the underlying view types would then be
// necessary. For now, use them directly.
pub use ;
// TODO: Using `Error` so broadly is a misuse case. Look at how complex
// `ResultExt` is! Just use `GraphError` directly. Never use `Error`
// along "happy" or "expected" paths (this happens often in the
// `mutation` module.