microcad-std 0.4.0

µcad Standard Library
Documentation
// Copyright © 2025-2026 The µcad authors <info@microcad.xyz>
// SPDX-License-Identifier: AGPL-3.0-or-later

pub use __builtin::ops::center;
pub use __builtin::ops::hull;
pub use __builtin::ops::intersect;
pub use __builtin::ops::subtract;
pub use __builtin::ops::multiply;
pub use __builtin::ops::union;

/// Align a geometry collection along an axis with a certain spacing.
pub op align(direction: Vec3, spacing = 0mm) {
    @input.__builtin::ops::align(
        x = direction.x,
        y = direction.y,
        z = direction.z,
        spacing
    )
}

/// Create a new geometry whose boundary is offset the specified distance from the input.
pub op buffer(distance: Length) {
    @input.__builtin::ops::buffer(distance);
}

/// Generate a contour geometry out of an input geometry.
pub op contour(thickness: Length, distance = 0mm) {
    @input.buffer(distance + thickness / 2) - @input.buffer(distance - thickness / 2);
}


/// Distribute geometries within a 2D rectangular grid.
///
/// The `distribute_grid` operator arranges elements evenly inside a rectangular region,
/// subdivided into a specified number of rows and columns. Each grid cell receives
/// one element, allowing for structured placement of objects, points, or geometries.
///
/// The grid is defined by its position (`x`, `y`), total dimensions (`width`, `height`),
/// and subdivision counts (`rows`, `columns`).
pub op distribute_grid(x: Length, y: Length, width: Length, height: Length, rows: Integer, columns: Integer) {
    /// Initialize a centered rectangular grid.
    init(width: Length, height: Length, rows: Integer, columns: Integer) {
        x = -width / 2.0; // center x
        y = -height / 2.0; // center y
    }

    /// Initialize a centered square grid.
    ///
    /// The `init` helper simplifies grid creation by specifying a single `size`
    /// value instead of separate width and height. It automatically centers
    /// the grid around the origin and defines its overall dimensions.
    init(size: Length, rows: Integer, columns: Integer) {
        width = size;
        height = size;
        x = -size / 2.0; // center x
        y = -size / 2.0; // center y
    }

    /// Initialize a centered grid with a squared cell size.
    ///
    /// The `init` helper simplifies grid creation by specifying a single `cell_size`
    /// value instead of separate width and height. It automatically centers
    /// the grid around the origin and defines its overall dimensions.
    init(cell_size: Length, rows: Integer, columns: Integer) {
        width = cell_size * columns;
        height = cell_size * rows;
        x = -width / 2.0; // center x
        y = -height / 2.0; // center y
    }


    @input.__builtin::ops::distribute_grid(x, y, width, height, rows, columns)
}

/// Linear extrude a 2D geometry into a 3D.
pub op extrude(
        height: Length,
        scale = (x = 100%, y = 100%),
        twist = 0°,
) {
    @input.__builtin::ops::extrude(height, scale_x = scale.x, scale_y = scale.y, twist);
}

/// Mirror along an axis, keeping existing geometry.
pub op mirror(x = 0.0mm, y = 0.0mm, z = 0.0mm, n: Vec3) {
    @input.__builtin::ops::mirror(
        x, y, z, nx = n.x, ny = n.y, nz = n.z
    )
}

/// Orient an object towards a vector.
pub op orient(v: Vec3) {
    @input.__builtin::ops::orient(x = v.x, y = v.y, z = v.z);
}

/// Reflect a geometry along an axis.
pub op reflect(x = 0.0mm, y = 0.0mm, z = 0.0mm, n: Vec3) {
    @input.__builtin::ops::reflect(
        x, y, z, nx = n.x, ny = n.y, nz = n.z
    )
}

/// Revolve a geometry around 360°.
pub op revolve(angle = 360°) {
    @input.__builtin::ops::revolve(angle);
}

/// An operation that rotates a part.
///
/// See the `init`s for examples on how to use this operation. 
pub op rotate(matrix: Matrix3) {
    /// Rotate around an axis by an angle using a 3D vector.
    /// 
    /// The `axis` vector will be normalized. 
    ///
    /// * `angle` - An angle.
    /// * `axis` - An axis to rotate around (Z axis is default).
    ///
    /// Examples:
    /// * `Rect(42mm).rotate(45°);`: 2D rotation of a square by 45°.
    /// * `Cube(42mm).rotate(45°, (x = 1, y = 1, z = 1)) ;`: Rotates a cube by 45° around a diagonal axis.
    /// * `Cube(42mm).rotate(30°, Y);`: Rotates a cube by 30° around Y axis.
    init(angle: Angle, axis = __builtin::math::Z) {
        matrix = __builtin::math::rotate_around_axis(angle, x = axis.x, y = axis.y, z = axis.z);
    }
    
    /// Euler rotation around X, Y, Z.
    ///
    /// * `x` - X angle.
    /// * `y` - Y angle.
    /// * `z` - Z angle.
    ///
    /// Examples:
    /// * `Cube(42mm).rotate(45°, (1, 0, 0));`: Rotates a cylinder by 45° around X axis (unnamed tuple).
    init(x = 0°, y = 0°, z = 0°) {
        matrix = __builtin::math::rotate_xyz(x, y, z);        
    }
    
    /// Euler rotation around X, Y, Z (nautical angles)
    ///
    /// * `roll` - Roll angle, rotates around X axis.
    /// * `pitch` - Pitch angle, rotates around Y axis.
    /// * `yaw` - Yaw angle, rotates around Z axis.
    ///
    /// Example:
    /// * `Cube(42mm).rotate(roll = 30°)`: Rotates a cylinder by 45° around X axis.
    init(roll = 0°, pitch = 0°, yaw = 0°) {
        matrix = __builtin::math::rotate_xyz(roll, pitch, yaw);
    }
    
    /// Euler rotation around X, Y and Z axis (with a vector of angles)
    ///
    /// * `Cube(42mm).rotate(xyz = (30°,20°,10°))`: Euler rotation for a cube around X, Y, Z axis.
    init(xyz = (x = 0°,y = 0°,z = 0°)) {
        matrix = __builtin::math::rotate_xyz(xyz.x, xyz.y, xyz.z);
    }
    
    /// Euler rotation around Z, Y and X axis (with a vector of angles)
    ///
    /// * `Cube(42mm).rotate(zyx = (30°,20°,10°));`: Euler rotation for a cube around Z, Y, X axis.
    init(zyx = (x = 0°, y = 0°, z = 0°)) {
        matrix = __builtin::math::rotate_zyx(zyx.z, zyx.y, zyx.x);
    }

    @input.__builtin::ops::rotate(matrix);
}

/// An operation that scales a part.
///
/// See the `init`s for examples on how to use this operation. 
pub op scale(v: Vec3) {
    /// Uniform scale.
    /// 
    /// * `s` - Scale factor.
    ///
    /// Examples:
    /// * `Rect(42mm).scale(200%);`: Scale a rectangle by 200%.
    init(s: Scalar) {
        v = (x = s, y = s, z = s);
    }

    /// Non-uniform scale.
    /// 
    /// * `x` - Scale factor in X direction.
    /// * `y` - Scale factor in Y direction.
    /// * `z` - Scale factor in Z direction.
    ///
    /// Examples:
    /// * `Rect(42mm).scale(x = 2.0);`: Scale a rectangle in X direction.
    init(x: Scalar = 1.0, y: Scalar = 1.0, z: Scalar = 1.0) {
        v = (x = x, y = y, z = z);
    }

    @input.__builtin::ops::scale(x = v.x, y = v.y, z = v.z);
}

/// Create a spiral with a height and an inner and outer radius.
pub op spiralize(
    inner_radius: Length, 
    outer_radius: Length,
    angle: Angle,
    height = 0mm
) {
    @input.__builtin::ops::spiralize(height, inner_radius, outer_radius, angle);
}

/// An operation that translates (moves) a geometry.
pub op translate(x = 0.0mm, y = 0.0mm, z = 0.0mm) {
    /// Polar-style translate with distance and angle.
    init(distance: Length, angle: Angle) {
        x = distance * __builtin::math::cos(angle);
        y = distance * __builtin::math::sin(angle);
        z = 0.0mm;
    }

    @input.__builtin::ops::translate(x, y, z);
}