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        }
59    }
60}
61
62impl MirrorAcross3d {
63    /// Use a sketch-solve segment by finding its engine ID.
64    pub fn from_segment(segment: &Segment) -> Result<Self, KclError> {
65        match &segment.kind {
66            SegmentKind::Line { .. } => Ok(Self::Edge(Box::new(EdgeReference::Uuid(segment.id)))),
67            SegmentKind::Point { .. } => Err(KclError::new_type(KclErrorDetails {
68                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
69                backtrace: Default::default(),
70                message: "Cannot use a point as an axis".to_owned(),
71            })),
72            SegmentKind::Arc { .. } => 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 an arc as an axis".to_owned(),
76            })),
77            SegmentKind::Circle { .. } => 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 a circle as an axis".to_owned(),
81            })),
82        }
83    }
84}
85
86/// A 3D axis or tagged edge.
87#[allow(clippy::large_enum_variant)]
88#[derive(Debug, Clone, PartialEq)]
89pub enum Axis3dOrEdgeReference {
90    /// 3D axis and origin.
91    Axis { direction: [TyF64; 3], origin: [TyF64; 3] },
92    /// Tagged edge.
93    Edge(EdgeReference),
94}
95
96impl Axis3dOrEdgeReference {
97    /// Use a sketch-solve segment by finding its engine ID.
98    pub fn from_segment(segment: &Segment) -> Result<Self, KclError> {
99        match &segment.kind {
100            SegmentKind::Line { .. } => Ok(Self::Edge(EdgeReference::Uuid(segment.id))),
101            SegmentKind::Point { .. } => Err(KclError::new_type(KclErrorDetails {
102                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
103                backtrace: Default::default(),
104                message: "Cannot use a point as an axis".to_owned(),
105            })),
106            SegmentKind::Arc { .. } => Err(KclError::new_type(KclErrorDetails {
107                source_ranges: segment.meta.iter().map(|meta| meta.source_range).collect(),
108                backtrace: Default::default(),
109                message: "Cannot use an arc as an axis".to_owned(),
110            })),
111            SegmentKind::Circle { .. } => 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 circle as an axis".to_owned(),
115            })),
116        }
117    }
118}
119
120/// A 2D axis or a raw point2d.
121#[derive(Debug, Clone, PartialEq)]
122pub enum Axis2dOrPoint2d {
123    /// 2D axis and origin.
124    Axis { direction: [TyF64; 2], origin: [TyF64; 2] },
125    /// Raw point2d.
126    Point([TyF64; 2]),
127}
128
129impl Axis2dOrPoint2d {
130    /// Convert to a 2D axis.
131    pub fn to_point2d(&self) -> [TyF64; 2] {
132        match self {
133            Axis2dOrPoint2d::Axis { direction, origin: _ } => direction.clone(),
134            Axis2dOrPoint2d::Point(point) => point.clone(),
135        }
136    }
137}
138
139/// A 3D axis or a raw point3d.
140#[derive(Debug, Clone, PartialEq)]
141pub enum Axis3dOrPoint3d {
142    /// 3D axis and origin.
143    Axis { direction: [TyF64; 3], origin: [TyF64; 3] },
144    /// Raw point3d.
145    Point([TyF64; 3]),
146}
147
148impl Axis3dOrPoint3d {
149    /// Convert to a 3D axis.
150    pub fn to_point3d(&self) -> [TyF64; 3] {
151        match self {
152            Axis3dOrPoint3d::Axis { direction, origin: _ } => direction.clone(),
153            Axis3dOrPoint3d::Point(point) => point.clone(),
154        }
155    }
156
157    pub fn axis_origin(&self) -> Option<[TyF64; 3]> {
158        match self {
159            Axis3dOrPoint3d::Axis { origin, .. } => Some(origin.clone()),
160            Axis3dOrPoint3d::Point(..) => None,
161        }
162    }
163}
164
165/// A raw point3d, 3D axis, Edge, Face, Solid or Tag.
166#[allow(clippy::large_enum_variant)]
167#[derive(Debug, Clone, PartialEq)]
168pub enum Point3dAxis3dOrGeometryReference {
169    /// Raw point3d.
170    Point([TyF64; 3]),
171    /// 3D axis and origin.
172    Axis { direction: [TyF64; 3], origin: [TyF64; 3] },
173    /// Plane.
174    Plane(Box<Plane>),
175    /// Edge Reference.
176    Edge(EdgeReference),
177    /// Face.
178    Face(FaceTag),
179    /// Sketch.
180    Sketch(Box<Sketch>),
181    /// Solid.
182    Solid(Box<Solid>),
183    /// Tagged edge or face.
184    TaggedEdgeOrFace(TagIdentifier),
185}