// 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);
}