Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation of Vertex #2101

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 69 additions & 15 deletions crates/fj-core/src/objects/kinds/vertex.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,71 @@
/// A vertex, defined in global (3D) coordinates
/// # A vertex that identifies a point in space
///
/// This struct exists to distinguish between vertices and points at the type
/// level. This is a relevant distinction, as vertices are part of a shape that
/// help define its topology.
/// ## Purpose
///
/// Points, on the other hand, might be used to approximate a shape for various
/// purposes, without presenting any deeper truth about the shape's structure.
/// 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.
///
/// # Validation
/// 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.
///
/// Vertices must be unique within a shape, meaning an identical vertex must not
/// exist in the same shape. In the context of vertex uniqueness, points that
/// are close to each other are considered identical. The minimum distance
/// between distinct vertices can be configured using the respective field in
/// [`ValidationConfig`].
/// 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.
///
/// # Equality
/// 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 used within a `Handle`,
/// where `Handle::id` can be used to compare different instances of `Vertex`.
Expand All @@ -28,12 +78,16 @@
/// `Eq`/`Ord`/..., you can use `HandleWrapper<Vertex>` to do that. It will
/// use `Handle::id` to provide those `Eq`/`Ord`/... implementations.
///
/// [`ValidationConfig`]: crate::validate::ValidationConfig
/// [`HalfEdge`]: crate::objects::HalfEdge
/// [`Handle`]: crate::storage::Handle
/// [`Sketch`]: crate::objects::Sketch
/// [`Solid`]: crate::objects::Solid
/// [`Surface`]: crate::objects::Surface
#[derive(Clone, Copy, Debug, Default, Hash)]
pub struct Vertex {}

impl Vertex {
/// Construct a `Vertex` from a position
/// Construct a `Vertex`
pub fn new() -> Self {
Self::default()
}
Expand Down