Skip to main content

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    hidden-line drawings (exact) .... "hidden-lines-provider" or "application"
75    2D fields, morphology ........... "field-ops"
76    mesh repair / healing ........... "heal"
77
78BUNDLES -- use when you want breadth over a minimal build:
79    "standard" ... the pre-0.4 default: mesh + cpu + integration
80    "discrete" ... mesh stack: booleans, sections, hidden-line contracts,
81                   measure, spatial, generate
82    "parametric" . exact stack: curves, surfaces, topology, NURBS
83    "advanced" ... discrete + parametric + heal
84    "full" ....... everything, including parallel/simd/gpu adapters
85
86IMPORTANT -- features are ADDITIVE and imply their prerequisites, so name the
87capability you need, not its dependencies. "brep" already pulls surfaces,
88curves and linear; adding them by hand only widens your build.
89
90Operations that dispatch to a provider (booleans, sections, drawings) need BOTH a
91contract and a registered provider. "application" is the supported
92combination; "mesh-boolean" alone gives you the trait with nothing behind it.
93
94Full matrix: `cargo metadata` on this crate, or docs/architecture/closure-profiles.md
95for the exact crate set each profile compiles."#
96);
97
98/// Versioned description of the compiled downstream surface.
99#[cfg(feature = "integration")]
100pub mod integration;
101
102/// Caller-held broad-phase index for repeated ray casts.
103// Gated on BOTH: the cache needs the ray crate for the narrow phase and
104// the spatial crate for the broad phase. Enabling ray-mesh alone must
105// still build, so the cache is absent there and the facade falls back.
106#[cfg(all(feature = "ray-mesh", feature = "spatial"))]
107pub mod ray_index;
108
109/// Supported provider-neutral application boundary.
110#[cfg(feature = "application")]
111pub mod application;
112
113/// Always-available scalar, transform, and bounds vocabulary.
114pub mod core {
115    pub use axiolid_core::*;
116}
117
118pub use axiolid_core::{Aabb, Point2, Point3, Scalar, Tolerance, Transform3, Vec2, Vec3};
119
120#[cfg(feature = "mesh")]
121pub mod mesh {
122    pub use axiolid_mesh::*;
123}
124
125/// Point-sampled geometry: scans and photogrammetry captures.
126///
127/// Representation only. Parsing LAS/LAZ/E57/PCD/COPC is deliberately out of
128/// the kernel (ADR 0038); an ingestion crate converts a file into this value
129/// and the kernel never sees the source format.
130#[cfg(feature = "pointcloud")]
131pub mod pointcloud {
132    pub use axiolid_pointcloud::*;
133}
134
135/// Turning point-sampled geometry into a surface.
136///
137/// The contract and its types. A concrete provider arrives with the
138/// `pointcloud-provider` feature, or a caller supplies its own.
139#[cfg(feature = "pointcloud-reconstruction")]
140pub mod pointcloud_reconstruction {
141    pub use axiolid_pointcloud_reconstruction_contract::*;
142
143    /// Reference provider: a signed-distance field extracted as a level set.
144    #[cfg(feature = "pointcloud-provider")]
145    pub use axiolid_pointcloud_reconstruction_sdf::SdfReconstruction;
146}
147
148#[cfg(feature = "linear")]
149pub mod linear {
150    pub use axiolid_linear::*;
151}
152
153#[cfg(feature = "predicates")]
154pub mod predicates {
155    pub use axiolid_predicates::*;
156}
157
158/// Certified linear intersection queries.
159///
160/// The facade adds one compilation unit by design. An application that wants
161/// the smallest possible closure should depend on `axiolid-linear` and
162/// `axiolid-linear-intersection` directly (ADR 0036).
163#[cfg(feature = "linear-intersection")]
164pub mod linear_intersection {
165    pub use axiolid_linear_intersection::*;
166}
167
168#[cfg(feature = "profiles")]
169pub mod profile {
170    pub use axiolid_profile::*;
171}
172
173#[cfg(feature = "curves")]
174pub mod curve {
175    pub use axiolid_curve::*;
176}
177
178#[cfg(feature = "surfaces")]
179pub mod surface {
180    pub use axiolid_surface::*;
181}
182
183/// General NURBS analysis, inverse-query, and exact transformation algorithms.
184/// Scalar evaluation for parametric curves and surfaces.
185#[cfg(feature = "evaluate")]
186pub mod evaluate {
187    pub use axiolid_evaluate::*;
188}
189
190#[cfg(feature = "nurbs")]
191pub mod nurbs {
192    pub use axiolid_nurbs::*;
193}
194
195#[cfg(feature = "topology")]
196pub mod topology {
197    pub use axiolid_topology::*;
198}
199
200/// Strict exact B-rep results with typed analytic support catalogs and native
201/// trim intervals. Tessellation remains an explicit, tolerance-bearing output.
202#[cfg(feature = "brep")]
203pub mod brep {
204    pub use axiolid_brep::*;
205}
206
207#[cfg(feature = "model")]
208pub mod model {
209    pub use axiolid_model::*;
210}
211
212#[cfg(feature = "primitives")]
213pub mod primitive {
214    pub use axiolid_primitive::*;
215}
216
217#[cfg(feature = "tessellation")]
218pub mod tessellation {
219    pub use axiolid_tessellation_contract::*;
220}
221
222#[cfg(feature = "spatial")]
223pub mod spatial {
224    pub use axiolid_spatial::*;
225}
226
227/// Narrow-phase ray/triangle-mesh nearest-hit intersection.
228///
229/// Composes with the `spatial` broad phase: a caller can feed BVH candidate
230/// keys into `nearest_hit_among`, or scan a whole mesh with `nearest_hit`.
231#[cfg(feature = "ray-mesh")]
232pub mod ray_mesh {
233    pub use axiolid_ray_mesh::*;
234}
235
236#[cfg(feature = "measure")]
237pub mod measure {
238    pub use axiolid_measure::*;
239}
240
241#[cfg(feature = "overlay")]
242pub mod overlay {
243    pub use axiolid_overlay::*;
244}
245
246/// Planar projection of meshes: projected outlines and vertical prism
247/// intersection.
248#[cfg(feature = "project")]
249pub mod project {
250    pub use axiolid_project::*;
251}
252
253/// Exact planar shortest paths over a visibility graph, with typed
254/// unreachable reasons.
255///
256/// The kernel reports that no route exists under a given envelope. It never
257/// reports that a design is non-compliant: that reading belongs to the
258/// consumer, not to geometry.
259#[cfg(feature = "route")]
260pub mod route {
261    pub use axiolid_route::*;
262}
263
264/// Geometry generation: discrete sweeps plus focused certified trimmed arrangements.
265///
266/// Broad profile/path generators still return explicit meshes. The certified affine
267/// surface-pair constructor returns an analytic `ExactBRep` arrangement with an
268/// explicit residual certificate and never substitutes a mesh fallback (ADR 0029).
269#[cfg(feature = "generate")]
270pub mod generate {
271    pub use axiolid_construct::*;
272}
273
274/// Frame-neutral sampled layered-field values and configuration.
275#[cfg(feature = "field")]
276pub mod field {
277    pub use axiolid_field::*;
278}
279
280/// Sampling, morphology, clearance, and optional navigation over layered fields.
281#[cfg(feature = "field-ops")]
282pub mod field_ops {
283    pub use axiolid_field_ops::*;
284}
285
286#[cfg(feature = "heal")]
287pub mod heal {
288    pub use axiolid_heal::*;
289}
290
291#[cfg(feature = "contracts")]
292pub mod contracts {
293    pub use axiolid_contracts::*;
294}
295
296#[cfg(feature = "mesh-contracts")]
297pub mod mesh_contracts {
298    pub use axiolid_mesh_contracts::*;
299}
300
301#[cfg(feature = "mesh-boolean")]
302pub mod mesh_boolean {
303    pub use axiolid_mesh_boolean_contract::*;
304}
305
306#[cfg(feature = "mesh-section")]
307pub mod mesh_section {
308    pub use axiolid_mesh_section_contract::*;
309}
310
311/// Hidden-line drawings (orthographic and perspective) and visible face regions
312/// (orthographic) of triangle meshes.
313///
314/// The contracts and their types (ADR 0090, ADR 0094). The exact scalar
315/// providers arrive with the `hidden-lines-provider` feature, or a caller
316/// supplies its own. The contract is part of `discrete`; `application` adds
317/// the providers and `Application::hidden_lines` (ADR 0105).
318#[cfg(feature = "mesh-hidden-lines")]
319pub mod mesh_hidden_lines {
320    pub use axiolid_mesh_hidden_lines_contract::*;
321
322    /// Reference provider: visibility decided exactly in the view's frame.
323    #[cfg(feature = "hidden-lines-provider")]
324    pub use axiolid_hidden_lines::ScalarHiddenLines;
325
326    /// Reference provider: visible face regions decided exactly in the view's
327    /// frame.
328    #[cfg(feature = "hidden-lines-provider")]
329    pub use axiolid_hidden_lines::ScalarVisibleFaces;
330}
331
332#[cfg(feature = "graph-compile")]
333pub mod graph_compile {
334    pub use axiolid_mesh_compile_contract::*;
335}
336
337#[cfg(any(
338    feature = "dispatch-mesh-boolean",
339    feature = "dispatch-mesh-section",
340    feature = "dispatch-mesh-hidden-lines"
341))]
342pub mod dispatch {
343    pub use axiolid_dispatch::*;
344}
345
346#[cfg(feature = "cpu")]
347pub mod cpu {
348    pub use axiolid_backend_cpu::*;
349}
350
351#[cfg(feature = "gpu")]
352pub mod gpu {
353    pub use axiolid_backend_gpu::*;
354}