microcad_lang/model/
operation.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Operation trait.
5
6use crate::{model::*, render::*};
7use microcad_core::*;
8
9/// Operation trait.
10pub trait Operation {
11    /// The output type of this operation.
12    ///
13    /// By default, the output type is undetermined.
14    fn output_type(&self) -> OutputType {
15        OutputType::NotDetermined
16    }
17
18    /// Process the model and output a 2D geometry.
19    fn process_2d(&self, _context: &mut RenderContext) -> RenderResult<Geometry2DOutput> {
20        unimplemented!()
21    }
22
23    /// Process the model and output a 3D geometry.
24    fn process_3d(&self, _context: &mut RenderContext) -> RenderResult<Geometry3DOutput> {
25        unimplemented!()
26    }
27}
28
29/// Transformation matrix
30#[derive(Clone, Debug)]
31pub enum AffineTransform {
32    /// Translation.
33    Translation(Vec3),
34    /// Generic rotation.
35    Rotation(Mat3),
36    /// Scale.
37    Scale(Vec3),
38    /// Uniform scale.
39    UniformScale(Scalar),
40}
41
42impl AffineTransform {
43    /// Get the 2D transformation matrix
44    pub fn mat2d(&self) -> Mat3 {
45        match self {
46            AffineTransform::Translation(v) => Mat3::from_translation(Vec2::new(v.x, v.y)),
47            AffineTransform::Rotation(m) => Mat3::from_cols(
48                Vec3::new(m.x.x, m.x.y, 0.0),
49                Vec3::new(m.y.x, m.y.y, 0.0),
50                Vec3::new(0.0, 0.0, 1.0),
51            ),
52            AffineTransform::Scale(v) => Mat3::from_nonuniform_scale(v.x, v.y),
53            AffineTransform::UniformScale(s) => Mat3::from_scale(*s),
54        }
55    }
56
57    /// Get the 3D transformation matrix
58    pub fn mat3d(&self) -> Mat4 {
59        match self {
60            AffineTransform::Translation(v) => Mat4::from_translation(*v),
61            AffineTransform::Rotation(a) => Mat4::from_cols(
62                a.x.extend(0.0),
63                a.y.extend(0.0),
64                a.z.extend(0.0),
65                Vec3::new(0.0, 0.0, 0.0).extend(1.0),
66            ),
67            AffineTransform::Scale(v) => Mat4::from_nonuniform_scale(v.x, v.y, v.z),
68            AffineTransform::UniformScale(s) => Mat4::from_scale(*s),
69        }
70    }
71}