fj_core/objects/kinds/vertex.rs
1/// # A vertex that identifies a point in space
2///
3/// ## Purpose
4///
5/// Vertices are referenced by [`HalfEdge`]s. They are topological objects,
6/// which means that their purpose is to define how parts of a shape relate to
7/// each other. They *identify* a point in space, but they do not define its
8/// position.
9///
10/// In fact, this struct does not contain any data at all which could define
11/// anything. As such, [`Vertex`] is solely intended to be used through a
12/// [`Handle`], which provides the vertex with a unique identity, allowing it
13/// to do its job.
14///
15/// Having a unique identity for a point in space is very valuable, as we can't
16/// just rely on the value of points to compare them. If two half-edges connect,
17/// we expect them to connect at a single point, not two points that are very
18/// close to each other.
19///
20/// Due to the realities of computing (and specifically, the realities of
21/// computing floating-point numbers), we might very well end up *thinking* that
22/// our code computed a single point, when in fact it does not, which only shows
23/// up outside of our testing environment. This can be a pervasive source of
24/// bugs, if left unchecked.
25///
26/// With [`Vertex`], we can provide a unique identity to each point where it is
27/// computed. This allows [validation code](crate::validate) to exist, which can
28/// identify where our code generates multiple distinct points that might end up
29/// in slightly different positions in a real-life scenario.
30///
31///
32/// ## Positions
33///
34/// (Warning: If the following information is relevant to you, please double-
35/// check it by looking at the code that this section references. Everything
36/// here is true at the time of writing, but there are planned changes which
37/// could make this section obsolete.)
38///
39/// A vertex can exist in multiple distinct spaces, and can thus have multiple
40/// positions. Those positions are defined by the objects that reference the
41/// vertex. How exactly that happens depends on the overall shape.
42///
43/// If the shape is defined by a [`Sketch`], it is 2D-only. The (2D) position of
44/// the vertex will then be defined by the half-edges that reference it.
45/// Validation code can make sure that those redundant definitions don't result
46/// in wildly different values.
47///
48/// If the shape is defined by a [`Solid`], then it it 3-dimensional. The
49/// referencing half-edges still define the surface-local 2D positions of the
50/// vertex. Since such half-edges could meet in the same surface, or exist where
51/// multiple surfaces meet, these positions could end up being in one or more
52/// surfaces.
53///
54/// The corresponding [`Surface`] objects can then be used to convert those 2D
55/// positions into global 3D positions.
56///
57/// As you might have noted, in each case, we still have redundant definitions
58/// of the vertex position, and might end up with multiple values for the
59/// position that are not exactly equal. However, since we know these positions
60/// belong to the same vertex, this is not a problem.
61///
62/// Validation code can make sure that the actual values are very close
63/// together, and where we lose this identity information(when generating a
64/// triangle mesh for a file export, for example), we can choose exactly one of
65/// those values.
66///
67///
68/// ## Equality
69///
70/// `Vertex` contains no data and exists purely to be referenced via a `Handle`,
71/// where `Handle::id` can be used to compare different instances of it.
72///
73/// If `Vertex` had `Eq`/`PartialEq` implementations, it containing no data
74/// would mean that all instances of `Vertex` would be considered equal. This
75/// would be very error-prone.
76///
77/// If you need to reference a `Vertex` from a struct that needs to derive
78/// `Eq`/`Ord`/..., you can use `HandleWrapper<Vertex>` to do that. It will
79/// use `Handle::id` to provide those `Eq`/`Ord`/... implementations.
80///
81/// [`HalfEdge`]: crate::objects::HalfEdge
82/// [`Handle`]: crate::storage::Handle
83/// [`Sketch`]: crate::objects::Sketch
84/// [`Solid`]: crate::objects::Solid
85/// [`Surface`]: crate::objects::Surface
86#[derive(Clone, Copy, Debug, Default, Hash)]
87pub struct Vertex {}
88
89impl Vertex {
90 /// Construct a `Vertex`
91 pub fn new() -> Self {
92 Self::default()
93 }
94}