Something went wrong. Try again.
A three.js based web UI to create and export vases using code.
Something went wrong. Try again.
2.7 kB · 90 lines
TypeScript
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091import type { BooleanMode } from '../geometry/csg.ts'import { subtract, taggedCylinder, union } from '../geometry/csg.ts'import { loft as buildLoft, ring as buildRing, vec } from '../geometry/mesh.ts'import type { Shape, Vec3 } from '../geometry/types.ts'
export type ParamValue = number | string | boolean
export interface RunResult { shape: Shape | null /** Parameter names declared via setParams(), in declaration order. */ declared: string[] /** Current parameter values after the run (overrides applied on top of defaults). */ params: Record<string, ParamValue> error: string | null}
export interface ShapeGlobals { setParams: (defaults: Record<string, ParamValue>) => void params: Record<string, ParamValue> vec: typeof vec ring: (points: unknown[]) => Vec3[] loft: typeof buildLoft cylinder: typeof taggedCylinder cut: (a: Shape, b: Shape) => Shape fuse: (a: Shape, b: Shape) => Shape result: (s: Shape) => void}
export interface RunOptions { overrides?: Record<string, ParamValue> mode?: BooleanMode}
export function runShape(script: string, opts: RunOptions = {}): RunResult { const overrides = opts.overrides ?? {} const mode = opts.mode ?? 'fast'
const params: Record<string, ParamValue> = { ...overrides } const declared: string[] = [] let shape: Shape | null = null
const globals: ShapeGlobals = { setParams: (defaults) => { for (const key of Object.keys(defaults)) { if (!(key in params)) params[key] = defaults[key] if (!declared.includes(key)) declared.push(key) } }, params, vec, ring: buildRing, loft: buildLoft, cylinder: taggedCylinder, cut: (a, b) => subtract(a, b, mode), fuse: (a, b) => union(a, b, mode), result: (s) => { shape = s }, }
let error: string | null = null try { const fn = new Function( 'setParams', 'params', 'vec', 'ring', 'loft', 'cylinder', 'cut', 'fuse', 'result', script, ) fn(globals.setParams, params, globals.vec, globals.ring, globals.loft, globals.cylinder, globals.cut, globals.fuse, globals.result) } catch (e) { error = e instanceof Error ? e.message : String(e) if (e instanceof Error && e.stack) error += `\n${e.stack}` }
// Order params by declaration order (not by override insertion order, which // would shuffle the slider panel whenever the user tweaks a middle param). const ordered: Record<string, ParamValue> = {} for (const key of declared) ordered[key] = params[key] for (const key of Object.keys(params)) { if (!(key in ordered)) ordered[key] = params[key] }
return { shape, declared, params: ordered, error }}