kcl-samples → bench-for-kids
bench-for-kids

KCL
// Bench for kids.
// Shaped like a friendly animal and sturdy enough for climbing.
@settings(defaultLengthUnit = cm)
// Define primary parameters for the bench geometry.
benchLength = 80 // overall end-to-end size
benchWidth = 40 // overall depth (front-to-back)
seatHeight = 35
// SEATING BLOCK (half-cylinder, rounded side up so it feels like an animal back)
// Because it's half a cylinder, the bench width equals the cylinder’s diameter.
benchSeatRadius = benchWidth / 2
// Height of the flat face of the cylinder: seat height minus cylinder radius.
benchSeatElevation = seatHeight - benchSeatRadius
// Center the bench in the scene by creating a sketch plane offset by half length.
seatSketchPlane = offsetPlane(XZ, offset = -benchLength / 2)
// Flat face of the cylinder sits one radius below the seat.
seatSketch = startSketchOn(seatSketchPlane)
seatProfile = startProfile(seatSketch, at = [-benchSeatRadius, benchSeatElevation])
|> arc(interiorAbsolute = [0, seatHeight], endAbsolute = [benchSeatRadius, benchSeatElevation])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
seatBody = extrude(seatProfile, length = benchLength)
// LEGS (four chunky, rounded cylinders)
legRadius = benchWidth * 0.12 // scale with bench width so model stays parametric
// Build one leg, then pattern-copy it to make the full set.
legSketch = startSketchOn(XY)
legProfile = circle(
legSketch,
center = [0, 0],
radius = legRadius,
tag = $legCircle,
)
// Make the leg a bit longer because it will be tilted later.
legHeight = benchSeatElevation * 1.1
legExtrudedBody = extrude(legProfile, length = legHeight, tagStart = $legCapStart)
// Round the foot: use a slightly smaller radius to avoid fillet errors.
legFilletRadius = legRadius * 0.9
legBody = fillet(
legExtrudedBody,
radius = legFilletRadius,
tags = [
getCommonEdge(faces = [legCircle, legCapStart])
],
)
// Position and array the legs.
legChassisWidth = benchWidth * 0.6
legChassisLength = benchLength * 0.8
firstLeg = translate(
legBody,
x = -legChassisWidth / 2,
y = -legChassisLength / 2,
z = 0,
)
// Pattern in X, then Y, to create all four legs.
allFourLegs = patternLinear3d(
firstLeg,
instances = 2,
distance = legChassisWidth,
axis = [1, 0, 0],
)
|> patternLinear3d(instances = 2, distance = legChassisLength, axis = [0, 1, 0])
// EARS (two small cylinders, tilted sideways slightly)
earHeight = 20
earRadius = legRadius * 0.9
earFilletRadius = earRadius * 0.9
earTiltAngle = 13
earDistance = benchWidth * 0.4 // defined for completeness, currently unused
earElevation = seatHeight * 0.9
// Ears sit roughly above the front legs.
earOffsetForward = legChassisLength / 2
earSketch = startSketchOn(offsetPlane(XY, offset = 0))
earProfile = circle(
earSketch,
center = [0, 0],
radius = earRadius,
tag = $earCircle,
)
earBody = extrude(earProfile, length = earHeight, tagEnd = $earCapEnd)
|> fillet(
radius = earFilletRadius,
tags = [
getCommonEdge(faces = [earCircle, earCapEnd])
],
)
|> translate(x = 0, y = -earOffsetForward, z = earElevation)
|> rotate(
roll = 0,
pitch = earTiltAngle,
yaw = 0,
global = true,
)
// Copy the first ear over to the other side with a circular array.
ears = patternCircular3d(
earBody,
instances = 2,
axis = [0, 1, 0],
center = [0, 0, 0],
arcDegrees = -earTiltAngle * 2,
)
// TAIL (single cylinder at the rear, slightly rotated downward)
tailPlane = offsetPlane(XZ, offset = -benchLength * 0.45)
tailLength = earHeight * 1.2
tailRadius = earRadius * 0.9
tailFilletRadius = tailRadius * 0.9
tailElevation = benchSeatElevation + benchSeatRadius * 0.9
tailSketch = startSketchOn(tailPlane)
tailProfile = circle(
tailSketch,
center = [0, 0],
radius = tailRadius,
tag = $tailCircle,
)
tailBody = extrude(tailProfile, length = -tailLength, tagStart = $tailCapStart)
|> fillet(
radius = tailFilletRadius,
tags = [
getCommonEdge(faces = [tailCircle, tailCapStart])
],
)
|> rotate(roll = -10, pitch = 0, yaw = 0)
|> translate(
x = 0,
y = 0,
z = tailElevation,
global = true,
)