add some models

This commit is contained in:
Robin Appelman 2025-12-12 17:43:23 +01:00
commit 5c5b0b3768
2 changed files with 264 additions and 0 deletions

View file

@ -0,0 +1,22 @@
use std::ops::*;
use std::math::*;
use std::geo3d::*;
use gridfinity::*;
mod gridfinity;
fn getOffset(units: Integer) -> Length {
if units > 1 {
return 5.1mm;
} else {
return 3.2mm;
}
}
part Holder(diameter: Length) {
units = int(diameter / BasicUnitXY) + 1;
Box(gridsX = units, gridsY = units, gridsZ = 4, magents = true) - Cylinder(radius = diameter / 2, height = 100mm, offset = getOffset(units));
}
#[resolution = 200%]
Holder(60.5mm);

242
models/gridfinity.µcad Normal file
View file

@ -0,0 +1,242 @@
/// Ported from https://github.com/Zergie/gridfinity-UltraLight, not all features are supported
use std::ops::*;
use std::geo3d::*;
use std::geo2d::*;
use std::debug::assert;
const MagnetDiameter = 6.15mm;
const MagnetDepth = 2.2mm;
const WallThickness = 1.0mm;
const OffsetXY = 0.25mm;
pub const BasicUnitXY = 42.0mm;
pub const BasicUnitZ = 7.0mm;
const BasicRadius1 = 4.0mm;
const BasicRadius2 = 8.0mm;
const TopClearanceOffset = 0.6mm;
const StackingLipWidth = 2.6mm;
const LabelHeight = 1.0mm;
const MagnetRadius = 0.5 * MagnetDiameter;
/// Like std::geo3d::Cube, but not centered
part CornerCube(width: Length, height: Length, depth: Length) {
Rect(width, height, x = 0mm, y = 0mm).extrude(z = depth)
}
part BinClean(gridsX: Scalar, gridsY: Scalar, gridsZ: Scalar, magents: Bool) {
baseCleans = BinBaseCleanSingle(startX = [0..gridsX - 1] * BasicUnitXY, startY = [0..gridsY - 1] * BasicUnitXY, magents);
xCorners = [BasicRadius1, (gridsX * BasicUnitXY) - BasicRadius1];
yCorners = [BasicRadius1, (gridsY * BasicUnitXY) - BasicRadius1];
radius0 = BasicRadius1 - OffsetXY;
height0 = 4.40mm;
around = CornerCube(width = gridsX * BasicUnitXY, height = gridsY * BasicUnitXY, depth = gridsZ * BasicUnitZ) -
Cylinder(height = gridsZ * BasicUnitZ, radius = radius0, offset = 0mm).translate(x = xCorners, y = yCorners).hull();
bellowHeight = 12.0mm;
bellow = CornerCube(width = gridsX * BasicUnitXY, height = gridsY * BasicUnitXY, depth = bellowHeight).translate(z = -bellowHeight);
around | baseCleans | bellow
}
part BinBaseCleanSingle(startX: Length = 0.0mm, startY: Length = 0.0mm, widthX = 1.0, widthY = 1.0, magents: Bool) {
radius0 = 1.05mm - OffsetXY;
radius1 = 1.85mm - OffsetXY;
radius2 = BasicRadius1 - OffsetXY;
height0 = 0.80mm;
height1 = 1.80mm;
height2 = 2.15mm;
base = CornerCube(width = widthX * BasicUnitXY, height = widthY * BasicUnitXY, depth = height0 + height1 + height2)
.translate(x = startX, y = startY);
corners = (
x = [startX + BasicRadius1, startX + (widthX * BasicUnitXY) - BasicRadius1],
y = [startY + BasicRadius1, startY + (widthY * BasicUnitXY) - BasicRadius1]
);
cutout = HullStack(corners, heights = [height0, height1, height2], radii = [
radius0,
radius1,
radius1,
radius2
]);
if (magents & (widthX == 1.0) & (widthY == 1.0)) {
(base - cutout) | MagnetHoles(startX, startY)
} else {
base - cutout
}
}
part MagnetHoles(startX: Length = 0.0mm, startY: Length = 0.0mm) {
xCorners = [startX + BasicRadius2, startX + BasicUnitXY - BasicRadius2];
yCorners = [startY + BasicRadius2, startY + BasicUnitXY - BasicRadius2];
Cylinder(height = MagnetDepth, radius = MagnetRadius, offset = 0mm).translate(x = xCorners, y = yCorners)
}
part BinBody(gridsX: Scalar, gridsY: Scalar, gridsZ: Scalar, hollow: Bool) {
radius0 = BasicRadius1 - OffsetXY;
height0 = 4.75mm;
height1 = 7.0mm - height0;
height2 = (gridsZ - 1) * BasicUnitZ;
corners = (
x = [BasicRadius1, gridsX * BasicUnitXY - BasicRadius1],
y = [BasicRadius1, gridsY * BasicUnitXY - BasicRadius1]
);
base = Cylinder(height = height1 + height2, radius = radius0, offset = 0mm)
.translate(x = corners.x, y = corners.y, height0)
.hull();
cutout = Cylinder(height = height1 + height2, radius = radius0 - WallThickness, offset = 0mm)
.translate(x = corners.x, y = corners.y, height0)
.hull();
if hollow {
base - cutout
} else {
base
}
}
part BinBaseSingle(startX: Length = 0.0mm, startY: Length = 0.0mm, widthX = 1.0, widthY = 1.0, magents: Bool, ultraLight: Bool) {
radius0 = 1.05mm - OffsetXY;
radius1 = 1.85mm - OffsetXY;
radius2 = BasicRadius1 - OffsetXY;
height0 = 0.80mm;
height1 = 1.80mm;
height2 = 2.15mm;
corners = (
x = [startX + BasicRadius1, startX + widthX * BasicUnitXY - BasicRadius1],
y = [startY + BasicRadius1, startY + widthY * BasicUnitXY - BasicRadius1]
);
outside = CornerCube(width = widthX * BasicUnitXY, height = widthY * BasicUnitXY, depth = height0 + height1 + height2 + WallThickness)
.translate(x = startX, y = startY);
ultraLightCutout = HullStack(
corners,
heights = [
height0 - 0.5858 * WallThickness,
height1,
height2,
1.4142 * WallThickness
],
radii = [
radius0 - 0.4142 * WallThickness,
radius1 - WallThickness,
radius1 - WallThickness,
radius2 - WallThickness,
radius2
],
offset = WallThickness
);
showMagnets = magents & (widthX == 1.0) & (widthY == 1.0);
magnetCutout = MagnetHoles(startX, startY);
magnetXCorners = [startX + BasicRadius2, startX + widthX * BasicUnitXY - BasicRadius2];
magnetYCorners = [startY + BasicRadius2, startY + widthY * BasicUnitXY - BasicRadius2];
magnetOutside = Cylinder(height = MagnetDepth + WallThickness, radius = MagnetRadius + WallThickness, offset = 0mm).translate(x = magnetXCorners, y = magnetYCorners) - magnetCutout;
if (ultraLight & showMagnets) {
(outside - ultraLightCutout - magnetCutout) | magnetOutside;
} else if (ultraLight) {
outside - ultraLightCutout;
} else if (showMagnets) {
(outside | magnetOutside) - magnetCutout;
} else {
outside
}
}
part BinBase(gridsX: Scalar, gridsY: Scalar, gridsZ: Scalar, magents: Bool, ultraLight: Bool) {
BinBaseSingle(startX = [0..gridsX - 1] * BasicUnitXY, startY = [0..gridsY - 1] * BasicUnitXY, magents, ultraLight);
}
part BinStacklip(gridsX: Scalar, gridsY: Scalar, gridsZ: Scalar) {
radius0 = 1.15mm;
radius1 = 1.85mm;
radius2 = BasicRadius1 - OffsetXY;
height0 = StackingLipWidth - WallThickness;
height1 = 0.60mm;
height2 = 0.70mm;
height3 = 1.80mm;
height4 = 1.90mm;
height5 = 0.75mm;
heightStart = (gridsZ * BasicUnitZ) - (height0 + height1);
xCorners = [BasicRadius1, gridsX * BasicUnitXY - BasicRadius1];
yCorners = [BasicRadius1, gridsY * BasicUnitXY - BasicRadius1];
outer = Cylinder(height = height0 + height1 + height2 + height3 + height4 + height5, radius = radius2, offset = 0mm).translate(x = xCorners, y = yCorners, z = heightStart).hull();
cutouts = HullStack((x = xCorners, y= yCorners), heights = [height0, height1, height2, height3, height4, height5], radii = [
radius2 - WallThickness,
radius0,
radius0,
radius1,
radius1,
radius2,
radius2
], offset = heightStart);
outer - cutouts
}
part HullStack(corners: (x: [Length], y: [Length]), heights: [Length], radii: [Length], offset: Length = 0mm) {
assert(heights.count() == radii.count() - 1, "radii must be an array with one more elements that heights");
self = Cylinder(height = heights.head(), radius_bottom = radii.head(), radius_top = radii.tail().head(), offset)
.translate(x = corners.x, y = corners.y).hull();
if heights.count() > 1 {
self | HullStack(corners, heights = heights.tail(), radii = radii.tail(), offset = offset + heights.head())
} else {
self
}
}
// A basic bin
pub part Bin(gridsX = 1, gridsY = 1, gridsZ = 1, magents: Bool = false, ultraLight: Bool = false, center: Bool = true) {
bin = BinBody(gridsX, gridsY, gridsZ, hollow = true) |
BinBase(gridsX, gridsY, gridsZ, magents, ultraLight) |
BinStacklip(gridsX, gridsY, gridsZ) -
BinClean(gridsX, gridsY, gridsZ, magents);
if center {
bin.translate(x = -gridsX * BasicUnitXY / 2, y = -gridsY * BasicUnitXY / 2)
} else {
bin
}
}
part Box_(gridsX = 1, gridsY = 1, gridsZ = 1, magents: Bool = false, lip: Bool = true, center: Bool = true) {
if lip {
BinBody(gridsX, gridsY, gridsZ, hollow = false) |
BinBase(gridsX, gridsY, gridsZ, magents, ultraLight = false) |
BinStacklip(gridsX, gridsY, gridsZ) -
BinClean(gridsX, gridsY, gridsZ, magents)
} else {
BinBody(gridsX, gridsY, gridsZ, hollow = false) |
BinBase(gridsX, gridsY, gridsZ, magents, ultraLight = false) -
BinClean(gridsX, gridsY, gridsZ, magents)
}
}
/// A solid box, intended as the base for custom cutouts
pub part Box(gridsX = 1, gridsY = 1, gridsZ = 1, magents: Bool = false, lip: Bool = true, center: Bool = true) {
box = Box_(gridsX, gridsY, gridsZ, magents, lip, center);
if center {
box.translate(x = -gridsX * BasicUnitXY / 2, y = -gridsY * BasicUnitXY / 2)
} else {
box
}
}
Box(gridsX = 2)