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
//! # Fornjot Core
//!
//! [Fornjot] is an early-stage b-rep CAD kernel written in Rust. The kernel is
//! split into multiple libraries that can be used semi-independently, and this
//! is one of those.
//!
//! This library defines geometric and topological primitives, and the
//! algorithms that operate on them.
//!
//!
//! ## Design Principle
//!
//! The CAD kernel follows the design principle of **robustness through
//! explicitness**. This means that geometrical relationships must be expressed
//! explicitly, or they are not accepted.
//!
//! This principle is not fully implemented yet. There are quite a few
//! validation checks that enforce part of it, but many are still missing.
//!
//! ### Motivation
//!
//! A problem that CAD kernels need to handle is the inherent fuzziness of
//! geometric relationships. Is a point on a curve, or just close to it? Does a
//! curve lie in a surface, or does it not? This is exacerbated by the limited
//! precision of numerical representations in computers, and especially the
//! inconvenient precision characteristics of floating-point numbers.
//!
//! These problems can be addressed by always comparing numbers using an epsilon
//! value. Numbers that are very close together (their difference is smaller
//! than epsilon) are considered equal.
//!
//! This approach has several problems:
//! - If the epsilon value is chosen too high, then very small models can become
//!   buggy, as distinct geometry is merged together.
//! - If the epsilon value is chosen too low, then very large models can become
//!   buggy, as geometry that is supposed to be identical is recognized as
//!   distinct.
//! - These epsilon comparisons need to be used everywhere where numbers are
//!   handled. It can be easy to forget this. Using custom wrapper types is
//!   possible, but either inflexible (because the epsilon value is hardcoded)
//!   or inconvenient (because the epsilon value needs to be provided).
//!
//! Choosing an epsilon value that is suitable for *most* use cases is possible,
//! at the cost of non-standard use cases breaking in unexpected and non-obvious
//! ways. Fornjot has chosen a different approach.
//!
//! ### Explicitness
//!
//! By requiring geometric relationships to be *explicit*, we don't have to use
//! error-prone heuristics to determine those relationships. That means, for
//! example, two vertices that happen to be identical, or very close to each
//! other, are not accepted.
//!
//! If vertex instances that refer to the same point are used in different
//! places (for example, in two neighboring edges that share a vertex), then
//! those vertex instances must be known by the system to refer to the same
//! vertex. If a vertex lies on an edge or in a surface, then it must be defined
//! in terms of its position on that edge or surface.
//!
//! This can have consequences for how users define models. For example, if the
//! user moves two shapes close to each other, so they touch but don't
//! intersect, this should lead to an error message, explaining to the user why
//! what they did is a problem, and teaching them how to define their model in
//! a different way, so the system knows the semantic relationships between
//! geometrical objects.
//!
//! ### Validation
//!
//! These rules of explicitness must be validated, so the user can know if there
//! is a problem in the model, and fix it. This is preferable to failing in
//! unexpected ways later on.
//!
//! For the comparisons required for validation, an epsilon value must be used.
//! This epsilon value can be derived from the size of the model, and should be
//! chosen as high as possible, so any potential problems can be immediately
//! reported as errors.
//!
//! If the user does something non-standard, they can override the epsilon value
//! on a per-shape basis. Forcing the user to deal with these issues up-front
//! should lead to less work overall.
//!
//! [Fornjot]: https://www.fornjot.app/

pub mod algorithms;
pub mod geometry;
pub mod layers;
pub mod objects;
pub mod operations;
pub mod presentation;
pub mod queries;
pub mod storage;
pub mod validate;
pub mod validation;

mod core;

pub use self::core::Core;