Skip to main content

kcl_lib/std/
axis_or_reference.rs

1//! Types for referencing an axis or edge.
2
3use super::args::TyF64;
4use crate::KclError;
5use crate::errors::KclErrorDetails;
6use crate::execution::Plane;
7use crate::execution::Segment;
8use crate::execution::SegmentKind;
9use crate::execution::Sketch;
10use crate::execution::Solid;
11use crate::execution::TagIdentifier;
12use crate::std::fillet::EdgeReference;
13use crate::std::sketch::FaceTag;
14
15/// A 2D axis or tagged edge.
16#[derive(Debug, Clone, PartialEq)]
17pub enum Axis2dOrEdgeReference {
18    /// 2D axis and origin.
19    Axis { direction: [TyF64; 2], origin: [TyF64; 2] },
20    /// Tagged edge.
21    Edge(EdgeReference),
22}
23
24/// A 3D mirror target.
25#[derive(Debug, Clone, PartialEq)]
26pub enum MirrorAcross3d {
27    /// 3D axis and origin.
28    Axis {
29        direction: Box<[TyF64; 3]>,
30        origin: Box<[TyF64; 3]>,
31    },
32    /// Tagged edge.
33    Edge(Box<EdgeReference>),
34    /// A plane.
35    Plane(Box<Plane>),
36}
37
38impl Axis2dOrEdgeReference {
39    /// Use a sketch-solve segment by finding its engine ID.
40    pub fn from_segment(segment: &Segment) -> Result<Self, KclError> {
41        match &segment.kind {
42            SegmentKind::Line { .. } => Ok(Self::Edge(EdgeReference::Uuid(segment.id))),
43            SegmentKind::Point { .. } => Err(KclError::new_type(KclErrorDetails {
44                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
45                backtrace: Default::default(),
46                message: "Cannot use a point as an axis".to_owned(),
47            })),
48            SegmentKind::Arc { .. } => Err(KclError::new_type(KclErrorDetails {
49                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
50                backtrace: Default::default(),
51                message: "Cannot use an arc as an axis".to_owned(),
52            })),
53            SegmentKind::Circle { .. } => Err(KclError::new_type(KclErrorDetails {
54                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
55                backtrace: Default::default(),
56                message: "Cannot use a circle as an axis".to_owned(),
57            })),
58            SegmentKind::ControlPointSpline { .. } => Err(KclError::new_type(KclErrorDetails {
59                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
60                backtrace: Default::default(),
61                message: "Cannot use a control point spline as an axis".to_owned(),
62            })),
63        }
64    }
65}
66
67impl MirrorAcross3d {
68    /// Use a sketch-solve segment by finding its engine ID.
69    pub fn from_segment(segment: &Segment) -> Result<Self, KclError> {
70        match &segment.kind {
71            SegmentKind::Line { .. } => Ok(Self::Edge(Box::new(EdgeReference::Uuid(segment.id)))),
72            SegmentKind::Point { .. } => Err(KclError::new_type(KclErrorDetails {
73                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
74                backtrace: Default::default(),
75                message: "Cannot use a point as an axis".to_owned(),
76            })),
77            SegmentKind::Arc { .. } => Err(KclError::new_type(KclErrorDetails {
78                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
79                backtrace: Default::default(),
80                message: "Cannot use an arc as an axis".to_owned(),
81            })),
82            SegmentKind::Circle { .. } => Err(KclError::new_type(KclErrorDetails {
83                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
84                backtrace: Default::default(),
85                message: "Cannot use a circle as an axis".to_owned(),
86            })),
87            SegmentKind::ControlPointSpline { .. } => Err(KclError::new_type(KclErrorDetails {
88                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
89                backtrace: Default::default(),
90                message: "Cannot use a control point spline as an axis".to_owned(),
91            })),
92        }
93    }
94}
95
96/// A 3D axis or tagged edge.
97#[allow(clippy::large_enum_variant)]
98#[derive(Debug, Clone, PartialEq)]
99pub enum Axis3dOrEdgeReference {
100    /// 3D axis and origin.
101    Axis { direction: [TyF64; 3], origin: [TyF64; 3] },
102    /// Tagged edge.
103    Edge(EdgeReference),
104}
105
106impl Axis3dOrEdgeReference {
107    /// Use a sketch-solve segment by finding its engine ID.
108    pub fn from_segment(segment: &Segment) -> Result<Self, KclError> {
109        match &segment.kind {
110            SegmentKind::Line { .. } => Ok(Self::Edge(EdgeReference::Uuid(segment.id))),
111            SegmentKind::Point { .. } => Err(KclError::new_type(KclErrorDetails {
112                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
113                backtrace: Default::default(),
114                message: "Cannot use a point as an axis".to_owned(),
115            })),
116            SegmentKind::Arc { .. } => Err(KclError::new_type(KclErrorDetails {
117                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
118                backtrace: Default::default(),
119                message: "Cannot use an arc as an axis".to_owned(),
120            })),
121            SegmentKind::Circle { .. } => Err(KclError::new_type(KclErrorDetails {
122                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
123                backtrace: Default::default(),
124                message: "Cannot use a circle as an axis".to_owned(),
125            })),
126            SegmentKind::ControlPointSpline { .. } => Err(KclError::new_type(KclErrorDetails {
127                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
128                backtrace: Default::default(),
129                message: "Cannot use a control point spline as an axis".to_owned(),
130            })),
131        }
132    }
133}
134
135/// A 2D axis or a raw point2d.
136#[derive(Debug, Clone, PartialEq)]
137pub enum Axis2dOrPoint2d {
138    /// 2D axis and origin.
139    Axis { direction: [TyF64; 2], origin: [TyF64; 2] },
140    /// Raw point2d.
141    Point([TyF64; 2]),
142}
143
144impl Axis2dOrPoint2d {
145    /// Convert to a 2D axis.
146    pub fn to_point2d(&self) -> [TyF64; 2] {
147        match self {
148            Axis2dOrPoint2d::Axis { direction, origin: _ } => direction.clone(),
149            Axis2dOrPoint2d::Point(point) => point.clone(),
150        }
151    }
152}
153
154/// A 3D axis or a raw point3d.
155#[derive(Debug, Clone, PartialEq)]
156pub enum Axis3dOrPoint3d {
157    /// 3D axis and origin.
158    Axis { direction: [TyF64; 3], origin: [TyF64; 3] },
159    /// Raw point3d.
160    Point([TyF64; 3]),
161}
162
163impl Axis3dOrPoint3d {
164    /// Convert to a 3D axis.
165    pub fn to_point3d(&self) -> [TyF64; 3] {
166        match self {
167            Axis3dOrPoint3d::Axis { direction, origin: _ } => direction.clone(),
168            Axis3dOrPoint3d::Point(point) => point.clone(),
169        }
170    }
171
172    pub fn axis_origin(&self) -> Option<[TyF64; 3]> {
173        match self {
174            Axis3dOrPoint3d::Axis { origin, .. } => Some(origin.clone()),
175            Axis3dOrPoint3d::Point(..) => None,
176        }
177    }
178}
179
180/// A raw point3d, 3D axis, Edge, Face, Solid or Tag.
181#[allow(clippy::large_enum_variant)]
182#[derive(Debug, Clone, PartialEq)]
183pub enum Point3dAxis3dOrGeometryReference {
184    /// Raw point3d.
185    Point([TyF64; 3]),
186    /// 3D axis and origin.
187    Axis { direction: [TyF64; 3], origin: [TyF64; 3] },
188    /// Plane.
189    Plane(Box<Plane>),
190    /// Edge Reference.
191    Edge(EdgeReference),
192    /// Face.
193    Face(FaceTag),
194    /// Sketch.
195    Sketch(Box<Sketch>),
196    /// Solid.
197    Solid(Box<Solid>),
198    /// Tagged edge or face.
199    TaggedEdgeOrFace(TagIdentifier),
200}