Operations
Standalone functions for combining and manipulating meshes.
merge
Combine multiple meshes into one. Automatically normalizes attributes (colors, UVs, normals) and handles mixed indexed/non-indexed geometry.
import { merge, box, sphere } from 'shapecraft'
const combined = merge(
box().translate(-1, 0, 0),
sphere().translate(1, 0, 0),
)
center
Recenter a mesh’s bounding box to the origin.
import { center } from 'shapecraft'
const centered = center(mesh)
clone
Deep copy a mesh.
import { clone } from 'shapecraft'
const copy = clone(mesh)
loft, tube & thicken
loft
Sweep a 2D cross-section along a 3D path. The cross-section is oriented using rotation-minimizing frames (or a fixed up vector).
import { loft } from 'shapecraft'
// Fixed cross-section
loft({
path: [[0,0,0], [0,1,0], [0.5,2,0]],
shape: [[-0.1,0], [0.1,0], [0,0.1]],
})
// Varying cross-section (tapered leaf shape)
loft({
path: frondPath,
shape: (t) => {
const w = 0.3 * (1 - t)
return [[-w, 0], [0, w*0.3], [w, 0]]
},
closedShape: false, // open cross-section (no bottom)
closed: false, // no end caps
up: [0, 1, 0], // keep cross-section aligned to world up
})
Options:
shape—[x,y][]or(t: number) => [x,y][]for varying along pathclosed— cap the ends (defaulttrue)closedShape— connect last shape point to first (defaulttrue)up— reference up vector for consistent orientation (default: auto)
tube
Shorthand for circular loft — sweep a radius along a path. Great for branches, vines, trunks.
import { tube } from 'shapecraft'
// Fixed radius
tube([[0,0,0], [0,1,0], [0.3,2,0]], 0.05, 6)
// Tapered — radius function of t (0-1 along path)
tube(path, (t) => 0.1 * (1 - t), 6)
// Palm trunk with bulge waves
tube(path, (t) => {
const taper = 0.1 * (1 - t * 0.6)
const wave = 1 + Math.sin(t * Math.PI * 14) * 0.15
return taper * wave
}, 5)
thicken
Give a flat mesh depth by duplicating it, offsetting along normals, and stitching boundary edges. Works best with indexed geometry (e.g. from loft).
import { thicken } from 'shapecraft'
const leaf = thicken(flatLeafMesh, 0.02)