axiolid/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Feature-gated facade for Axiolid geometry.
4//!
5//! Nothing is compiled unless it is asked for: `default = []`, so a consumer
6//! names the capability they need and pays for that alone (kernel#9). Building
7//! with no feature at all raises a `compile_error!` listing the options rather
8//! than leaving an empty crate whose every call site fails as "not found".
9//! `standard` reproduces the pre-0.4 default (`mesh + cpu + integration`) for
10//! consumers who want the old behaviour in one line.
11//!
12//! Features are additive and named for geometry capabilities. No feature or
13//! bundle is named after a source format, vendor or downstream product, and
14//! every package behind a feature stays usable as a direct dependency.
15//!
16//! # Exact geometry is the primary currency
17//!
18//! No entry point in this facade converts exact geometry into a mesh
19//! unless the caller asked for one and supplied a tolerance. Tessellation
20//! is a requested OUTPUT, never a fallback:
21//!
22//! - `generate::GenerationRequest::ExactBRep` carries no tolerance field,
23//!   so a mesh cannot be produced for it. A request it cannot satisfy
24//!   exactly is refused rather than approximated.
25//! - `generate::TessellationRequest` and `TessellationOptions` have no
26//!   `Default`. There is no global chord error to fall back to, because
27//!   acceptable error depends on source units and downstream use.
28//! - A tessellated result carries the tolerance it was built to, so an
29//!   approximation cannot later be mistaken for an exact value.
30//!
31//! `tests/exact_primary.rs` holds this to account (kernel#36).
32
33// No capability feature is enabled, so this crate would compile to an empty
34// facade and every call site would fail with a confusing "not found in this
35// scope" error instead of naming the real cause (kernel#9). Fail loudly here.
36//
37// The guard lists ONE feature per capability family rather than every
38// feature: each family entry is implied by its own bundle, so a consumer who
39// enabled `brep` (which implies `surfaces` -> `curves` -> `linear`) already
40// satisfies it. Listing leaves instead would make this fire spuriously.
41#[cfg(not(any(
42    feature = "mesh",
43    feature = "linear",
44    feature = "predicates",
45    feature = "profiles",
46    feature = "curves",
47    feature = "primitives",
48    feature = "overlay",
49    feature = "field",
50    feature = "pointcloud",
51    feature = "contracts",
52    feature = "cpu",
53)))]
54compile_error!(
55    r#"the `axiolid` facade has no capability features enabled, so it exports nothing.
56
57As of 0.4 `default = []`: this crate is pay-for-what-you-use and compiles only
58the geometry you name. Add at least one feature in Cargo.toml.
59
60MIGRATING FROM <=0.3 (default was `mesh + cpu + integration`):
61    axiolid = { version = "0.4", features = ["standard"] }
62
63PICK BY TASK -- narrowest feature that does the job:
64    triangle meshes, no operations .. "mesh"
65    line/plane/ray intersection ..... "linear-intersection"
66    volume, area, centroid .......... "measure"
67    ray casting against a mesh ...... "ray-mesh"
68    boolean union/difference ........ "application"
69    planar section / contours ....... "application"
70    NURBS curves and surfaces ....... "nurbs"
71    exact B-rep topology ............ "brep"
72    tessellate exact -> mesh ........ "tessellation"
73    point clouds to mesh ............ "pointcloud-provider"
74    2D fields, morphology ........... "field-ops"
75    mesh repair / healing ........... "heal"
76
77BUNDLES -- use when you want breadth over a minimal build:
78    "standard" ... the pre-0.4 default: mesh + cpu + integration
79    "discrete" ... mesh stack: booleans, sections, measure, spatial, generate
80    "parametric" . exact stack: curves, surfaces, topology, NURBS
81    "advanced" ... discrete + parametric + heal
82    "full" ....... everything, including parallel/simd/gpu adapters
83
84IMPORTANT -- features are ADDITIVE and imply their prerequisites, so name the
85capability you need, not its dependencies. "brep" already pulls surfaces,
86curves and linear; adding them by hand only widens your build.
87
88Operations that dispatch to a provider (booleans, sections) need BOTH a
89contract and a registered provider. "application" is the supported
90combination; "mesh-boolean" alone gives you the trait with nothing behind it.
91
92Full matrix: `cargo metadata` on this crate, or docs/architecture/closure-profiles.md
93for the exact crate set each profile compiles."#
94);
95
96/// Versioned description of the compiled downstream surface.
97#[cfg(feature = "integration")]
98pub mod integration;
99
100/// Caller-held broad-phase index for repeated ray casts.
101// Gated on BOTH: the cache needs the ray crate for the narrow phase and
102// the spatial crate for the broad phase. Enabling ray-mesh alone must
103// still build, so the cache is absent there and the facade falls back.
104#[cfg(all(feature = "ray-mesh", feature = "spatial"))]
105pub mod ray_index;
106
107/// Supported provider-neutral application boundary.
108#[cfg(feature = "application")]
109pub mod application;
110
111/// Always-available scalar, transform, and bounds vocabulary.
112pub mod core {
113    pub use axiolid_core::*;
114}
115
116pub use axiolid_core::{Aabb, Point2, Point3, Scalar, Tolerance, Transform3, Vec2, Vec3};
117
118#[cfg(feature = "mesh")]
119pub mod mesh {
120    pub use axiolid_mesh::*;
121}
122
123/// Point-sampled geometry: scans and photogrammetry captures.
124///
125/// Representation only. Parsing LAS/LAZ/E57/PCD/COPC is deliberately out of
126/// the kernel (ADR 0038); an ingestion crate converts a file into this value
127/// and the kernel never sees the source format.
128#[cfg(feature = "pointcloud")]
129pub mod pointcloud {
130    pub use axiolid_pointcloud::*;
131}
132
133/// Turning point-sampled geometry into a surface.
134///
135/// The contract and its types. A concrete provider arrives with the
136/// `pointcloud-provider` feature, or a caller supplies its own.
137#[cfg(feature = "pointcloud-reconstruction")]
138pub mod pointcloud_reconstruction {
139    pub use axiolid_pointcloud_reconstruction_contract::*;
140
141    /// Reference provider: a signed-distance field extracted as a level set.
142    #[cfg(feature = "pointcloud-provider")]
143    pub use axiolid_pointcloud_reconstruction_sdf::SdfReconstruction;
144}
145
146#[cfg(feature = "linear")]
147pub mod linear {
148    pub use axiolid_linear::*;
149}
150
151#[cfg(feature = "predicates")]
152pub mod predicates {
153    pub use axiolid_predicates::*;
154}
155
156/// Certified linear intersection queries.
157///
158/// The facade adds one compilation unit by design. An application that wants
159/// the smallest possible closure should depend on `axiolid-linear` and
160/// `axiolid-linear-intersection` directly (ADR 0036).
161#[cfg(feature = "linear-intersection")]
162pub mod linear_intersection {
163    pub use axiolid_linear_intersection::*;
164}
165
166#[cfg(feature = "profiles")]
167pub mod profile {
168    pub use axiolid_profile::*;
169}
170
171#[cfg(feature = "curves")]
172pub mod curve {
173    pub use axiolid_curve::*;
174}
175
176#[cfg(feature = "surfaces")]
177pub mod surface {
178    pub use axiolid_surface::*;
179}
180
181/// General NURBS analysis, inverse-query, and exact transformation algorithms.
182/// Scalar evaluation for parametric curves and surfaces.
183#[cfg(feature = "evaluate")]
184pub mod evaluate {
185    pub use axiolid_evaluate::*;
186}
187
188#[cfg(feature = "nurbs")]
189pub mod nurbs {
190    pub use axiolid_nurbs::*;
191}
192
193#[cfg(feature = "topology")]
194pub mod topology {
195    pub use axiolid_topology::*;
196}
197
198/// Strict exact B-rep results with typed analytic support catalogs and native
199/// trim intervals. Tessellation remains an explicit, tolerance-bearing output.
200#[cfg(feature = "brep")]
201pub mod brep {
202    pub use axiolid_brep::*;
203}
204
205#[cfg(feature = "model")]
206pub mod model {
207    pub use axiolid_model::*;
208}
209
210#[cfg(feature = "primitives")]
211pub mod primitive {
212    pub use axiolid_primitive::*;
213}
214
215#[cfg(feature = "tessellation")]
216pub mod tessellation {
217    pub use axiolid_tessellation_contract::*;
218}
219
220#[cfg(feature = "spatial")]
221pub mod spatial {
222    pub use axiolid_spatial::*;
223}
224
225/// Narrow-phase ray/triangle-mesh nearest-hit intersection.
226///
227/// Composes with the `spatial` broad phase: a caller can feed BVH candidate
228/// keys into `nearest_hit_among`, or scan a whole mesh with `nearest_hit`.
229#[cfg(feature = "ray-mesh")]
230pub mod ray_mesh {
231    pub use axiolid_ray_mesh::*;
232}
233
234#[cfg(feature = "measure")]
235pub mod measure {
236    pub use axiolid_measure::*;
237}
238
239#[cfg(feature = "overlay")]
240pub mod overlay {
241    pub use axiolid_overlay::*;
242}
243
244/// Planar projection of meshes: projected outlines and vertical prism
245/// intersection.
246#[cfg(feature = "project")]
247pub mod project {
248    pub use axiolid_project::*;
249}
250
251/// Exact planar shortest paths over a visibility graph, with typed
252/// unreachable reasons.
253///
254/// The kernel reports that no route exists under a given envelope. It never
255/// reports that a design is non-compliant: that reading belongs to the
256/// consumer, not to geometry.
257#[cfg(feature = "route")]
258pub mod route {
259    pub use axiolid_route::*;
260}
261
262/// Geometry generation: discrete sweeps plus focused certified trimmed arrangements.
263///
264/// Broad profile/path generators still return explicit meshes. The certified affine
265/// surface-pair constructor returns an analytic `ExactBRep` arrangement with an
266/// explicit residual certificate and never substitutes a mesh fallback (ADR 0029).
267#[cfg(feature = "generate")]
268pub mod generate {
269    pub use axiolid_construct::*;
270}
271
272/// Frame-neutral sampled layered-field values and configuration.
273#[cfg(feature = "field")]
274pub mod field {
275    pub use axiolid_field::*;
276}
277
278/// Sampling, morphology, clearance, and optional navigation over layered fields.
279#[cfg(feature = "field-ops")]
280pub mod field_ops {
281    pub use axiolid_field_ops::*;
282}
283
284#[cfg(feature = "heal")]
285pub mod heal {
286    pub use axiolid_heal::*;
287}
288
289#[cfg(feature = "contracts")]
290pub mod contracts {
291    pub use axiolid_contracts::*;
292}
293
294#[cfg(feature = "mesh-contracts")]
295pub mod mesh_contracts {
296    pub use axiolid_mesh_contracts::*;
297}
298
299#[cfg(feature = "mesh-boolean")]
300pub mod mesh_boolean {
301    pub use axiolid_mesh_boolean_contract::*;
302}
303
304#[cfg(feature = "mesh-section")]
305pub mod mesh_section {
306    pub use axiolid_mesh_section_contract::*;
307}
308
309#[cfg(feature = "graph-compile")]
310pub mod graph_compile {
311    pub use axiolid_mesh_compile_contract::*;
312}
313
314#[cfg(any(feature = "dispatch-mesh-boolean", feature = "dispatch-mesh-section"))]
315pub mod dispatch {
316    pub use axiolid_dispatch::*;
317}
318
319#[cfg(feature = "cpu")]
320pub mod cpu {
321    pub use axiolid_backend_cpu::*;
322}
323
324#[cfg(feature = "gpu")]
325pub mod gpu {
326    pub use axiolid_backend_gpu::*;
327}