axiolid_profile/lib.rs
1#![forbid(unsafe_code)]
2
3//! Exact two-dimensional section profiles.
4//!
5//! The crate stores profile intent. Boolean cleanup and triangulation are
6//! algorithms in higher tiers so a consumer can use profile data without them.
7
8pub mod center_line;
9pub mod contour;
10pub mod parameterized;
11pub mod validate;
12
13use axiolid_core::Transform2;
14
15pub use center_line::CenterLineProfile;
16pub use contour::{Contour, ContourProfile, ProfileSegment};
17pub use parameterized::{CircleProfile, EllipseProfile, RectangleProfile, SectionProfile};
18pub use validate::ValidateProfile;
19
20/// Format-neutral profile representation.
21#[non_exhaustive]
22#[derive(Debug, Clone, PartialEq)]
23#[cfg_attr(
24 feature = "serde",
25 derive(serde::Serialize, serde::Deserialize),
26 serde(deny_unknown_fields)
27)]
28pub enum Profile {
29 /// Rectangle or rounded rectangle.
30 Rectangle(RectangleProfile),
31 /// Circle or annulus.
32 Circle(CircleProfile),
33 /// Ellipse.
34 Ellipse(EllipseProfile),
35 /// Structural parameterized section.
36 Section(SectionProfile),
37 /// Arbitrary exact contour with holes.
38 Contour(ContourProfile),
39 /// Profile transformed from another profile.
40 ///
41 /// Placement is recorded as a transform over the exact basis, not by
42 /// transforming tessellated points, so a placed circle stays a circle.
43 Derived {
44 /// Base profile.
45 basis: Box<Profile>,
46 /// Two-dimensional transform.
47 transform: Transform2,
48 },
49 /// Ordered collection of profiles used as one section.
50 Composite(Vec<Profile>),
51 /// Open path plus a constant width, centred on the path.
52 ///
53 /// Distinct from [`Profile::Contour`] because the area is *implied* by an
54 /// offset rather than bounded explicitly. A consumer that cannot offset
55 /// must refuse this rather than treat the path as a boundary: the path is
56 /// open, so reading it as a contour yields a degenerate zero-area region.
57 CenterLine(CenterLineProfile),
58}