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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
//! Shared types used by cnccoder, such as Vector2, Vector3, Units, Direction, Axis and Bounds.
use std::fmt;
use serde::{Deserialize, Serialize};
mod vector;
pub use vector::*;
/// Represents an area in 3D space from one min and one max [Vector3](struct.Vector3.html) point.
#[derive(Default, Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
pub struct Bounds {
/// Minimum 3D point of the boundary.
pub min: Vector3,
/// Maximum 3D point of the boundary.
pub max: Vector3,
}
impl Bounds {
/// Create a `Bounds` struct starting at xyz 0.0 and ending at the given xyz coordinates.
#[must_use]
pub fn new(x: f64, y: f64, z: f64) -> Self {
Self {
min: Vector3::new(0.0, 0.0, 0.0),
max: Vector3::new(x, y, z),
}
}
/// Create a `Bounds` struct using xyz `f64::MIN` as min and `f64::MAX` for max.
#[must_use]
pub fn minmax() -> Self {
Self {
min: Vector3::max(),
max: Vector3::min(),
}
}
/// Return the size of the bounds area as a [Vector3](struct.Vector3.html).
#[must_use]
pub fn size(&self) -> Vector3 {
Vector3::new(
self.max.x - self.min.x,
self.max.y - self.min.y,
self.max.z - self.min.z,
)
}
}
/// Indicates if metric or imperial units should be used. This is used as a setting both for a
/// [Program](../program/struct.Program.html) and [tools](../tools/).
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
#[serde(rename_all = "lowercase")]
pub enum Units {
/// Indicates that measurements are given using millimeters.
#[default]
Metric,
/// Indicates that measurements are given using inches.
Imperial,
}
impl Units {
/// Converts from millimeters to inches
pub fn mm_to_inch(mm: f64) -> f64 {
mm * 25.4
}
/// Converts a measurement from the selected unit to millimeters
pub fn measurement_from_mm(self, value: f64) -> f64 {
match self {
Self::Metric => value,
Self::Imperial => Self::mm_to_inch(value),
}
}
/// Provides default z_end value, what the CNC should consider as the vertical bottom value
/// by default, either as millimeters or inches.
pub fn default_z_end(self) -> f64 {
match self {
Self::Metric => 0.1,
Self::Imperial => Self::mm_to_inch(0.1),
}
}
/// Provides default z_max_step value. As the CNC machine cuts a path it will often be
/// instructed to cut the path in several passes instead of cutting the full depth at once.
/// This function provides a default value as millimeters or inches.
pub fn default_z_max_step(self) -> f64 {
match self {
Self::Metric => 1.0,
Self::Imperial => Self::mm_to_inch(1.0),
}
}
}
impl fmt::Display for Units {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{}",
match self {
Units::Metric => "mm",
Units::Imperial => "\"",
}
)
}
}
/// Indicates a rotation direction, this is used by the [tools](../tools/), but also when cutting [arcs](../cuts/struct.Arc.html).
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
#[serde(rename_all = "lowercase")]
pub enum Direction {
/// Clockwise direction.
#[default]
Clockwise,
/// Counter clockwise direction.
Counterclockwise,
}
impl fmt::Display for Direction {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{}",
match self {
Direction::Clockwise => "clockwise",
Direction::Counterclockwise => "counterclockwise",
}
)
}
}
/// Indicates one specific axis, mainy when cutting [arcs](../cuts/struct.Arc.html).
#[derive(Debug, Clone)]
pub enum Axis {
/// Indicates X axis.
X,
/// Indicates Y axis.
Z,
/// Indicates Z axis.
Y,
}
impl fmt::Display for Axis {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{}",
match self {
Axis::X => "X",
Axis::Y => "Y",
Axis::Z => "Z",
}
)
}
}
/// Indicates how a path should be compensated by the radius of the tool.
#[derive(Debug, Clone, Default)]
pub enum ToolPathCompensation {
/// The tool will cut at the specified path, without compensating for the radius. This is the default value.
#[default]
None,
/// The tool will cut at the inside of the path, this is useful for pocket cuts.
Inner,
/// The tool will cut at the outside of the path, this is useful for contour/frame cuts.
Outer,
}
impl fmt::Display for ToolPathCompensation {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{}",
match self {
ToolPathCompensation::None => "none",
ToolPathCompensation::Inner => "inner",
ToolPathCompensation::Outer => "outer",
}
)
}
}