1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! Surface relationships that compose curve and surface nodes.
use axiolid_core::{Scalar, Vec3};
use crate::{NodeId, SectionAtStation, StationFrame, StationedOpenSection};
/// Relationship between surface nodes.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub enum SurfaceRelation {
/// Surface bounded by oriented curve nodes.
CurveBounded {
basis: NodeId,
boundaries: Vec<NodeId>,
implicit_outer: bool,
},
/// Rectangular parameter-space trim.
RectangularTrimmed {
basis: NodeId,
u: (Scalar, Scalar),
v: (Scalar, Scalar),
u_sense: bool,
v_sense: bool,
},
/// Constant-distance offset surface.
Offset {
basis: NodeId,
distance: Scalar,
self_intersect: Option<bool>,
},
/// Surface generated by translating a curve.
LinearExtrusion {
swept_curve: NodeId,
direction: Vec3,
},
/// Surface generated by revolving a curve around an axis.
Revolution {
swept_curve: NodeId,
axis_origin: axiolid_core::Point3,
axis_direction: Vec3,
},
/// Open sections standing at stations along a directrix, joined by tag
/// (#241).
///
/// Each section's open polyline is placed in the directrix's `frame` at
/// its station (profile `x` to the lateral axis, `y` to up; see
/// [`crate::station`]). Between two stations, points with equal tags
/// are joined and interpolated linearly in distance, as are the
/// offsets. At least two sections, strictly increasing in distance,
/// with one tag sequence (or none) are required.
SectionedSurface {
directrix: NodeId,
sections: Vec<StationedOpenSection>,
frame: StationFrame,
},
/// Open sections standing at stations along a directrix, each
/// optionally explicitly oriented (#246): the general form of
/// [`SurfaceRelation::SectionedSurface`].
///
/// Each section's open polyline is placed as in a `SectionedSurface`,
/// its plane turned by the section's orientation. Sections are joined
/// by tag, or by index when none is tagged (see [`crate::station`]).
/// At least two sections, strictly increasing in distance, all tagged
/// or none, are required.
OpenSectionsAtStations {
directrix: NodeId,
sections: Vec<SectionAtStation>,
frame: StationFrame,
},
}
impl SurfaceRelation {
pub(crate) fn references(&self, out: &mut Vec<NodeId>) {
match self {
Self::CurveBounded {
basis, boundaries, ..
} => {
out.push(*basis);
out.extend(boundaries.iter().copied());
}
Self::RectangularTrimmed { basis, .. } | Self::Offset { basis, .. } => out.push(*basis),
Self::LinearExtrusion { swept_curve, .. } | Self::Revolution { swept_curve, .. } => {
out.push(*swept_curve)
}
Self::SectionedSurface {
directrix,
sections,
..
} => {
out.push(*directrix);
out.extend(sections.iter().map(|section| section.profile));
}
Self::OpenSectionsAtStations {
directrix,
sections,
..
} => {
out.push(*directrix);
out.extend(sections.iter().map(|section| section.profile));
}
}
}
}