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
/// # A vertex that identifies a point in space
///
/// ## Purpose
///
/// Vertices are referenced by [`HalfEdge`]s. They are topological objects,
/// which means that their purpose is to define how parts of a shape relate to
/// each other. They *identify* a point in space, but they do not define its
/// position.
///
/// In fact, this struct does not contain any data at all which could define
/// anything. As such, [`Vertex`] is solely intended to be used through a
/// [`Handle`], which provides the vertex with a unique identity, allowing it
/// to do its job.
///
/// Having a unique identity for a point in space is very valuable, as we can't
/// just rely on the value of points to compare them. If two half-edges connect,
/// we expect them to connect at a single point, not two points that are very
/// close to each other.
///
/// Due to the realities of computing (and specifically, the realities of
/// computing floating-point numbers), we might very well end up *thinking* that
/// our code computed a single point, when in fact it does not, which only shows
/// up outside of our testing environment. This can be a pervasive source of
/// bugs, if left unchecked.
///
/// With [`Vertex`], we can provide a unique identity to each point where it is
/// computed. This allows [validation code](crate::validate) to exist, which can
/// identify where our code generates multiple distinct points that might end up
/// in slightly different positions in a real-life scenario.
///
///
/// ## Positions
///
/// (Warning: If the following information is relevant to you, please double-
/// check it by looking at the code that this section references. Everything
/// here is true at the time of writing, but there are planned changes which
/// could make this section obsolete.)
///
/// A vertex can exist in multiple distinct spaces, and can thus have multiple
/// positions. Those positions are defined by the objects that reference the
/// vertex. How exactly that happens depends on the overall shape.
///
/// If the shape is defined by a [`Sketch`], it is 2D-only. The (2D) position of
/// the vertex will then be defined by the half-edges that reference it.
/// Validation code can make sure that those redundant definitions don't result
/// in wildly different values.
///
/// If the shape is defined by a [`Solid`], then it it 3-dimensional. The
/// referencing half-edges still define the surface-local 2D positions of the
/// vertex. Since such half-edges could meet in the same surface, or exist where
/// multiple surfaces meet, these positions could end up being in one or more
/// surfaces.
///
/// The corresponding [`Surface`] objects can then be used to convert those 2D
/// positions into global 3D positions.
///
/// As you might have noted, in each case, we still have redundant definitions
/// of the vertex position, and might end up with multiple values for the
/// position that are not exactly equal. However, since we know these positions
/// belong to the same vertex, this is not a problem.
///
/// Validation code can make sure that the actual values are very close
/// together, and where we lose this identity information(when generating a
/// triangle mesh for a file export, for example), we can choose exactly one of
/// those values.
///
///
/// ## Equality
///
/// `Vertex` contains no data and exists purely to be referenced via a `Handle`,
/// where `Handle::id` can be used to compare different instances of it.
///
/// If `Vertex` had `Eq`/`PartialEq` implementations, it containing no data
/// would mean that all instances of `Vertex` would be considered equal. This
/// would be very error-prone.
///
/// If you need to reference a `Vertex` from a struct that needs to derive
/// `Eq`/`Ord`/..., you can use `HandleWrapper<Vertex>` to do that. It will
/// use `Handle::id` to provide those `Eq`/`Ord`/... implementations.
///
/// [`HalfEdge`]: crate::objects::HalfEdge
/// [`Handle`]: crate::storage::Handle
/// [`Sketch`]: crate::objects::Sketch
/// [`Solid`]: crate::objects::Solid
/// [`Surface`]: crate::objects::Surface