axiolid_topology/
brep.rs

1//! Append-only typed arenas for B-rep topology.
2
3use crate::{
4    Edge, EdgeId, Face, FaceId, Loop, LoopId, Shell, ShellId, Solid, SolidId, Vertex, VertexId,
5};
6
7/// Owned B-rep. Generic geometry handles avoid a dependency cycle with the
8/// model graph that stores exact curves and surfaces.
9#[derive(Debug, Clone, PartialEq)]
10pub struct BRep<Curve3, Curve2 = Curve3, Surface = Curve3> {
11    vertices: Vec<Vertex>,
12    edges: Vec<Edge<Curve3>>,
13    loops: Vec<Loop<Curve2>>,
14    faces: Vec<Face<Surface>>,
15    shells: Vec<Shell>,
16    solids: Vec<Solid>,
17}
18
19impl<Curve3, Curve2, Surface> Default for BRep<Curve3, Curve2, Surface> {
20    fn default() -> Self {
21        Self {
22            vertices: Vec::new(),
23            edges: Vec::new(),
24            loops: Vec::new(),
25            faces: Vec::new(),
26            shells: Vec::new(),
27            solids: Vec::new(),
28        }
29    }
30}
31
32impl<Curve3, Curve2, Surface> BRep<Curve3, Curve2, Surface> {
33    /// Fallibly reserve append-only arena capacity for bounded construction.
34    pub fn try_reserve(
35        &mut self,
36        vertices: usize,
37        edges: usize,
38        loops: usize,
39        faces: usize,
40        shells: usize,
41        solids: usize,
42    ) -> Result<(), std::collections::TryReserveError> {
43        self.vertices.try_reserve_exact(vertices)?;
44        self.edges.try_reserve_exact(edges)?;
45        self.loops.try_reserve_exact(loops)?;
46        self.faces.try_reserve_exact(faces)?;
47        self.shells.try_reserve_exact(shells)?;
48        self.solids.try_reserve_exact(solids)?;
49        Ok(())
50    }
51
52    /// Add a vertex and return its typed handle.
53    pub fn add_vertex(&mut self, value: Vertex) -> VertexId {
54        let id = VertexId::from_index(self.vertices.len());
55        self.vertices.push(value);
56        id
57    }
58
59    /// Add an edge and return its typed handle.
60    pub fn add_edge(&mut self, value: Edge<Curve3>) -> EdgeId {
61        let id = EdgeId::from_index(self.edges.len());
62        self.edges.push(value);
63        id
64    }
65
66    /// Add a loop and return its typed handle.
67    pub fn add_loop(&mut self, value: Loop<Curve2>) -> LoopId {
68        let id = LoopId::from_index(self.loops.len());
69        self.loops.push(value);
70        id
71    }
72
73    /// Add a face and return its typed handle.
74    pub fn add_face(&mut self, value: Face<Surface>) -> FaceId {
75        let id = FaceId::from_index(self.faces.len());
76        self.faces.push(value);
77        id
78    }
79
80    /// Add a shell and return its typed handle.
81    pub fn add_shell(&mut self, value: Shell) -> ShellId {
82        let id = ShellId::from_index(self.shells.len());
83        self.shells.push(value);
84        id
85    }
86
87    /// Add a solid and return its typed handle.
88    pub fn add_solid(&mut self, value: Solid) -> SolidId {
89        let id = SolidId::from_index(self.solids.len());
90        self.solids.push(value);
91        id
92    }
93
94    /// Vertices in stable insertion order.
95    pub fn vertices(&self) -> &[Vertex] {
96        &self.vertices
97    }
98
99    /// Edge handle at a dense arena index, if present.
100    pub fn edge_id_at(&self, index: usize) -> Option<EdgeId> {
101        (index < self.edges.len()).then(|| EdgeId::from_index(index))
102    }
103
104    /// Loop handle at a dense arena index, if present.
105    pub fn loop_id_at(&self, index: usize) -> Option<LoopId> {
106        (index < self.loops.len()).then(|| LoopId::from_index(index))
107    }
108
109    /// All edges in insertion order.
110    pub fn edges(&self) -> &[Edge<Curve3>] {
111        &self.edges
112    }
113
114    /// Loops in stable insertion order.
115    pub fn loops(&self) -> &[Loop<Curve2>] {
116        &self.loops
117    }
118
119    /// Face handle at a dense arena index, if present.
120    pub fn face_id_at(&self, index: usize) -> Option<FaceId> {
121        (index < self.faces.len()).then(|| FaceId::from_index(index))
122    }
123
124    /// All faces in insertion order.
125    pub fn faces(&self) -> &[Face<Surface>] {
126        &self.faces
127    }
128
129    /// Shells in stable insertion order.
130    pub fn shells(&self) -> &[Shell] {
131        &self.shells
132    }
133
134    /// Solids in stable insertion order.
135    pub fn solids(&self) -> &[Solid] {
136        &self.solids
137    }
138}