axiolid_topology/
entity.rs

1//! B-rep entities. `G` is a caller-chosen curve/surface geometry handle.
2
3use axiolid_core::Point3;
4
5use crate::{EdgeId, FaceId, LoopId, ShellId, VertexId};
6
7/// Topological orientation relative to the underlying geometry.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum Orientation {
10    /// Same parameter direction/normal.
11    Forward,
12    /// Reversed parameter direction/normal.
13    Reversed,
14}
15
16/// Vertex with an explicit model-space position.
17#[derive(Debug, Clone, Copy, PartialEq)]
18pub struct Vertex {
19    /// Position.
20    pub position: Point3,
21}
22
23/// Edge bounded by two vertices and optionally supported by exact curve data.
24#[derive(Debug, Clone, PartialEq)]
25pub struct Edge<G> {
26    /// Start vertex.
27    pub start: VertexId,
28    /// End vertex.
29    pub end: VertexId,
30    /// Exact support curve handle; absent for a straight topological edge whose
31    /// endpoints are sufficient.
32    pub curve: Option<G>,
33}
34
35/// One oriented use of an edge in a loop.
36///
37/// The `pcurve` is the edge's image in the parameter space of the face this
38/// use belongs to. A 3D edge curve says where a boundary sits in model
39/// space; it does not say where that boundary lies in a surface's `(u, v)`
40/// domain, and inverting a surface to recover it is not generally solvable
41/// in closed form. Trimming a curved face therefore needs it stated, which
42/// is what exchange formats carry alongside the 3D edge curve.
43///
44/// It belongs to the USE rather than the edge: one edge bounds two faces
45/// with different support surfaces, so it has a different parameter image
46/// in each.
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48pub struct EdgeUse<G> {
49    /// Referenced edge.
50    pub edge: EdgeId,
51    /// Traversal direction.
52    pub orientation: Orientation,
53    /// Optional 2D curve handle in the owning face's surface parameters.
54    pub pcurve: Option<G>,
55}
56
57/// Closed boundary wire.
58#[derive(Debug, Clone, Default, PartialEq, Eq)]
59pub struct Loop<G> {
60    /// Consecutive oriented edges.
61    pub edges: Vec<EdgeUse<G>>,
62}
63
64/// One oriented loop use on a face.
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
66pub struct FaceBound {
67    /// Referenced loop.
68    pub loop_id: LoopId,
69    /// Whether this bound has the same orientation as the face.
70    pub orientation: Orientation,
71    /// Whether this is the outer bound.
72    pub outer: bool,
73}
74
75/// Face supported by an exact surface and bounded by loops.
76#[derive(Debug, Clone, PartialEq)]
77pub struct Face<G> {
78    /// Exact support surface handle. Planar polygonal faces may omit it.
79    pub surface: Option<G>,
80    /// Outer and inner bounds.
81    pub bounds: Vec<FaceBound>,
82    /// Orientation relative to the support surface normal.
83    pub orientation: Orientation,
84}
85
86/// Connected collection of oriented faces.
87#[derive(Debug, Clone, Default, PartialEq, Eq)]
88pub struct Shell {
89    /// Face handles.
90    pub faces: Vec<(FaceId, Orientation)>,
91    /// Whether the source asserts closure.
92    pub closed: bool,
93}
94
95/// Solid with one outer shell and optional void shells.
96#[derive(Debug, Clone, PartialEq, Eq)]
97pub struct Solid {
98    /// Outer shell.
99    pub outer: ShellId,
100    /// Interior void shells.
101    pub voids: Vec<ShellId>,
102}