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}