brepkit_operations/lib.rs
1//! # brepkit-operations
2//!
3//! CAD modeling operations for B-Rep solids. Layer L3, depending on
4//! `brepkit-math`, `brepkit-topology`, `brepkit-geometry`, `brepkit-algo`,
5//! `brepkit-blend`, `brepkit-heal`, `brepkit-check`, and `brepkit-offset`.
6//!
7//! # Module families
8//!
9//! | Family | Modules | Purpose |
10//! |--------|---------|---------|
11//! | **Core** | [`primitives`], [`extrude`], [`revolve`], [`sweep`], [`loft`], [`pipe`], [`helix`] | Shape creation |
12//! | **Transform** | [`transform`], [`copy`], [`mirror`], [`pattern`] | Spatial operations |
13//! | **Boolean** | [`boolean`], [`mesh_boolean`] | Set operations |
14//! | **Blend** | [`fillet`], [`chamfer`], [`blend_ops`] | Edge smoothing |
15//! | **Offset** | [`offset_face`], [`offset_trim`], [`offset_v2`], [`offset_wire`] | Wall thickness |
16//! | **Surface** | [`fill_face`], [`thicken`], [`shell_op`], [`draft`], [`section`], [`split`] | Surface/solid modification |
17//! | **Repair** | [`heal`], [`defeature`], [`sew`], [`untrim`] | Shape fixing |
18//! | **Analysis** | [`measure`], [`distance`], [`classify`], [`validate`], [`query`], [`feature_recognition`] | Interrogation |
19//! | **Tessellation** | [`tessellate`] | Mesh generation |
20//! | **Infrastructure** | [`assembly`], [`compound_ops`], [`evolution`], [`sketch`] | Utilities |
21
22use brepkit_math::vec::{Point3, Vec3};
23
24pub mod extrude;
25pub mod helix;
26pub mod loft;
27pub mod pipe;
28pub mod primitives;
29pub mod projection;
30pub mod revolve;
31pub mod sweep;
32
33pub mod copy;
34pub mod mirror;
35pub mod pattern;
36pub mod transform;
37
38pub mod boolean;
39pub mod mesh_boolean;
40
41pub mod blend_ops;
42pub mod chamfer;
43pub mod fillet;
44
45pub mod offset_face;
46pub mod offset_trim;
47pub mod offset_v2;
48pub mod offset_wire;
49
50pub mod draft;
51pub mod fill_face;
52pub mod section;
53pub mod shell_op;
54pub mod split;
55pub mod thicken;
56
57pub mod defeature;
58pub mod heal;
59pub mod sew;
60pub mod untrim;
61
62pub mod classify;
63pub mod distance;
64pub mod feature_recognition;
65pub mod measure;
66pub mod query;
67pub mod validate;
68
69pub mod tessellate;
70
71pub mod assembly;
72pub(crate) mod cap;
73pub mod compound_ops;
74pub mod evolution;
75pub mod sketch;
76pub(crate) mod winding;
77
78#[cfg(test)]
79pub(crate) mod test_helpers;
80
81/// Compute `n · p` treating a `Point3` as a direction vector.
82///
83/// Equivalent to the dot product `n.x*p.x + n.y*p.y + n.z*p.z`, used
84/// for the plane equation `n · point = d`.
85fn dot_normal_point(n: Vec3, p: Point3) -> f64 {
86 n.dot(Vec3::new(p.x(), p.y(), p.z()))
87}
88
89/// Errors from modeling operations.
90#[derive(Debug, thiserror::Error)]
91pub enum OperationsError {
92 /// The input shape is invalid for this operation.
93 #[error("invalid input: {reason}")]
94 InvalidInput {
95 /// Description of what is wrong.
96 reason: String,
97 },
98
99 /// The operation produced a non-manifold result.
100 #[error("non-manifold result")]
101 NonManifoldResult,
102
103 /// The operation produced an empty result (no geometry).
104 ///
105 /// Boolean operations return this when the algebraic outcome is the
106 /// empty set: `Cut(A, B)` when `A ⊆ B`, or any operation on
107 /// pre-collapsed inputs. Distinguishable from [`InvalidInput`] so
108 /// callers can apply empty-operand identity rules without
109 /// string-matching the error message.
110 ///
111 /// [`InvalidInput`]: Self::InvalidInput
112 #[error("empty result: {reason}")]
113 EmptyResult {
114 /// Description of the empty-result scenario.
115 reason: String,
116 },
117
118 /// A referenced topology entity was not found.
119 #[error(transparent)]
120 Topology(#[from] brepkit_topology::TopologyError),
121
122 /// A math error occurred during the operation.
123 #[error(transparent)]
124 Math(#[from] brepkit_math::MathError),
125
126 /// A GFA algorithm error occurred.
127 #[error("algo: {0}")]
128 Algo(#[from] brepkit_algo::error::AlgoError),
129
130 /// A blend (fillet/chamfer v2) error occurred.
131 #[error("blend: {0}")]
132 Blend(#[from] brepkit_blend::BlendError),
133
134 /// A check (classification/validation/distance) error occurred.
135 #[error("check: {0}")]
136 Check(#[from] brepkit_check::CheckError),
137
138 /// A geometry conversion error occurred.
139 #[error("geometry: {0}")]
140 Geometry(#[from] brepkit_geometry::error::GeomError),
141}