kittycad_modeling_cmds/
length_unit.rs

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
//! A length unit is a type that converts a length value from one unit to another.
//! In the case of the engine we will always convert to millimeters, since that is what the engine uses.

use serde::{Deserialize, Serialize};

use crate::shared::{Point2d, Point3d, Point4d};

/// A length unit is wrapper around an f64 that represents a length in some unit.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, Default)]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
pub struct LengthUnit(pub f64);

impl LengthUnit {
    /// Get the value of the length unit in millimeters.
    /// This is how we convert for the engine.
    pub fn to_millimeters(&self, from: crate::units::UnitLength) -> f64 {
        from.convert_to(crate::units::UnitLength::Millimeters, self.0)
    }

    /// Get the value from millimeters to the length unit.
    pub fn from_millimeters(&self, to: crate::units::UnitLength) -> LengthUnit {
        LengthUnit(crate::units::UnitLength::Millimeters.convert_to(to, self.0))
    }
}

impl Point3d<LengthUnit> {
    /// Convert the point to millimeters.
    pub fn to_millimeters(&self, from: crate::units::UnitLength) -> Point3d<f64> {
        Point3d {
            x: self.x.to_millimeters(from),
            y: self.y.to_millimeters(from),
            z: self.z.to_millimeters(from),
        }
    }
}

impl Point3d<f64> {
    /// Convert the point from millimeters.
    pub fn from_millimeters(&self, to: crate::units::UnitLength) -> Point3d<LengthUnit> {
        Point3d {
            x: crate::units::UnitLength::Millimeters.convert_to(to, self.x).into(),
            y: crate::units::UnitLength::Millimeters.convert_to(to, self.y).into(),
            z: crate::units::UnitLength::Millimeters.convert_to(to, self.z).into(),
        }
    }
}

impl Point2d<LengthUnit> {
    /// Convert the point to millimeters.
    pub fn to_millimeters(&self, from: crate::units::UnitLength) -> Point2d<f64> {
        Point2d {
            x: self.x.to_millimeters(from),
            y: self.y.to_millimeters(from),
        }
    }
}

impl Point2d<f64> {
    /// Convert the point from millimeters.
    pub fn from_millimeters(&self, to: crate::units::UnitLength) -> Point2d<LengthUnit> {
        Point2d {
            x: crate::units::UnitLength::Millimeters.convert_to(to, self.x).into(),
            y: crate::units::UnitLength::Millimeters.convert_to(to, self.y).into(),
        }
    }
}

impl Point4d<LengthUnit> {
    /// Convert the point to millimeters.
    pub fn to_millimeters(&self, from: crate::units::UnitLength) -> Point4d<f64> {
        Point4d {
            x: self.x.to_millimeters(from),
            y: self.y.to_millimeters(from),
            z: self.z.to_millimeters(from),
            w: self.w.0,
        }
    }
}

impl Point4d<f64> {
    /// Convert the point from millimeters.
    pub fn from_millimeters(&self, to: crate::units::UnitLength) -> Point4d<LengthUnit> {
        Point4d {
            x: crate::units::UnitLength::Millimeters.convert_to(to, self.x).into(),
            y: crate::units::UnitLength::Millimeters.convert_to(to, self.y).into(),
            z: crate::units::UnitLength::Millimeters.convert_to(to, self.z).into(),
            w: LengthUnit(self.w),
        }
    }
}

impl schemars::JsonSchema for LengthUnit {
    fn schema_name() -> String {
        "LengthUnit".to_string()
    }

    fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
        <f64>::json_schema(gen)
    }
}

impl From<f64> for LengthUnit {
    fn from(value: f64) -> Self {
        LengthUnit(value)
    }
}

impl std::ops::Neg for LengthUnit {
    type Output = Self;

    fn neg(self) -> Self::Output {
        LengthUnit(-self.0)
    }
}

impl std::ops::Add for LengthUnit {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        LengthUnit(self.0 + rhs.0)
    }
}

impl std::ops::Sub for LengthUnit {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        LengthUnit(self.0 - rhs.0)
    }
}

impl std::ops::Mul<f64> for LengthUnit {
    type Output = Self;

    fn mul(self, rhs: f64) -> Self::Output {
        LengthUnit(self.0 * rhs)
    }
}

impl std::ops::Div<f64> for LengthUnit {
    type Output = Self;

    fn div(self, rhs: f64) -> Self::Output {
        LengthUnit(self.0 / rhs)
    }
}