fj_kernel/objects/mod.rs
1//! Objects of a shape
2//!
3//! Objects, in Fornjot parlance, are the elements that make up shapes. An
4//! object can be simple and just contain data (like [`Vertex`], for example),
5//! or they can be quite complex and refer to other objects (which is actually
6//! most of them).
7//!
8//! # Object Identity vs Object Equality
9//!
10//! Two objects are *equal*, if they contain the same data. For example, two
11//! instances of [`Vertex`] are equal, if they have the same position. This
12//! doesn't mean those objects are *identical*. They might have been created by
13//! different pieces of code. Or maybe by the same piece of code, but at
14//! different times, maybe even based on different inputs.
15//!
16//! This distinction is relevant, because non-identical objects that are
17//! *supposed* to be equal can end up being equal, if they are created based on
18//! simple input data (as you might have in a unit test). But they might end up
19//! slightly different, if they are created based on complex input data (as you
20//! might have in the real world).
21//!
22//! ## An Example
23//!
24//! Let's talk about a specific example: two simple curves (straight lines that
25//! are coincident with coordinate system axes) which are intersecting at a
26//! simple point. Let's say the intersection point sits at the global origin
27//! (`[0, 0, 0]`), and its local coordinate on each line also happens to be `0`.
28//!
29//! If you compute the global coordinates from each of the line-local
30//! coordinates, you'll end up with the same result for sure. If we create two
31//! [`Vertex`] instances from these global coordinates, any validation code that
32//! expects those two instances to be equal, will be happy.
33//!
34//! But what if the situation is not so simple? Let's say the curves are circles
35//! instead of lines, and instead of being all neat, they are at some arbitrary
36//! location in space, oriented at weird angles. The local coordinates of their
37//! intersection point are not `0`, but different values that are not neatly
38//! represented by floating point values.
39//!
40//! In such a situation, you have an excellent chance of ending up with slightly
41//! different global coordinates, if you compute them from each local
42//! coordinate. If you're building a [`Cycle`], and this intersection point is
43//! where the two curves connect, you could end up with a gap (or self-
44//! intersection) in the cycle. If that ends up exported to a triangle mesh,
45//! that mesh will be invalid.
46//!
47//! ## Validation Must Use Identity
48//!
49//! To prevent such situations, where everything looked fine during development,
50//! but you end up with a bug in production, any validation code that compares
51//! objects and expects them to be the same, must do that comparison based on
52//! identity, not equality. That way, this problem can never happen, because we
53//! never expect non-identical objects to be the same.
54//!
55//! For our example, this would mean we compute *one* [`Vertex`] from *one* of
56//! the local coordinates.
57//!
58//! ## How Identity Works
59//!
60//! We can exactly determine the identity of an object, thanks to [centralized
61//! object storage][`Objects`]. If objects are created at different times,
62//! potentially by different code, they end up being stored at different memory
63//! locations, regardless of their (non-)equality.
64//!
65//! If you have two [`Handle`]s, you can compare the identity of the objects
66//! they point to using the `id` method.
67//!
68//! ## Implementation Note
69//!
70//! As of this writing, most objects are not managed in the centralized object
71//! storage. Changing this is an ongoing effort ([#1021]).
72//!
73//! [`Handle`]: crate::storage::Handle
74//! [#1021]: https://github.com/hannobraun/Fornjot/issues/1021
75
76mod full;
77mod object;
78mod set;
79mod stores;
80
81pub use self::{
82 full::{
83 cycle::{Cycle, HalfEdgesOfCycle},
84 edge::{GlobalEdge, HalfEdge},
85 face::{Face, FaceSet, Handedness},
86 shell::Shell,
87 sketch::Sketch,
88 solid::Solid,
89 surface::Surface,
90 vertex::Vertex,
91 },
92 object::{Bare, BehindHandle, Form, Object, WithHandle},
93 set::ObjectSet,
94 stores::{Objects, Surfaces},
95};