Model Editor Workflows

Multi-step recipes you can paste into the Script Editor while the Model Editor is open. Each one builds, queries, or transforms geometry across several methods, and verifies the result with console.log or an inline check.

File I/O

  • Parent / unparent / delete nodes, add an image plane, and clear the scene

    Spawn nodes; parent and unparent them; add an image plane; open a project; delete the nodes; clear the scene.

    Example
    What you'll seeconsole: parent/unparent ops; imagePlane and openScene probes; final clear-scene result.

Viewport & Camera

Geometry & Topology

  • Tally the surface area of every mesh

    Walk every mesh in the asset, read mesh.area and mesh.bbox extents, and log a CSV summary you can copy out.

    Example
    What you'll seeA CSV block printed to the console (name,area,bbX,bbY,bbZ) plus a summary line with the total area.
  • Mark every vertex of a mesh with a small sphere

    Build a low-poly mesh, then mark every vertex with a tiny sphere at its world position and parent the lot under a group. Handy for visually debugging topology.

    Example
    What you'll seeconsole: vertex count + sphere radius used; viewport: a small sphere on each vertex, parented under one group.
  • Summarize the UV island layout on every mesh

    Build a couple of meshes, then read mesh.uv.islands on each: log the island count and per-island UV-space size for a quick "is this UV layout sane" sweep.

    Example
    What you'll seeconsole: per-mesh island count; per-island index + UV size + face count.
  • Report per-mesh topology stats

    Walk every mesh and log face / vertex / edge counts plus surface area. Handy for catching outliers before export.

    Example
    What you'll seeconsole: per-mesh table-like line with faces, verts, edges, area; totals at the bottom.
  • Build a cube, sphere, and cylinder and group them

    Create three primitive meshes, place them at offset positions so they do not overlap, then wrap them under one named group and log the group bounding box.

    Example
    What you'll seeconsole: each primitive name + final group bounding-box span; outliner: a new group containing three meshes.
  • Subdivide a cube and bend it

    Start with a 1m cube, subdivide it twice to add resolution, bend it 60 degrees around the Y axis, and log the before / after vertex count.

    Example
    What you'll seeconsole: starting / post-subdivide / post-bend vertex count + final bbox size in meters.
  • Cut a hole through a cube with a sphere

    Build a cube, position a smaller sphere inside it, run a difference boolean, and log the resulting vertex and face counts.

    Example
    What you'll seeconsole: cube counts before / after the cut, plus the final face count of the carved cube.
  • Extrude a tall tower and bevel its top edges

    Take a 1m cube, extrude the top face upward to make a tower, then bevel every edge on the top so it has a soft chamfer.

    Example
    What you'll seeconsole: face counts after each step + final bbox height.
  • Unwrap a cube and pin a UV corner

    Create a cube, run an automatic UV unwrap, then pin a single UV so subsequent re-unwraps preserve that corner. Logs the UV count and the pinned position.

    Example
    What you'll seeconsole: number of UVs before / after the unwrap and the pinned UV position.
  • Topology query and manifold audit across primitives

    Spawn cube + sphere + plane (with explicit deselect between via select(null, {mode: "clear"})); query isClosed / isManifold / holes / shells / triangle counts.

    Example
    What you'll seeconsole: per-mesh closed/manifold/holes/shells/triangle counts.
  • Vertex iteration + nearest / within radius queries

    Spawn a subdivided cube; forEachVertex + log; query nearestVertices + verticesWithin.

    Example
    What you'll seeconsole: cube vertex count, point sample, nearest-5 verts, within-radius count.
  • Raycast a sphere and place a locator at the hit

    Spawn a sphere; raycast from camera origin; place a locator at the hit; query closestPoint to a test position.

    Example
    What you'll seeconsole: raycast hit + locator placement + closestPoint result.
  • Reverse / recalc / smooth normals

    Spawn a cube; flip normals; recalculate; smooth; inspect getNormals at each step.

    Example
    What you'll seeconsole: normal sample at each step.
  • Three cubes with varied bevel strategies (vertex / flat-edge / rounded-edge)

    Spawn three cubes; bevelVertices on one, a single-segment (flat) edge bevel on another, a multi-segment (rounded) edge bevel on the third; log vert/face deltas.

    Example
    What you'll seeconsole: per-cube before/after V/F counts.
  • Mutate a curve: degree, closed flag, control vertex position

    Read .numPoints / .closed / .degree; mutate via .toggleClosed / .setDegree / .setPoint.

    Example
    What you'll seeconsole: per-step CV count + closed/degree state.
  • Transform helpers: translate / rotate / scale / xform / freeze / reset

    Drive a node through the compound TRS attrs, a bulk .xform({...}) write (local + world, relative), then .freezeTransform() and .resetTransform() to see the full transform lifecycle.

    Example
    What you'll seeconsole: TRS values after each set, after relative local + world xforms, post-freeze, and post-reset.
  • Spawn 10 composite primitives in a row (arch / arrow / bolt / box / bracket / capsule / channel / compartment / cross / funnel)

    Build a contact sheet of structural shapes, deselecting between each to keep undo clean.

    Example
    What you'll seeconsole: 10 spawn lines with mesh ids; viewport reframed.
  • Spawn 13 more composite primitives (gear / heart / knob / lShape / ring / roundedBox / screw / screwAndNut / spring / star / storageBox / tShape / tube)

    Second half of the structural-primitives sweep: gears, decorative shapes, fasteners, and storage forms.

    Example
    What you'll seeconsole: 13 spawn lines confirming each primitive.
  • Build a polyline, a circle, and a rectangle curve

    Demonstrate create / createCircle / createRectangle: the three curve constructors.

    Example
    What you'll seeconsole: 3 curves created with their names.
  • Build meshes from raw verts, polylines, profiles, and revolves

    Demonstrate every non-class mesh factory: fromVertsAndFaces / empty / loft and Curve sweep methods: extrudeAlong / revolveAround / fillBoundary.

    Example
    What you'll seeconsole: one line per mesh confirming name and vert count.
  • Spawn cone, hemisphere, pyramid, torus, and wedge primitives

    Cover the five non-class poly mesh constructors that complete the primitives table.

    Example
    What you'll seeconsole: 5 primitive spawn lines with vert counts.
  • Non-linear deformer tour: bend / twist / taper / squash / wave / sine

    Spawn six subdivided cubes and apply each non-linear deformer to one. Log the resulting deformer stack on each.

    Example
    What you'll seeconsole: per-cube deformer-stack length after each non-linear add.
  • Smoothing deformer stack: smooth + deltaMush + normalPush + FFD + cage

    Layer smooth + deltaMush + normalPush + FFD + cage deformers on one cube; log the stack growing.

    Example
    What you'll seeconsole: stack length after each add (1..5).
  • Skinning, vertex-snap, shrinkwrap + reorder + remove cycle

    Add skinCluster + vertexSnap + shrinkwrap; reorder the stack; remove one; log each step.

    Example
    What you'll seeconsole: stack length and ordering at each step.
  • Face op chain: faces().inset -> faces().extrudeIndividual -> faces().extrude -> faces().delete

    On a subdivided cube, inset a face set, extrude each face individually, extrude the set together, then delete a face to open a hole. Every op is a face-selection verb (mesh.faces([...]).<verb>) and every step is wired headless; V/F deltas logged per step.

    Example
    What you'll seeconsole: V/F counts before/after each op.
  • Edge op toolkit: insertEdgeLoop (x2) + edges().bevel + merge({ distance })

    Add parallel edge loops, bevel an edge into supporting loops, add more loops, then weld doubles by distance. (offsetEdgeLoops and loopCut are interactive-tool-only / not-yet-wired — they throw from a plain script — so both loop steps use the scriptable insertEdgeLoop + edge bevel instead.)

    Example
    What you'll seeconsole: V/E counts before / after each op.
  • Slide tools: compute slide data + edgeSlide + vertexSlide + generic slide

    Compute slide data on chosen edges + vertices, then apply edgeSlide / vertexSlide at factor 0.3, plus the generic slide router.

    Example
    What you'll seeconsole: slide-data sample + verts/edges after each slide.
  • Imperative mesh builder: appendVertex + appendEdge + appendFace + bulkAppend + beginBatch

    Start from a polyPlane, append two verts, an edge, a face; run bulkAppend; demo beginBatch for coalesced authoring.

    Example
    What you'll seeconsole: V/E/F counts after each append + batch commit.
  • Topology cut tools: bisect + knife + slice + spin + mirror

    Spawn four cubes; bisect by plane, slice axis-aligned, spin around Y, mirror across X. Knife runs as a session that gets cancelled.

    Example
    What you'll seeconsole: V/F deltas across the five cut/mirror tools.
  • Deformation ops sweep: smooth / pushPull / flatten / flattenToPlane / toSphere / shear / shrinkFatten

    Spawn seven subdivided cubes; apply one deformation op to each; log V counts.

    Example
    What you'll seeconsole: per-op verts before/after.
  • Resolution control: decimate + remesh + solidify

    Decimate a sphere, voxel-remesh a separate sphere, solidify a plane; log V/F deltas.

    Example
    What you'll seeconsole: V/F before+after for decimate / remesh / solidify.
  • UV authoring suite: setUV / setUVs / transferUV / closestUV / unwrapUV / uvIsland / uvIslandAt / packUV / markSeam

    Unwrap a cube, list its UV islands, pack tightly, write one UV via setUV, write a whole UV map via setUVs, sample closestUV, mark a seam edge, and transfer the UV map to a sphere.

    Example
    What you'll seeconsole: island count, closestUV hit, transfer dst island count.
  • Vertex attribute writes: setPoints / setVertexPositions / setNormals / setVertexColor(s) / mapVertices / markSharp

    Spawn a subdivided cube; read points, mirror them with setPoints, write a per-index update with setVertexPositions, override normals + vertex colors, map every vertex through a closure, and mark sharp edges.

    Example
    What you'll seeconsole: points sample, normal/color buffer lengths, mapVertices count.
  • Mesh handle getters: id / meshId / faces / edges / vertices / verts / e / f + wireframe

    Inspect a cube via every handle getter, iterate vertices(), and tube-ify the mesh via wireframe().

    Example
    What you'll seeconsole: id, faces[0] component, e/f lengths, vertices() iterator count, V/F after wireframe.
  • Interactive sessions: polyDraw / polyPen / sculptSession / buildOnNormal / fillHoles

    Open each interactive session against a reference cube; immediately cancel or finish so the recipe runs headless.

    Example
    What you'll seeconsole: per-session handle inspection + cancel/commit confirmation.
  • Bisect tool: axis + offset + fill, then commit; cancel on a second pass

    Open a Bisect session, configure the plane (axis + offset) and fill behavior, commit a cut, then open a second session and cancel to demonstrate the abort path.

    Example
    What you'll seeconsole: session getters before commit, V/F counts after the cut, then a second session that is cancelled.
  • Build on Normal: activate the surface-stamp tool, inspect the session, then cancel

    Open the Build-on-Normal interactive session against a cube. The tool stays active so the user can click surfaces in the viewport; the script inspects every session getter then cancels.

    Example
    What you'll seeconsole: session getters confirm the tool is active, then cancel tear it down.
  • Fill Hole tool: open against an auto-detected boundary loop, place an interior vert + tri face, then commit; cancel a second pass

    Open a Fill Hole session against an auto-detected boundary loop on the live mesh. Demonstrate placeVertex (client-pixel coords) + placeFace (vertex ids) then commit; a second pass shows cancel.

    Example
    What you'll seeconsole: session getters before placement, optional placement attempts, then commit OR cancel.
  • Knife tool: open a session, addPoint twice to seed a cut line, commit; cancel a second pass

    Open the Knife session, seed two cut points (client-pixel coords) with addPoint, then commit. A second pass demonstrates cancel.

    Example
    What you'll seeconsole: session getters before the cut, optional commit, then cancel on the second pass.
  • PolyPen tool: placeVertex + placeEdge + placeFace + placeTriangleFromEdge in one session

    Open a PolyPen retopo session against a reference surface and demonstrate every placement primitive: vertex, edge, quad face, triangle from edge. Commit bakes the new geometry; a second pass cancels.

    Example
    What you'll seeconsole: session getters, placement attempts, optional commit, then cancel.
  • Slice (freeform): set two endpoints in client-pixel space, commit; cancel a second pass

    Open the freeform Slice session and drive setEndpoints with two client-pixel points to define a camera-relative cut. Commit bakes the cut; a second pass cancels.

    Example
    What you'll seeconsole: session getters, endpoint configuration, optional commit, then cancel.
  • Slice (plane, one-shot): mode + axis + offset + fill + oneShot — headless cut

    Cut a mesh headless with mesh.slice({ mode:"plane", axis, offset, fill, oneShot:true }). A non-oneShot slice returns an INTERACTIVE session and applies nothing, so a script MUST pass oneShot:true (with axis + offset) to actually cut. There is no setAxis/setOffset/setFill chain.

    Example
    What you'll seeconsole: V/F counts before and after the one-shot plane cut.
  • Slice router: open in plane mode (axis/offset) and freeform mode (endpoints) and exercise every router method

    The slice router is the public entry behind mesh.slice(): it discriminates on mode and forwards to either SlicePlaneSession or SliceFreeformSession. This recipe opens both modes and exercises every router-level method.

    Example
    What you'll seeconsole: per-mode session getters, configuration applied, optional commit, then cancel.
  • HSW honeycomb wall (grid panel)

    The HSW panel itself - a staggered grid of 20 mm hex sockets with the snap-lock lip, sized by columns and rows. Everything else clips into it.

    Example
  • HSW spring clip (snap-lock connector)

    The bare snap-in spring connector that locks into a single hex hole - push it in and the barbs catch behind the wall lip.

    Example
  • HSW friction mount (plug + back-plate)

    A back-plate carrying a lattice of friction hex plugs - the simple, render-safe foundation that accessories build on.

    Example
  • HSW Bin

    A parametric wall bin split into sections, with optional honeycomb-pattern panels on the front, back, sides, separators and bottom. Clips on with hex connectors.

    Example
  • HSW Tube Holder (diamond lattice)

    A row of round tube holders with decorative diamond-lattice walls and a bottom plate, on a hex-connector strip. Set square_size = 0 for solid (faster) walls.

    Example
  • HSW Scalpel / Craft-Knife Holder

    Holds a round knife handle with internal retention lips and a side slot for spare blades; clips on with a hex plug.

    Example
  • HSW Pen / Pencil Cup

    A round, slightly back-tilted pen and pencil cup with an optional drain hole. Pick how it clips to the wall: friction peg, bare peg (into a latch), latch insert, or spring clip.

    Example
  • HSW Open Parts Bin

    An open-top parts bin with a lowered front wall for easy scooping, on swappable wall plugs. Good for screws, clips, and small components.

    Example
  • HSW Deep Bin

    A tall, fully-enclosed bin for long parts, bottles, brushes, or rolled items, on swappable wall plugs. Open top, full-height walls.

    Example
  • HSW J-Hook

    A strong J-hook for hanging cables, bags, headphones, or tools — the arm reaches out and curves up into a cradle so things stay put. Swappable wall plugs.

    Example
  • HSW U-Saddle Holder

    A saddle block with a rounded groove that cradles round handles, cans, spray bottles, or power-tool bodies. Swappable wall plugs.

    Example
  • HSW Insert (rounded, configurable)

    A smoothly-rounded honeycomb-wall insert with optional center hole, side latch tabs, front hexagon emboss and a flat-side variant.

    Example
  • HSW Screwdriver Rack

    A wall shelf with a row of graduated holes that hold screwdrivers (or any shaft tool) shaft-down with the handle resting on top. Pick how it clips to the wall: friction peg, bare peg (into a latch), latch insert, or spring clip; grid or honeycomb support.

    Example
  • HSW Wide Tool Cup

    A wide, flat-based cup for pliers, brushes, markers, or shop tools, held out from the wall on swappable plugs. Optional drain hole in the base.

    Example
  • HSW Drill-Bit Block

    A block with a grid of graduated holes to organise drill bits, end mills, or small round tools by size. Swappable wall plugs.

    Example
  • HSW Shelf

    A flat shelf with a raised front lip to stop things sliding off, plus an angled support gusset underneath. Swappable wall plugs.

    Example
  • HSW Test-Tube / Marker Rack

    A row of equal round bores to hold test tubes, markers, pens, or small bottles upright. Swappable wall plugs.

    Example
  • HSW Cable Hook

    A wide-throat hook for coiled cables, extension leads, lanyards, or straps — the broad rounded curve is gentle on cable jackets. Swappable wall plugs.

    Example
  • HSW Divided Tray

    A shallow tray split into a grid of compartments for sorting screws, beads, SMD parts, or findings. Choose the number of columns and rows. Swappable wall plugs.

    Example
  • HSW Hex-Key Holder

    A slim block with a row of slots that hold Allen / hex keys (or small flat tools) upright and sorted by size. Swappable wall plugs.

    Example
  • HSW Phone / Tablet Shelf

    A small ledge that holds a phone or tablet leaning against the wall, with a front lip to stop it sliding and a cable slot through the deck. Swappable wall plugs.

    Example
  • HSW Rod / Pillar Holder

    A deep round socket that holds a rod, dowel, pillar, umbrella, or long tool upright. Optional drain hole in the base. Swappable wall plugs.

    Example
  • HSW Blank Baseplate

    A flat blank plate on swappable wall plugs — a starting point to build your own accessory, glue parts to, or mount hardware. Pick the size and plug count.

    Example
  • HSW Brush / Marker Cup

    A tall, narrow cup for paintbrushes, markers, files, or long slim tools — keeps them upright and visible. Optional drain. Swappable wall plugs.

    Example
  • HSW Plier / Cutter Rack

    A row of wide slots that hold pliers, cutters, and snips by the handle, tips hanging down. Choose how many. Swappable wall plugs.

    Example
  • HSW Insert (solid latching)

    A solid hexagonal insert that snaps into one honeycomb wall cell with sprung side latches and a flat decorated face - the base building block other attachments grow from.

    Example
  • HSW Insert (empty / hollow)

    A latching wall insert with its centre bored through - a hollow socket to pass a fastener, cable, or your own plug through.

    Example
  • HSW Insert (with mounting plate)

    A latching wall insert capped by a solid plate face - a blank mounting pad to build your own accessory onto.

    Example
  • HSW Insert base (friction, no latches)

    The bare insert body without the spring latches - a friction-only building block for designs that add their own retention.

    Example
  • HSW Hex plug

    A plain hexagonal plug that press-fits into an empty insert (or a wall cell) to blank it off or anchor a part.

    Example
  • HSW M2.5 nut insert

    A wall insert with a captive M2.5 nut pocket and screw clearance - bolt accessories straight to the wall. (Sister recipes cover M3-M10; call insertM3()..insertM10() for other sizes.)

    Example
  • HSW M3 nut insert

    A wall insert with a captive M3 nut pocket and screw clearance for bolting accessories to the wall.

    Example
  • HSW M4 nut insert

    A wall insert with a captive M4 nut pocket and screw clearance for bolting accessories to the wall.

    Example
  • HSW M5 nut insert

    A wall insert with a captive M5 nut pocket and screw clearance for bolting accessories to the wall.

    Example
  • HSW M6 nut insert

    A wall insert with a captive M6 nut pocket and screw clearance for bolting accessories to the wall.

    Example
  • HSW M8 nut insert

    A wall insert with a captive M8 nut pocket and screw clearance for bolting accessories to the wall.

    Example
  • HSW M10 nut insert

    A wall insert with a captive M10 nut pocket and screw clearance for bolting accessories to the wall.

    Example
  • HSW Attach-to-wall insert (screw-through)

    A latching insert with a countersunk screw hole through its base - screw any flat object onto the honeycomb wall. Tune holeDiameter / facetHeight / bottomThickness.

    Example
  • HSW Attach-to-wall insert (empty, supportless)

    The attach-to-wall insert with the centre bored out and a supportless bridge so it prints cleanly with no supports.

    Example
  • Gridfinity baseplate 2×2

    A 2×2 Gridfinity baseplate — the grid foundation that bins drop into. Built with the kennetek gridfinity-rebuilt library; change gridx/gridy for a larger plate.

    Example
  • Gridfinity baseplate 3×3

    A 3×3 Gridfinity baseplate for a 9-cell organizer foundation. Built with the kennetek gridfinity-rebuilt library.

    Example
  • Gridfinity bin 1×1

    The smallest Gridfinity storage bin — a single 1×1 cell, 3 units tall, with a stacking lip. Built with the kennetek gridfinity-rebuilt library.

    Example
  • Gridfinity bin 2×1

    A 2×1 Gridfinity storage bin, 6 units tall, one open compartment. Built with the kennetek gridfinity-rebuilt library.

    Example
  • Gridfinity bin 2×2

    A 2×2 Gridfinity storage bin, 6 units tall, one large compartment. Built with the kennetek gridfinity-rebuilt library.

    Example
  • Gridfinity bin 2×2 (4 compartments)

    A 2×2 Gridfinity bin subdivided into a 2×2 grid of four compartments for small-parts sorting. Built with the kennetek gridfinity-rebuilt library.

    Example
  • Gridfinity bin 2×1 (label tab)

    A 2×1 Gridfinity bin with an auto label tab ledge for a printed or written label. Built with the kennetek gridfinity-rebuilt library.

    Example
  • Gridfinity bin 1×2 (scooped)

    A 1×2 Gridfinity bin with a curved front scoop that sweeps parts toward your fingers. Built with the kennetek gridfinity-rebuilt library.

    Example
  • 2D booleans

    Shows union(), difference(), and intersection() applied to 2D circles and squares before a single extrude, so you can see each boolean result as a separate printed tile.

    Example
  • circle(), square(), polygon()

    Lays the three core 2D primitives side by side and extrudes each to a thin slab so the result is a printable 3D object you can examine from every angle.

    Example
  • combining booleans

    Shows how nesting union() inside difference() builds a simple mounting bracket from basic shapes. A vertical post and horizontal foot are joined first, then a bolt hole and slot are cut out.

    Example
  • children() in a module

    Defines a module that places whatever geometry you pass into it at evenly-spaced positions around a ring, using children() and a for loop with rotate().

    Example
  • circle() and square()

    Shows the two core 2D primitives - circle() and square() - combined with 2D union and difference to form a rounded-corner key-tag shape, then extruded into a printable part.

    Example
  • color()

    Demonstrates color() with named CSS colors and an RGBA alpha value. Three spheres overlap: two use named colors and the third is translucent so you can see through it.

    Example
  • cube()

    Shows the two common forms of cube(): an uncentered one sitting on the origin and a centered one floating above it. Tune size and spacing to explore the difference.

    Example
  • cylinder() and cones

    Shows three forms of cylinder() standing side by side: a plain cylinder, a sharp cone (r2=0), and a truncated cone (r1 not equal r2). Tune the radii and height freely.

    Example
  • difference() with a hole pattern

    Shows how difference() combined with a for loop removes a grid of holes from a flat plate. Tune the grid spacing and hole size to create your own custom perforation pattern.

    Example
  • difference()

    Shows how difference() carves one shape out of another. A cylinder is subtracted from a solid cube to create a round through-hole - the foundation of almost every functional part.

    Example
  • extrude a computed polygon

    Shows how a list comprehension builds the [x, y] points for a wavy disc outline, which polygon() then assembles and linear_extrude() lifts into a printable coaster or badge.

    Example
  • $fn, $fa, $fs

    Shows three cylinders of the same size rendered with different facet controls - coarse explicit $fn, fine explicit $fn, and angle-driven $fa - so you can see exactly how each setting shapes round geometry.

    Example
  • for loop

    A row of cylindrical pillars that grow taller from left to right, showing how a for loop iterates over a range and how loop variable drives both position and size.

    Example
  • for + rotate ring

    A ring of evenly spaced round pegs arranged in a circle using a for loop combined with rotate. Tune the number of pegs, ring radius, and peg size to explore radial symmetry.

    Example
  • defining a function

    A decorative arch whose keystone positions are computed by a user-defined function that evaluates a parametric circle. Shows how functions return values that drive geometry, keeping the math out of the module calls.

    Example
  • hull() in 2D

    Shows how hull() wraps a convex skin around a set of 2D circles to create a smooth rounded slot outline. The result is extruded into a printable plate with a slotted hole.

    Example
  • hull() in 3D

    Shows how hull() wraps a convex skin around spheres placed at the corners of a box to produce a solid with smoothly rounded edges and corners. Tune the box size and corner radius freely.

    Example
  • intersection_for()

    A faceted gem-like solid created by intersecting several rotated slabs using intersection_for(). Each iteration rotates a flat slab by an equal angle step, and the intersection keeps only the shared core.

    Example
  • intersection()

    Shows how intersection() keeps only the volume shared by all children. A cube and a sphere overlap to produce a rounded cube-corner gem shape - great for learning Boolean logic.

    Example
  • let() and assignment

    A set of nested hexagonal tiles whose size and position are computed with let() expressions, showing how to name intermediate values inside a comprehension without polluting the outer scope.

    Example
  • linear_extrude(scale=)

    Shows how scale= in linear_extrude() shrinks the cross-section as it rises, turning a hexagonal base into a tapered obelisk. Tune base size, height, and tip scale.

    Example
  • linear_extrude(twist=)

    Shows how adding a twist= angle to linear_extrude() spirals a square profile into a decorative twisted column. Adjust height, twist degrees, and profile size.

    Example
  • linear_extrude()

    Shows how linear_extrude() lifts a flat 2D star polygon straight up into a 3D prism. Tune the star size, point count, and height.

    Example
  • list comprehension with condition

    A sparse grid of pillars where each pillar is placed only when a mathematical condition holds, built with a list comprehension containing an if filter. Shows how to selectively include items in a generated list.

    Example
  • list comprehension

    A smooth wave-profile wall built by generating polygon outline points with a list comprehension and then extruding the result. Shows how to build point arrays mathematically rather than typing each coordinate by hand.

    Example
  • minkowski() in 2D

    Shows how minkowski() of a 2D square with a circle inflates and rounds the outline uniformly. The resulting smooth 2D profile is extruded into a thick printable pad with softened edges.

    Example
  • minkowski() rounding

    Shows how minkowski() of a box with a small sphere rounds every edge and corner simultaneously. The technique generalises to any shape. Note that the overall size grows by the sphere radius on each side.

    Example
  • mirror()

    Creates an asymmetric L-shaped bracket and then reflects it across the Y-Z plane using mirror(), producing a matching left-hand part from a single definition.

    Example
  • defining a module

    A parametric rounded peg module defined once and called multiple times with different sizes. Shows how modules encapsulate reusable geometry so you can place many variations without repeating code.

    Example
  • module default args

    A shelf bracket module with sensible default dimensions so it works with no arguments at all, but can be customised with named-argument calls. Demonstrates how default values reduce boilerplate and how named arguments improve readability.

    Example
  • multmatrix() shear

    Uses multmatrix() to apply a shear transform to a cube, leaning its top face in the X direction - a distortion that cannot be achieved with rotate() or scale() alone.

    Example
  • nested for

    A checkerboard grid of short square pillars built with two nested for loops, one for columns and one for rows. Shows how to iterate over two axes at once and skip alternating cells.

    Example
  • offset() delta + chamfer

    Shows how offset(delta=, chamfer=true) shifts a 2D outline by a fixed amount and adds sharp 45-degree chamfers at corners instead of arcs. An outer and inset shell are stacked to show the contrast.

    Example
  • offset() rounded

    Shows how offset(r=) inflates a 2D polygon outward and smoothly rounds every concave and convex corner. An L-shaped profile is offset then extruded into a printable bracket tile.

    Example
  • polygon() from points

    Shows how polygon() takes an explicit list of [x, y] points to define any custom shape - here a bold right-pointing arrow - then extrudes it into a printable marker.

    Example
  • polyhedron()

    Builds a square pyramid by hand using polyhedron() with a list of 5 corner points and 5 faces. A great introduction to defining arbitrary closed solids vertex by vertex.

    Example
  • projection()

    Shows how projection() collapses a 3D object down to a flat 2D silhouette in the XY plane, which can then be re-extruded into a thin shadow-stamp. Tune the source shape and stamp thickness.

    Example
  • ranges [a:step:b]

    A staircase of rectangular steps generated with a stepped range loop. Each iteration advances by the step size in both height and depth, showing how the three-argument range controls spacing between loop values.

    Example
  • recursive module

    A branching fractal tree built with a recursive module. Each call draws one branch segment, then calls itself twice at a smaller scale and angle. The 2D tree outline is extruded to a thin slab so it is printable.

    Example
  • #, %, ! modifiers note

    Demonstrates a solid composed part (a box with a lid) alongside a semi-transparent reference bounding volume drawn with the % modifier. The final render is always the solid geometry only.

    Example
  • rotate_extrude(angle=)

    Shows how the angle= parameter stops a rotate_extrude() part-way around, creating a C-shaped arc solid. Adjust the sweep angle and cross-section to explore partial revolves.

    Example
  • rotate_extrude()

    Shows how rotate_extrude() sweeps a 2D profile all the way around the Z axis to make a solid of revolution - here a chunky ring with a D-shaped cross-section.

    Example
  • rotate()

    Shows three elongated bars, each tipped 45 degrees around a different axis using rotate(), so the effect of rotating around X, Y, and Z is immediately visible.

    Example
  • scale() and resize()

    Compares scale() and resize() applied to the same sphere. scale() multiplies the current size by a factor while resize() sets an exact target size in millimetres.

    Example
  • sphere()

    Places two spheres of the same radius side by side to show how $fn controls smoothness - the left sphere is coarse and blocky while the right one is nearly smooth.

    Example
  • text() 2D

    Shows how text() creates a 2D letter outline that linear_extrude() lifts into raised 3D lettering on a name-badge plate. Change the label, font size, and thickness to customise.

    Example
  • engraving text

    Shows how to engrave text into a flat plate using difference() - the text shape is subtracted from the plate solid. Tune the plate size, engraving depth, and label.

    Example
  • translate()

    Places four identical cubes at different positions using translate() to show how moving along X, Y, and Z works independently and in combination.

    Example
  • union()

    Shows how union() merges two overlapping solids into a single seamless body. Adjust the box size, cylinder radius, and overlap to explore how the shapes combine.

    Example
  • 608 bearing footprint ring

    A solid printable ring matching the footprint of a standard 608 skate/skateboard ball bearing (22 mm OD, 8 mm bore, 7 mm wide). Use it as a press-fit spacer, a bearing-seat gauge, or a drop-in dummy bearing. The outer and inner edges are lightly chamfered so it seats cleanly. Tune the diameters and width to gauge other bearing sizes.

    Example
  • Bevel gear

    A straight-cut bevel gear that transmits motion between two shafts meeting at 90 degrees. Print one of these plus a mating bevel gear (swap teeth and mate_teeth) to build a right-angle drive. Tune the module, tooth count, mate tooth count, face width, and bore.

    Example
  • Generic threaded bottle cap

    A generic screw-on bottle cap that mates with the generic threaded bottle neck, built by the BOSL2 bottlecaps library. Tune the cap height, thread depth, thread outer diameter, and pitch (keep them matched to your neck) for a snug fit. Pairs with the generic bottle neck recipe.

    Example
  • Generic threaded bottle neck

    A generic threaded bottle neck finish with a support ring, built by the BOSL2 bottlecaps library. Pairs with the matching generic bottle cap. Tune the neck diameter, thread outer diameter, height, and thread pitch to design your own container opening.

    Example
  • Wall cable clip

    A small screw- or adhesive-mount cable clip: a flat backing pad with a rounded C-shaped catch that snaps over a cable to route it along a wall or desk edge. The catch mouth is narrower than the cable so it grips. Tune the cable diameter, mouth opening, backing size, and wall thickness.

    Example
  • Flat corner brace

    A flat L-shaped mending plate that reinforces a 90 degree corner joint. Two perpendicular arms share a rounded outer profile with a screw hole in each arm and the heel. Prints flat as one solid with no supports. Tune the arm length, width, thickness, corner rounding, and screw-hole diameter.

    Example
  • Rounded decorative bowl

    A curved bowl with a flat stable base and a rounded rim, hollowed to a uniform wall and a solid floor. Built by revolving an explicit profile with BOSL2 rotate_sweep. Tune the rim radius, depth, wall and base flat.

    Example
  • Faceted gem

    A solid brilliant-cut style gem: a flat-topped table on a faceted crown over a pointed pavilion, built from stacked BOSL2 regular prisms. Single shell, prints point-down style as one solid (table up). Tune the girdle width, facet count, and crown/pavilion proportions.

    Example
  • Hanging ornament ball

    A solid decorative sphere with an integrated torus hanging loop on top, fused into one printable shell. Tune the ball diameter, the loop size/thickness and the facet count for a smoother surface.

    Example
  • Picture frame with stand

    A desktop photo frame: a rounded rectangular border with a window cut through it, fused to an angled easel leg at the back so it stands on its own. One printable shell, prints flat on its back. Tune the frame size, border width, window and leg angle.

    Example
  • Tealight candle holder

    A weighted round holder with a recessed pocket sized for a standard tealight cup and a rounded outer rim. Single shell, prints flat with no supports. Tune the outer diameter, height, the tealight pocket diameter/depth and the rim rounding.

    Example
  • Twisted spiral column

    A decorative pillar/pedestal with a spiralling fluted shaft between a square base and a square cap, fused into one solid. The shaft is a rounded BOSL2 star profile linearly extruded with a twist. Tune the height, twist, flute count and base size.

    Example
  • Faceted prismoid vase

    An angular tapered vase with a wide square base flaring to a smaller rotated top, hollowed for stems. Built from two BOSL2 prismoids (outer minus inner) with a solid floor. Tune base/top widths, twist, height and wall.

    Example
  • Rounded bud vase

    A smooth single-shell bud vase with a swelling belly and a narrowed neck, hollowed for water. Built by revolving a rounded profile with BOSL2 rotate_sweep. Tune the base/belly/neck radii, height and wall thickness.

    Example
  • Cable management clip

    A desk-edge cable management clip: a flat adhesive base with an open C-shaped jaw on top that snaps around a cable bundle and holds it along the desk edge. The C jaw is a ring extruded across the clip depth with a top wedge cut for the snap opening, unioned to the base, so it prints flat-down as one solid. Tune the cable channel diameter, jaw opening, base size, and wall.

    Example
  • Business-card holder

    An angled desktop business-card holder: a rounded block with a slanted slot that cradles a stack of cards at a readable angle, plus a front cut-away so you can thumb the top card out. Carved entirely by difference from one rounded body so it prints as a single watertight piece. Tune the card width, stack thickness, slot angle, and wall.

    Example
  • Headphone hook bracket

    An under-desk headphone hook bracket: a flat vertical mounting plate (screw-mount) with a hook arm that sweeps out and curls up to cradle a headphone band without creasing it. The side profile (plate + arm + upturned tip) is drawn once and extruded across the width, then screw holes are bored, so it is guaranteed a single watertight solid. Tune the plate size, hook reach, tip height, and width.

    Example
  • Monitor-riser foot

    A single load-bearing foot/leg for a DIY monitor riser or laptop stand: a hollow tapered pedestal (wide stable base, narrower top) with a thick top deck and a centering spigot on top so a wooden or acrylic shelf board or a stacked foot locates onto it. Carved from a rounded prismoid with an internal cavity, printed open-side-down as one watertight shell. Tune the footprint, height, wall, taper, and spigot.

    Example
  • Pen & pencil cup with base tray

    A round desktop pen cup with a slightly flared rounded rim and a wide chamfered base disc that doubles as a stability foot and a tiny clip/eraser ledge. Built from a BOSL2 tube on a chamfered cylinder so it prints floor-down with no supports. Tune the outer diameter, height, wall, floor thickness, and base flare.

    Example
  • Phone stand

    A single-piece angled phone stand: a back support leaned at an angle with a front lip ledge that catches the phone, joined to a flat base for stability. Built by unioning a leaned slab, a base plate, and a front lip so it prints as one solid with no supports. Tune the width, lean angle, support height, base depth, and slab thickness.

    Example
  • Sticky-note tray

    A desktop sticky-note holder: a shallow rounded tray sized for a square sticky pad, with a scooped front thumb cut-out so you can peel the top note off easily, and a solid floor. Carved by difference from one rounded block so the whole tray is a single watertight piece. Tune the pad size, wall, tray height, and floor thickness.

    Example
  • Tablet stand

    A wider, sturdier cousin of the phone stand sized for tablets: a leaned back support slab with a deep front trough ledge that cradles a tablet, joined to a heavy base plate for stability. Unioned from base, trough lips, and a tilted slab so it prints as one solid, ledge facing up, no supports. Tune the width, lean, support height, base depth, and trough gap.

    Example
  • Divided tray (3 compartments)

    A shallow desk tray split into three equal compartments by two internal dividers, with rounded outer corners and a solid floor. Carve out each compartment from a rounded block so the whole tray prints as one watertight piece. Tune the footprint, height, wall thickness, and floor thickness.

    Example
  • Dovetail female socket

    A flat plate with a sliding dovetail groove (the female half) bored through it by the BOSL2 joiners library. The matching dovetail male connector slides in for a self-locking joint. Tune the plate size, groove width, height, and slide length.

    Example
  • Dovetail male connector

    A flat connector plate with a sliding dovetail tongue (the male half) generated by the BOSL2 joiners library. Slides into the matching dovetail female socket for a self-locking woodworking-style joint. Tune the plate size, dovetail width, height, and slide length.

    Example
  • Drawer organizer insert

    A drop-in drawer insert with a grid of pockets for screws, stationery, or small parts. The whole tray is carved from a rounded block so it prints as one watertight piece — set the rows and columns to repartition the grid. Tune the footprint, height, grid size, wall thickness, and floor thickness.

    Example
  • Flanged bushing

    A plain bushing with an integral shoulder flange at one end, so it both press-fits into a bore and seats against the face of the housing to take axial load. Printed as one watertight solid (flange + sleeve share the same bore). Tune the sleeve OD to your bore, the flange diameter for the bearing face, the bore for your shaft, and the lengths.

    Example
  • Flat-belt pulley with bore

    A crowned flat-belt pulley with a bored hub to run on a shaft. The slight barrel crown across the face keeps a flat belt tracked to the centre, and the bore lets it ride on a shaft or bushing. Printed as one watertight solid. Tune the rim diameter, crown, face width, and bore.

    Example
  • Friction-fit box lid

    A press-on lid with a downward inner lip that slides snugly inside a matching box opening, plus a finger-grip recess on top. Sized to pair with a rounded box base; adjust the clearance for a looser or tighter fit. Tune the opening size, lip depth, top thickness, and rounding.

    Example
  • Hose guide stake

    A ground stake topped with a smooth vertical roller post that steers a garden hose around bed corners without crushing plants. The post, collar, and pointed spike fuse into one printable solid. Tune the spike length, post height/diameter, and base collar.

    Example
  • Engraved plant label stake

    A flat plant label on a pointed push-in stake, with the plant name engraved into the face via difference so it prints as one connected solid. Tune the label size, stake length, plate thickness, engrave depth, and the text.

    Example
  • Plant pot with drainage holes

    A tapered round plant pot with a solid floor pierced by a ring of drainage holes. Carved from a tapered tube so it prints as one watertight shell. Tune the top/bottom diameters, height, wall, floor thickness, and drainage hole count/size.

    Example
  • Pot saucer / drip tray

    A shallow round saucer that catches drainage water under a plant pot, with a slightly raised inner lip and rounded outer edge. Carved from a rounded disc so it prints as one watertight piece. Tune the outer diameter, height, wall, and floor thickness.

    Example
  • Row-marker sign on stake

    A small angled signboard on a flat ground stake for labelling vegetable rows, with the crop name engraved into the tilted face via difference so it reads from above. The board, stake, and point fuse into one printable solid. Tune the board size, stake length, tilt, and the text.

    Example
  • Seed-starting tray (2x2 cells)

    A compact seed-starting tray with a 2x2 grid of tapered cells, each with its own drainage hole, joined by a shared rim so the whole tray lifts as one piece. Carved from a solid block so it prints watertight. Tune the cell count per side, cell size/depth, wall, and drain hole size.

    Example
  • Trellis / vine clip

    A C-shaped open clip that snaps onto a trellis wire or thin stake and gently holds a plant stem in a second loop, training climbers without ties. Built as one wedge-and-ring body so it prints connected. Tune the wire and stem diameters, the snap-gap, wall thickness, and clip depth.

    Example
  • Bottle watering spike

    A slow-release watering spike that screws into a standard PET bottle neck and drips into the soil through a hollow pointed stake with side weep holes. Bored hollow with a through-channel so water flows; prints as one shell. Tune the bottle-neck diameter, spike length, bore, and weep holes.

    Example
  • GT2 timing pulley

    A GT2 timing-belt pulley with 2 mm pitch tooth grooves and a flange on each end to keep the belt tracking. The default 20-tooth size is the common 3D-printer X/Y pulley. Tune the tooth count, bore, belt width, and flange size. Add a flat or grub-screw later if you need to lock it to a shaft.

    Example
  • Right-angle gusset bracket

    A heavy-duty 90 degree angle bracket: two square bolt-down plates meeting at a right angle, braced by a full-height central triangular gusset web so it resists bending under load. Each plate carries a bolt hole. Fuses into one watertight solid that prints with the inside corner on the bed. Tune the plate size, thickness, gusset thickness, and bolt-hole diameter.

    Example
  • Heat-set insert boss

    A mounting boss with a tapered pilot bore sized for a brass heat-set threaded insert, plus a chamfered lead-in so the insert seats square. Built from the BOSL2 shape library with rounded fillets for strength. A single printable solid. Tune the boss size and the insert pilot diameters.

    Example
  • Herringbone gear

    A double-helical (herringbone) spur gear. The mirrored helical teeth cancel axial thrust while running smoother and quieter than straight-cut teeth, and the chevron pattern prints cleanly without supports. Tune the module, tooth count, thickness, helix angle, and bore.

    Example
  • Bag / chip-bag sealing clip

    A springy C-shaped clip that pinches a folded bag closed. Two parallel jaws join at a solid left spine; the narrow mouth gap at the tips lets the printed plastic flex to grip. Built as a union of the spine plus two jaws so it prints flat as one connected piece. Tune the jaw length, width, gap, and spine thickness.

    Example
  • Beveled drink coaster

    A solid round drink coaster with a beveled top edge and a shallow recessed well to catch condensation drips, plus a fine bottom chamfer for a clean first layer. Tune the diameter, thickness, bevel, and well depth.

    Example
  • Fridge note clip with magnet pocket

    A small spring clip for pinning notes to a fridge. Two tapering jaws join at a solid spine and pinch to a narrow mouth gap to grip paper; a round pocket is carved into the back of the spine to glue in a magnet. Built as a union minus the pocket so it prints as one connected piece. Tune the jaw size, gap, and magnet diameter/depth.

    Example
  • Napkin ring

    A simple round napkin ring — a short tube with softly rounded inner and outer rims so it slides over a rolled napkin without catching. Prints flat on its rim with no supports. Tune the inner diameter, wall thickness, and height.

    Example
  • Soap dish with drain slots

    A rounded-rectangle soap dish with a raised lip and a floor cut by parallel drain slots so water runs off and the bar dries. The slotted floor keeps everything one watertight print. Tune the footprint, height, wall, and slot count/width.

    Example
  • Sink sponge holder

    A sink-side sponge tray with tall slotted side walls for airflow and a slotted floor for drainage, so a wet sponge dries from every side. Walls and floor are cut from a rounded open box so it stays one watertight print. Tune the footprint, height, wall, and slot spacing.

    Example
  • Toothbrush holder

    A round bathroom cup with a perforated top deck — drilled holes hold toothbrushes upright while the open base below lets water drain to the floor of the cup. One watertight print with a chamfered base. Tune the diameter, height, hole count, and hole size.

    Example
  • Cutlery caddy (4 bays)

    A countertop cutlery caddy split into four open bays by internal dividers, with rounded corners and a slotted floor so rinse water drains away. Pockets and slots are carved from a rounded block so it prints as one watertight piece. Tune the footprint, height, walls, and bay count.

    Example
  • Idler pulley with bore

    A grooved idler/guide pulley for round belt or cord, with a center bore to run on a shaft or bushing. The V-groove keeps the belt tracked; two flanges contain it. Printed as one watertight solid. Tune the outer diameter, groove depth, width, and bore to suit your belt and shaft.

    Example
  • Knuckle hinge leaf

    One leaf of a classic knuckle (butt) hinge — a flat plate with rounded barrel knuckles and a through pin bore, built from BOSL2 attachable primitives as a single printable solid. Print two and join with a pin rod. Tune the leaf size, knuckle count, barrel diameter, and pin bore.

    Example
  • Knurled knob (threaded bore)

    A grippy diamond-knurled control knob with an internally threaded blind bore so it screws onto a bolt or shaft, generated by the BOSL2 cylinder texture + threading libraries. A single printable solid. Tune the knob diameter, height, thread size and pitch.

    Example
  • Rounded L-bracket

    A right-angle mounting bracket with two filleted flanges and countersunk-free thru-holes on each face. The 90 degree inside corner is reinforced so it prints as one watertight solid. Tune the flange length, width, plate thickness, corner rounding, and bolt-hole diameter.

    Example
  • M8 hex bolt

    A real ISO-metric M8 hex-head bolt with a properly cut helical thread, generated by the BOSL2 screws library. A single printable solid (head + threaded shaft). Tune the metric size, shank length, threaded length, and fit tolerance.

    Example
  • M8 hex nut

    A real ISO-metric M8 hex nut with an internally cut helical thread, generated by the BOSL2 screws library. A single printable solid that mates with an M8 bolt. Tune the metric size, nut thickness, and internal-thread fit tolerance.

    Example
  • NEMA17 motor mount plate

    An L-shaped NEMA17 stepper mount: a vertical face plate with the standard 22 mm pilot bore and four 31 mm-spaced M3 bolt holes, joined to a horizontal base flange (with its own slots) by a stiffening rib. Dimensions follow the NEMA17 standard. Prints as one solid. Tune the plate size, thickness, bore, bolt-hole diameter, and base depth.

    Example
  • PCO-1810 bottle cap

    A standards-compliant PCO-1810 screw cap that fits the common 28mm PET soda/water bottle neck finish, generated by the BOSL2 bottlecaps library. Tune the cap height, wall thickness, and knurl texture for grip.

    Example
  • Pencil & tool cup

    A round desktop cup for pens, pencils, and small tools, with a rounded top rim and a solid floor. Built from a BOSL2 tube with a chamfered base disc so it prints cleanly without supports. Tune the outer diameter, height, wall thickness, and floor thickness.

    Example
  • Round pill container body

    A pocket-sized round pill bottle body with an external screw thread at the mouth, rounded shoulders, and a closed bottom, built with the BOSL2 threading helix. Pairs with a matching screw lid. Tune the body diameter, height, wall thickness, and thread pitch.

    Example
  • 2:1 reduction pinion

    A 12-tooth pinion that meshes with the 24-tooth spur gear in this set to give an exact 2:1 gear ratio. Print this and the spur gear, set them one pitch-distance apart, and the small gear turns twice for every turn of the large one. Tune the module, tooth count, thickness, and bore.

    Example
  • Pipe / rod mounting clamp

    A one-piece pipe stand-off: a closed cylindrical collar that a pipe or rod passes through, fused to a flat mounting foot with two bolt holes that screws to a wall or panel. The bore is sized for a slip fit. Prints flat as a single watertight solid, no supports. Tune the pipe diameter, wall thickness, collar length, foot width, and bolt-hole size.

    Example
  • Rack (linear gear)

    A straight gear rack: the flat, linear counterpart of a spur gear. A meshing pinion of the same module converts rotation into linear travel. Tune the module, number of teeth (rack length), thickness, width, and the solid backing below the teeth.

    Example
  • Internal ring gear

    An internal ring (annular) gear with teeth cut on the inside, the outer ring of a planetary gearset. A meshing spur gear of the same module rolls around the inside. Tune the module, tooth count, thickness, and the solid backing wall thickness behind the teeth.

    Example
  • Bore roller / conveyor wheel

    A barrel-shaped roller (conveyor / guide wheel) with a center bore to spin on a shaft or bushing. The crowned (slightly barrelled) profile self-centers a belt or load and the rounded ends resist edge wear. Printed as one watertight solid. Tune the body diameter, crown, length, and bore.

    Example
  • Rounded storage box base

    A hollow box base with softly rounded outer corners and an open top, sized for small parts and hardware. Built from a rounded BOSL2 cuboid with an inner cavity subtracted. Tune the footprint, height, wall thickness, corner rounding, and floor thickness.

    Example
  • Rounded box with lid

    A clean filleted enclosure with rounded edges and a friction-fit lid, using BOSL2 rounding + attachments. Tune the outer size, wall thickness, corner rounding, and lid height.

    Example
  • Capsule (stadium solid)

    A cylinder capped by hemispheres on both ends — the 3D stadium / pill shape, built by revolving a stadium profile into one watertight solid. Tune the radius and the straight mid-section length.

    Example
  • Chamfered box

    A solid box with flat 45-degree chamfers cut on every edge for a crisp faceted look. Tune the side lengths and the chamfer depth.

    Example
  • Filleted wedge ramp

    A right-triangular wedge / ramp solid with its long top edge rounded into a smooth fillet. Tune the footprint, the rise, and the fillet radius.

    Example
  • Cone frustum

    A truncated cone (frustum) with a wider base and narrower top, edges softly rounded. Tune the two radii, the height, and the rounding.

    Example
  • Hexagonal prism

    A regular six-sided prism with softly rounded vertical edges. Tune the across-flats radius, the height, and the side count to make other regular prisms.

    Example
  • Octagonal prism

    A regular eight-sided prism with a chamfered top and bottom rim for a faceted token look. Tune the radius, height, side count, and chamfer.

    Example
  • Onion dome finial

    A bulbous onion-dome solid that swells out then tapers to a point, sitting on a short cylindrical drum — a classic finial / cupola cap. Tune the bulge, height, and base.

    Example
  • Rounded cuboid

    A solid box with all twelve edges rounded into smooth fillets. Tune the three side lengths and the corner radius.

    Example
  • Spindle / lens solid

    A symmetric spindle (lens) made by revolving a circular arc — a fat lens that tapers to points at both poles. Tune the equatorial radius and the bulge height.

    Example
  • Super-egg (superellipsoid)

    A Piet Hein style super-egg — a superellipsoid that stands on its own end. Tune the radii and the superellipse exponent for a rounder or boxier profile.

    Example
  • Torus ring

    A solid donut/ring shape defined by the major (centerline) radius and the minor (tube) radius. Tune both radii and the facet counts.

    Example
  • Shelf bracket with gusset

    A load-bearing shelf bracket: a vertical wall plate, a horizontal shelf flange, and a triangular diagonal gusset web tying the two together for stiffness. Wall and shelf carry mounting holes. The whole part fuses into one watertight solid. Tune the wall height, shelf reach, width, thickness, and hole diameter.

    Example
  • Stepped shoulder bushing

    A two-diameter shoulder bushing: a smaller pilot diameter that drops into a bore and a larger shoulder that registers depth and takes face load. Printed as one watertight solid with a clean through bore. Tune the pilot and shoulder diameters and lengths, plus the bore for your shaft.

    Example
  • Plain sleeve bushing

    A simple cylindrical plain (journal) bushing — a printable sleeve that press-fits into a housing bore and gives a shaft a low-friction running surface. The inner and outer edges are chamfered for easy insertion. Tune the outer diameter to your housing, the bore to your shaft (leave running clearance), and the length to suit.

    Example
  • Snap-pin socket block

    A solid mounting block with a sprung snap-pin socket bored into it — the receiver for the BOSL2 snap pin. The socket geometry comes from the BOSL2 joiners library so the locking-nub catch matches the pin exactly. Tune the block size, socket radius, length, and snap depth.

    Example
  • Snap pin (sprung)

    A two-pronged snap pin that clicks into a matching socket and locks with a sprung nub. Generated by the BOSL2 joiners library so the spring slot, nub depth, and clearance are correct. Tune the radius, length, snap depth, prong thickness, and fit clearance.

    Example
  • Spur gear (involute)

    A real meshing spur gear with a correct involute tooth profile and a center bore, generated by the BOSL2 gears library. Tune the module (tooth size), tooth count, thickness, and shaft diameter.

    Example
  • Stacking parts bin

    An open-front-friendly parts bin whose rounded base nests a matching lip on the bin below, so several stack stably on a shelf. The shell is carved hollow from a rounded block with a recessed underside rim. Tune the footprint, height, wall thickness, floor thickness, and the nesting lip depth.

    Example
  • Rubber-foot bumper socket

    A screw-down socket that grips a push-in rubber bumper foot: a rounded cylindrical body with a counterbored cavity for the rubber foot's stem and a central screw hole through the bottom. Tune body diameter/height, socket cavity diameter/depth, and screw hole diameter.

    Example
  • Corner brace with triangular gusset

    A 90-degree corner brace: two flat mounting tabs joined by a tall triangular gusset web for stiffness, with one screw hole per tab. Tune tab length, plate thickness, gusset height/web thickness, and hole diameter.

    Example
  • Rounded L-bracket

    A right-angle mounting L-bracket with rounded outer corners, an inner fillet weld at the corner for strength, and four screw holes (two per leg). Tune leg length, width, thickness, hole diameter, and fillet radius.

    Example
  • Threaded leveling foot

    An adjustable leveling foot: a wide rounded base disk topped by a real metric-style threaded stud that screws into a furniture insert. Tune base diameter/height, stud thread diameter, pitch, and stud length. Pairs with a matching threaded insert/nut.

    Example
  • Panel snap clip

    A cantilever snap-fit clip for retaining a panel or wire: a screw-down base with an upright flexible arm ending in a hooked barb that snaps over a panel edge. Two base bolt holes. Tune base size, arm height/thickness, barb depth, and bolt hole diameter.

    Example
  • Right-angle gusset plate

    A flat triangular gusset plate for reinforcing 90-degree frame joints: a right-triangle web with a thickened ribbed hypotenuse and three bolt holes (one near each corner). Lies flat for printing. Tune leg length, thickness, rib width, and bolt hole diameter.

    Example
  • Shelf bracket with diagonal strut

    A wall-mount shelf bracket: a vertical wall plate, a horizontal shelf plate, and a diagonal strut between them for load support. Wall plate has two keyhole-free round screw holes; shelf plate has one. Tune arm lengths, thickness, width, strut width, and hole diameter.

    Example
  • Tube / rod clamp with mounting feet

    A saddle clamp that holds a tube or rod against a surface: a rounded cradle block with a semicircular channel and two flat mounting feet, each with a bolt hole. Tune tube diameter, wall thickness, foot length, base thickness, width, and bolt hole diameter.

    Example
  • Threaded jar body

    A round storage jar with an external screw thread at the mouth and a flat closed bottom, built with the BOSL2 threading helix. Pairs with the matching threaded lid recipe. Tune the body diameter, height, wall thickness, and thread pitch.

    Example
  • Threaded jar lid

    A round screw-on lid with an internal thread and a knurled grip skirt, built with the BOSL2 threading helix. Mates with the matching threaded jar body recipe — keep the jar diameter and pitch in sync. Tune the lid diameter, height, wall thickness, and pitch.

    Example
  • Threaded rod (metric)

    A real metric threaded rod (all-thread / studding) with a true helical ISO thread profile and blunt printable ends, generated by the BOSL2 threading library. A single printable solid. Tune the major diameter, pitch, and overall length.

    Example
  • Thrust washer

    A flat annular thrust washer that sits between a rotating part and a fixed face to carry axial load and reduce wear. Both faces are flat for full bearing contact, with chamfered edges so it does not snag. Tune the outer and inner diameters to your shaft and seat, and the thickness for the load.

    Example
  • Thumb screw

    A real thumb screw: a wide knurled finger grip head fused to a properly threaded metric shaft for tool-free tightening, built from the BOSL2 cylinder texture + threading libraries. A single printable solid. Tune the head diameter, shaft size, pitch and length.

    Example
  • Tool caddy with handle

    A two-pocket carry caddy with a central spine and a rounded grab handle, for ferrying tools, brushes, or craft supplies. The pockets, handle hole, and rounded body are all carved from one rounded block so it prints as a single watertight piece. Tune the footprint, height, wall thickness, and handle dimensions.

    Example
  • T-slot joiner clip

    A T-slot snap joiner clip from the BOSL2 joiners library — the printable connector that plugs two panels together edge-to-edge with a self-retaining barbed tongue. Tune the length, width, base thickness, and flank angle.

    Example
  • Broom / tool clip

    A spring-grip wall clip for broom, mop, or rake handles: a screw-mount backplate with a C-shaped jaw whose mouth is narrower than the handle so it snaps on and holds. Tune the handle diameter, mouth opening, jaw thickness, and backplate.

    Example
  • Screw-mount cable clip

    A screw-mount cable clip with a flat slotted backing tab and a rounded saddle that holds one or more cables against a wall or desk edge. The screw slot lets you snug it down over the cables. Tune the cable diameter, saddle width, tab length, and screw bore.

    Example
  • Double coat hook

    A double coat hook with two outward-curving prongs on a single screw-mount backplate, ideal for hanging two coats or a coat and a scarf. Tune the backplate size, prong reach, prong thickness, and screw bore.

    Example
  • French-cleat hook

    A French-cleat hanger: the back face is bevelled at 45 degrees to drop over a matching wall-mounted cleat rail, and the front carries an upward hook arm. Self-locking and tool-free to mount. Tune the body size, cleat angle, hook reach, and arm thickness.

    Example
  • J-hook wall hanger

    A deep J-shaped hook on a screw-mount backplate for hanging tools, mugs, utensils, or cables. The long curved tail makes items easy to lift on and off. Tune the backplate, hook drop, hook radius, and bar thickness.

    Example
  • Key rail with hooks

    A horizontal screw-mount key rail: a rounded backing bar with a row of small upward hooks for keys, lanyards, or jewellery, plus screw holes at each end. Tune the rail length, number of hooks, hook size, and bar thickness.

    Example
  • Pegboard hook

    A pegboard hook that plugs into standard 1-inch-pitch pegboard: two rear pegs drop into adjacent holes and a forward arm holds tools. Tune the peg diameter, pegboard pitch, board thickness, arm reach, and bar thickness. Default pitch 25.4 mm and peg 5.5 mm suit common 6 mm pegboard.

    Example
  • Screw-mount wall hook

    A simple screw-mount wall hook: a flat rounded backplate with a countersunk screw hole and an upward-curving arm to hang coats, bags, or towels. Tune the backplate size, arm reach, hook depth, and screw bore.

    Example
  • Wing nut

    A real wing nut: an internally threaded barrel with two flat finger wings for hand-tightening, built from the BOSL2 threading and shape libraries. A single printable solid. Tune the thread size and pitch, body height, and wing span.

    Example
  • Worm gear

    The wheel half of a worm drive: a throated spur gear whose teeth are curved to wrap around a mating worm screw. Pairing a worm with this wheel gives a high reduction, self-locking right-angle drive. Tune the module, tooth count, worm diameter, worm starts, and bore.

    Example
  • Worm screw (drive)

    The screw half of a worm drive: a helical thread that turns the mating worm wheel. One full turn of the worm advances the wheel by one tooth (per start), giving a large, self-locking reduction. Print this plus the worm gear wheel. Tune the module, length, diameter, and thread starts.

    Example
  • 2020 corner bracket (3-way)

    A 3-way corner bracket that joins three 2020 aluminium extrusions at a right-angle corner, with M5 bolt holes. From the adgaudio OpenSCAD_connectors library.

    Example
  • 2020 corner bracket (flat L)

    A flat L-shaped bracket that joins two 2020 aluminium extrusions in-plane, with M5 bolt holes. From the adgaudio OpenSCAD_connectors library.

    Example
  • 2020 extrusion end cap

    A press-fit end cap that closes the open end of a 20x20 aluminium extrusion, with an M5 bolt clearance hole. From the adgaudio OpenSCAD_connectors library.

    Example
  • 2020 T-slot extrusion bar

    A length of standard 2020 aluminium-style T-slot extrusion (20 by 20 mm cross section) with four T-channels, ready to print as a jig rail, frame member, or mock-up of real metal extrusion. Change the length to suit your build.

    Example
  • 2040 V-slot extrusion rail

    A length of 2040 aluminium-style extrusion (40 by 20 mm cross section) cut with V-shaped channels, the kind used for CNC and 3D-printer gantries that ride on V-wheels. Print it as a linear-motion rail mock-up or a sturdy frame member.

    Example
  • 2060 extrusion base bar

    A length of wide 2060 aluminium-style extrusion (60 by 20 mm cross section) with six T-channels across its face, perfect as a base bar or work-surface rail that needs lots of mounting slots. Resize the length for benches, fixtures, or camera sliders.

    Example
  • 3030 T-slot extrusion beam

    A length of 3030 aluminium-style extrusion (30 by 30 mm cross section) with four T-channels, a popular mid-weight size for printer frames, camera rigs, and shelving. Print it as a structural beam and adjust the length to fit your build.

    Example
  • 4040 heavy-duty extrusion post

    A short length of beefy 4040 aluminium-style extrusion (40 by 40 mm cross section) with eight T-channels, ideal as a corner post or load-bearing upright in a printed frame. Lengthen it for a full column or keep it short as a connector block.

    Example
  • Gridfinity storage bin 2x1x3

    A printable Gridfinity storage bin two grid cells wide, one deep, and three units tall, with magnet and screw pockets in the base and a finger-slide scoop for easy parts removal.

    Example
  • Gridfinity divided bin with label shelf

    A printable Gridfinity bin three cells wide and two deep, split into three chambers by internal dividers, with a sloped label shelf across the front for marking each compartment.

    Example
  • Gridfinity glue stick holder

    A printable Gridfinity cup sized to cradle a standard glue stick upright, with a snug bored pocket and a slightly flared mouth so the stick drops in and lifts out cleanly.

    Example
  • Gridfinity socket wrench holder

    A printable Gridfinity tray that holds a row of socket-wrench sockets at a 45-degree tilt for easy grabbing, with an engraved size label along the front edge.

    Example
  • Gridfinity weighted baseplate 3x2

    A printable Gridfinity baseplate three cells wide and two deep with hollow pockets in the underside for steel weights or screws, giving the grid a heavy, stable footing on the desk.

    Example
  • 608 bearing pillow block

    A printable pillow-block housing sized from the official ISO bearing table for the popular 608 skate bearing, with a press-fit pocket, a shoulder lip so the bearing seats square, and two mounting-bolt holes. Drop a real 608 bearing in and bolt it to a frame.

    Example
  • GT2 belt idler pulley blank

    A smooth flanged idler-pulley blank sized to a GT2 timing belt from the official belt table, with a bore reamed for a 623 ball bearing pressed in from each side. The belt-running surface width matches the GT2 pitch so the belt tracks without rubbing. Press in two 623 bearings and run it on an M3 shaft.

    Example
  • LM8UU linear bearing clamp

    A saddle clamp that holds an LM8UU linear ball bearing, sized straight from the official linear-bearing table, with a cradle bore for the bearing, two M3 bolt ears to pinch it closed, and a flat mounting base. Snap an LM8UU in and bolt the carriage to your 3D-printer gantry.

    Example
  • M8 captive-nut knob

    A knurled hand knob with a captive hex pocket sized from the official DIN934 nut table for an M8 nut, plus a clearance bore for the M8 bolt shank. Drop a real M8 nut in the trapped pocket and you have a tool-free clamping knob for jigs and fixtures.

    Example
  • NEMA17 stepper motor bracket

    An L-shaped face-mount bracket generated from the official NEMA17 motor-mount table, with the correct 31 mm bolt circle, a center pilot bore for the boss, four M3 screw holes, and a slotted base so you can square the motor before tightening. Bolt a real NEMA17 stepper straight on.

    Example
  • OpenBeam 1515 corner frame

    An L-shaped corner made from two lengths of OpenBeam 15x15 t-slot extrusion meeting at a right angle, the kind of joint used to build the edges of a printer or enclosure frame. Set the length of each leg independently.

    Example
  • OpenBeam 1515 cube frame

    A full open box frame built from twelve lengths of OpenBeam 15x15 t-slot extrusion, the skeleton of an enclosure, light box, or display cube. Set the inner edge size and all twelve rails are placed automatically.

    Example
  • OpenBeam 1515 extrusion post

    A single length of OpenBeam 15x15 aluminium-style t-slot extrusion with four open channels and a center bore, ready to use as a frame rail or leg. Adjust the length to suit your build.

    Example
  • OpenBeam 1515 parallel rail bed

    A row of evenly spaced parallel OpenBeam 15x15 t-slot rails, like the gantry or bed support of a 3D printer or CNC. Choose how many rails, how far apart they sit, and how long each one runs.

    Example
  • Helical spur gear

    An involute gear whose teeth twist along the thickness for quieter, smoother running than a straight-cut gear. Increase the twist for a steeper helix angle.

    Example
  • Gear with reinforced hub

    An involute spur gear with a raised cylindrical hub around the bore that adds grip length for a set screw or press-fit shaft. Tune the hub height and diameter for your shaft.

    Example
  • Meshing gear pair

    Two involute spur gears spaced so their pitch circles touch and the teeth mesh, ready to print as a working reduction stage. Adjust the pinion and wheel tooth counts to set the gear ratio.

    Example
  • Rack and pinion set

    A toothed rack bar paired with a round pinion gear that rolls along it, converting rotation into straight-line travel. Print both to build a linear actuator or sliding mechanism.

    Example
  • Involute spur gear

    A single printable involute spur gear with a centered shaft bore. Tune the tooth count, tooth pitch, thickness, and hole diameter to fit your drivetrain.

    Example
  • Arduino UNO Case

    A custom-fit Arduino UNO R3 enclosure base with matched mounting standoffs and USB and barrel-jack cutouts on the wall.

    Example
  • Electronics Enclosure Box

    A parametric 3D-printable electronics project box base with PCB standoffs and lid mounting posts.

    Example
  • Snap-On Enclosure Lid

    A parametric 3D-printable enclosure lid with an alignment lip and countersunk screw holes that mates to the matching box.

    Example
  • Panel-Mount Project Box

    A tall electronics project box with a row of round panel-mount holes on the front face for connectors and switches.

    Example
  • Raspberry Pi B+ snap-on bumper

    A low-profile protective bumper that clips around the edge of a Raspberry Pi 2/3/B+ board, with two external ear tabs drilled for wood screws so the whole board can be fastened flat to a panel or wall.

    Example
  • Raspberry Pi B+ enclosure box

    A walled case base for a Raspberry Pi 2/3/B+ with integrated tapped standoffs, side cut-outs for the USB, ethernet and power ports, and clip slots along the top edge that accept the matching snap-on lid.

    Example
  • Raspberry Pi B+ tapped standoffs

    A set of four tapered standoffs positioned at the exact mounting-hole spacing of a Raspberry Pi 2/3/B+ board, each with a self-tapping screw hole so the board can be raised off a baseplate or screwed into a case floor.

    Example
  • Raspberry Pi B+ enclosure lid

    The snap-fit top cover for the Raspberry Pi 2/3/B+ case base, with a recessed inner lip and four flexible clips that lock it onto the enclosure clip slots.

    Example
  • Raspberry Pi Zero tapped standoffs

    Four short tapered standoffs spaced for the compact Raspberry Pi Zero mounting holes, each tapped for a self-threading screw so a Zero can be lifted off a baseplate or anchored inside a slim project box.

    Example
  • Snap-fit cable grommet

    A round cable pass-through grommet with a cantilever snap-fit post on top, so it clips into a panel hole and stays put without screws. Tune the disc size, the cable bore, and the snap post to match your panel thickness and wire bundle.

    Example
  • Snap-together box clip coupler

    A two-plate coupler that snaps shut on itself: the bottom plate carries a positive snap-fit post and the matching top plate has the negative socket bored into it, so the two halves click together and stay closed. Print both, set the same diameter, and press them home. Great for closing enclosures or joining panels without fasteners.

    Example
  • Snap-in PCB standoff foot

    A tapered standoff foot with a chamfered snap-fit pin that pushes into a mounting hole on a circuit board or chassis and locks underneath. Print four to stand a board off its case. Tune the foot size and the pin diameter to match your board holes.

    Example
  • Push-in snap rivet

    A double-ended plastic push rivet: a snap-fit head on each end of a short waist, so it pushes through two aligned panel holes and locks both sheets together like a trim clip. Tune the head diameter, lip, and waist length for your combined panel thickness.

    Example
  • Auger drill bit

    A printable auger-style bit with a deep helical flute that comes to a point, the shape used for hand drills, soil augers, and material feeders. Print it as a demo, a feeder screw, or a soft-material auger. Tune the diameters, height, and pitch to change how aggressive the flute is.

    Example
  • Threaded storage jar neck

    A small open-top storage jar whose neck carries external threads, so a matching threaded lid screws on tight. Print it for screws, beads, spices, or small parts. Resize the body and the neck thread to make any jar you need.

    Example
  • M10 hex nut

    A printable M10 hex nut with metric-standard internal threads, sized to thread onto a matching M10 bolt. Great as a captive nut, a knob, or a spare fastener. Adjust the diameter for any metric size and the thickness for a thinner jam nut.

    Example
  • M8 hex-head bolt

    A real, fully printable M8 hex-head machine bolt with metric-standard threads, a hex head, and a built-in hex-key recess on top. Print it for fixtures, jigs, or anywhere a plastic fastener works. Change the diameter and length numbers to make any metric size.

    Example
  • Threaded grip knob

    A round, knurled-free grip knob with a threaded blind hole in the base so it screws straight onto an M6 stud or bolt. Use it as a tightening handle for jigs, clamps, or machine adjustments. Tune the knob size or the thread diameter to fit your hardware.

    Example
  • Basic project box enclosure

    A clean two-part snap-together project box sized for a small circuit board, with a base tray and matching overlapping lid. Adjust the board length, width, and wall height to fit your own electronics.

    Example
  • PCB tray with standoffs

    A base tray and lid with four printed standoffs that lift and fixate a circuit board off the floor, leaving room underneath for solder joints, plus a side cutout for a power jack. Tune the standoff height and diameter for your board's mounting holes.

    Example
  • Tool-free snap-fit box

    A compact enclosure that clicks shut with integrated snap-fit clips on all four walls, so it needs no screws to close. Great for battery holders or quick-access gadgets. Adjust the clip width and box height to control how firmly the lid grips.

    Example
  • Vented enclosure with USB port

    A project box whose lid carries a row of ventilation slots for airflow and whose front wall has a rectangular cutout for a USB connector. Ideal for boards that run warm. Tune the slot count, slot size, and port opening to match your hardware.

    Example
  • Wall-mountable screwed case

    An enclosure with external mounting flanges on two sides so it can be screwed to a wall or panel, plus internal screw posts that bolt the lid down onto the base for a secure, serviceable closure. Tune the flange screw size and post diameter to your fasteners.

    Example

Materials & Textures

  • Make a red metallic material

    Create a PBR material and assign it to the selected mesh. Properties are live setters; changes update the renderer immediately.

    Example
    What you'll seeconsole line: "Assigned red to <mesh name>"; viewport: mesh shows the new red metallic material.
  • Bind a material by name (no UUIDs)

    Name-first material workflow: create by name, resolve by name with getMaterial, set it on a mesh, then broadcast it to several meshes by name. Never capture a materialId UUID.

    Example
    What you'll seeconsole line confirming the bound material; viewport: the named meshes all show the Steel material.
  • Make every mesh emissive blue

    Walk every mesh in the scene and assign a flat unlit blue material. Quick way to silhouette a whole asset.

    Example
    What you'll seeconsole line with painted mesh count; viewport: every mesh renders flat blue.
  • Duplicate a material with a tweak

    Take the selected mesh material, duplicate it under a new name, dial the roughness up, and assign the variant.

    Example
    What you'll seeconsole line: "switched <mesh name> to <new material name>"; viewport: mesh material is the rougher variant.
  • Delete unused materials

    List every material in the asset and remove any that no mesh references.

    Example
    What you'll seeconsole line with removed-materials count.
  • Assign a hash-of-name material color to every mesh

    Build a few named meshes, then give each one a unique material whose base color comes from a hash of its name. Handy for telling parts apart in a screenshot.

    Example
    What you'll seeconsole: per-mesh name + assigned material name; viewport: every mesh shows a distinct color.
  • Find meshes with no material assigned

    Walk every mesh in the scene and report the ones with no resolvable material. Pairs with the inventory recipe to flag shading gaps before export.

    Example
    What you'll seeconsole: list of mesh names missing materials; outliner: those meshes are selected so the user can fix them in one pass.
  • Author a PBR material and roundtrip every channel

    Create a red metallic material, assign it to a cube, log every PBR field, then mutate via live setters to flip it to a blue rough double-sided variant.

    Example
    What you'll seeconsole: every PBR field read back, then re-read after the live setters flip the material from red metallic to blue rough.
  • Get a material by name and delete it

    Spawn a cube; create + assign a material; look it up by name; list every material; then delete the material (which also unassigns it).

    Example
    What you'll seeconsole: null for a missing name, the looked-up material, the material count, then null after delete.
  • Color toolkit: RGB / hex / HSL factories, lerp, multiply, to-hex

    Color handle walk-through: every factory, channel getters, blend with lerp / multiply, and round-trip through hex and HSL.

    Example
    What you'll seeconsole: r/g/b channels, hex round-trip, HSL components, lerp toward white, and a tint via component-wise multiply.

Selection

  • Select every mesh sharing a material

    Build meshes, paint two materials across them, then pick the seed mesh's material and select every other mesh that shares it. Mass-edit shading in one pass.

    Example
    What you'll seeconsole: count of meshes sharing the seed material; outliner: exactly those meshes are selected.
  • Invert the selection across all meshes

    Build the set of unselected meshes, then swap the selection so it contains exactly those instead. Invert-selection behavior for the mesh layer.

    Example
    What you'll seeconsole: before / after selection counts; outliner: every mesh that was unselected becomes selected.
  • Run grow / shrink / invert / select-by-face-sides and convert across component modes

    Spawn a subdivided cube; switch to vertex/edge/face mode; grow/shrink/invert; select-all, linked, loose, non-manifold, similar, sharp-edges, nth, interior; shortest-path; convert via toVertices/toEdges/toFaces/toIslands/toUVs; bulk-translate the selection.

    Example
    What you'll seeconsole: status line after every selection op; bulk translate confirms.

Snap, Align & Distribute

  • Snap one object onto another

    node.snapTo(target) copies the target node's world-space translate onto this node. Zero offset, polymorphic, one undo step.

    Example
    What you'll seeconsole line with the moved node's new world translate, matching the target.
  • Snap to the nearest scene transform

    node.snapToNearest({ mode: "transform", range }) finds the closest OTHER scene transform within range and snaps to it (returns null if none).

    Example
    What you'll seeconsole line with the snap distance, or "nothing in range" when no transform is within range.
  • Snap to a mesh surface

    Drop a locator onto the closest point of a target mesh surface using mesh.geometry.closestPoint(point, { space }) + node.translate.set(...). (node.snapToNearest mode:"surface" is unavailable from script — the surface branch calls a mesh method that is only exposed under mesh.geometry.)

    Example
    What you'll seeconsole line with the surface-hit position + travel distance.
  • Match a node exactly (t + r + s)

    node.matchTransform(source) copies the source node's WORLD translate, rotate AND scale onto the target in a single undo step. It takes ONLY a source (a Node handle / name / {name|nodeId|id}) — it always copies all three components (no per-channel flags). Useful for stamping duplicates onto reference transforms.

    Example
    What you'll seeconsole shows Target TRS before (origin / identity) and after — after equals the Source's t+r+s; single Ctrl+Z reverts all three.
  • Distribute and align a row of objects

    node1.distribute([node2, node3], { axis }) spaces nodes evenly between the first and last; node1.align([node2, node3], { axis, mode }) snaps every node's axis component to the min / center / max of the set.

    Example
    What you'll seeconsole line with x-positions [0, 2, 4, 6, 8]; 5 cubes evenly spaced + bottom-aligned.
  • Tune the viewport snap settings

    dev.snapSettings is a getter/setter for the gizmo snap state shown in the channel box (snapAngle / snapStep / snapScale / snapMode).

    Example
    What you'll seechannel-box snap section shows 15° angle + 0.25 step + rotate mode.
  • Snap the second selection onto the first, then verify

    Use node.snapTo to copy the first selected node's world translate onto the second, then read both world translates back and assert they match within 1e-5.

    Example
    What you'll seeconsole: mover world translate before / after; final line "MATCH" or "MISMATCH" with the residual delta.
  • Distribute and bottom-align a row of selected nodes

    Build a scattered row of cubes, evenly space them along X via node.distribute, then snap every Y to the minimum so the whole row sits on one baseline.

    Example
    What you'll seeconsole: per-node x / y after the pass; viewport: evenly spaced, bottom-aligned row.
  • Place spheres on a line and distribute them evenly

    Spawn five small spheres, pin the first and last to fixed anchors, then call node.distribute to space the middle three evenly between them.

    Example
    What you'll seeconsole: each sphere's final world X position; outliner: 5 spheres under one group.

Spatial Queries

  • Fill a character with spheres

    Build a closed volume, then fill it with small spheres on a regular grid, keeping only the ones whose centre sits inside the surface.

    Example
    What you'll seeconsole: "packed N spheres into <volume name>"; viewport: a group of small spheres clustered inside the volume.
  • Measure the distance between two named parts

    Build two named parts, look them up by name, read their world translates, and report the straight-line distance through MathLib.distance.

    Example
    What you'll seeconsole: per-part position + the distance in scene units.
  • Find the nearest mesh to a target point

    Build a spatial index from every mesh centroid in the scene and query the closest one to a target point. Marks the hit with a locator so the answer is visible.

    Example
    What you'll seeconsole: nearest mesh name + distance; viewport: locator placed on the centroid of the winning mesh.
  • Select every mesh within a radius

    Scatter several meshes, build a kd-tree over their centroids, and select every mesh whose centroid sits inside a sphere around a probe point.

    Example
    What you'll seeconsole: list of selected mesh names within the radius; outliner: exactly those meshes appear selected.
  • Compute the bounding-box union of the selection

    Build a spread of meshes, combine their bounding boxes into one envelope, then drop markers at the min and max corners so the combined volume is visible.

    Example
    What you'll seeconsole: union bbox min / max + diagonal length; viewport: two markers framing the combined volume.
  • Snap a marker to the nearest vertex on a mesh

    Build a mesh, index every vertex into a kd-tree, then snap a fresh marker to the vertex closest to a probe point.

    Example
    What you'll seeconsole: nearest vertex index + position + distance; viewport: a marker named "VertMarker" sitting on that vertex.
  • Build, query, expand, transform, and compare bounding boxes

    Pull a mesh AABB, then construct boxes via from / fromCenterAndSize / fromPoints / empty. Read every property (center / min / max / size / width / height / depth / isEmpty), exercise expand / expandBox / clone / transformedBy, and run contains / intersects / equals predicates.

    Example
    What you'll seeconsole: mesh AABB + 4 static-factory boxes + every property + expand / expandBox / clone results + contains / intersects predicates + transformedBy result.
  • Build and query 2D and 3D spatial indexes

    Construct MathLib.kdTree3D and MathLib.kdTree2D over a synthetic point cloud; demonstrate the KdTree3D + KdTree2D class re-exports.

    Example
    What you'll seeconsole: tree types verified via instanceof; closest + within results.

Attributes

  • Tidy the channel box & add a custom attribute

    Hide channels you do not animate, add a user-defined float attribute, and list what is left. setKeyable controls channel-box visibility only; it does not lock the value.

    Example
    What you'll seeconsole output shows scale keyable=false, wobbleAmount=0.75, and lists keyable + user-defined channels.
  • Drive one attribute from another

    Connect a source attribute so it drives a destination (attribute-driven connection). Pass { force: true } to replace an existing incoming connection in one undoable step.

    Example
    What you'll seeconsole output shows B.follows=5 after driving from A, then =9 after reconnecting to C with force.
  • Add a bounded slider attribute (min / max)

    Use min and max on addAttr to clamp a custom channel to a range. Out-of-range set() throws so script errors surface loudly instead of silently clamping.

    Example
    What you'll seeconsole: wetness=0.75; out-of-range write rejected with InvalidArgumentError.
  • Hide an internal state attribute from the channel box

    Use hidden:true to keep a custom attribute out of the channel box. Useful for rig-internal state that scripts read but artists should not edit.

    Example
    What you'll seeconsole: rigState=idle; hidden attribute does NOT appear in the keyable channel list.
  • Clean up every custom attribute on a node

    Iterate the user-defined attribute list and remove each one. Undo restores everything, including any connections that were live when the attr was removed.

    Example
    What you'll seeconsole: before list with custom attrs, after list empty.
  • Wire and unwire attributes from the Node handle

    Node.connect / Node.disconnect take both endpoints as paths; convenient when you have the source and destination Node handles in scope. Pass force:true to replace an existing incoming connection.

    Example
    What you'll seeconsole: B.driven=11 after connect, then =0 after disconnect.
  • Paint a deformer falloff from distance to a reference point

    Build a mesh + a twist deformer, then write a 1/(1+d) per-vertex weight from each vertex to a reference marker so the deform fades out with distance. Demonstrates the per-vertex weight setter on a live deformer.

    Example
    What you'll seeconsole: vertex count painted + min/max weight + a non-zero peak deform delta proving the weights drive the deform.
  • Attribute lifecycle: lock, limits, keyable, getAsAngle/getAsString

    Walk an Attribute through its full state space. nodeId + path identify it; get/set is the value pair; lock/isLocked guards writes; setLimits/getLimits/enableLimits enforce ranges; setKeyable/isKeyable toggles channel-box visibility; getAsAngle / getAsString are typed readers.

    Example
    What you'll seeconsole: identity + r/w + bounds + lock + keyable + typed reads.
  • Inspect a deformer handle: meshId, type, displayName, envelope, weights

    DeformerHandle exposes the live deformer record. Identity: meshId + deformerId + deformerType + displayName. Common params: envelope + enabled. Per-vertex: weights[i] read + setWeight(i, w) write.

    Example
    What you'll seeconsole: handle identity + weights length + write evidence.
  • DeformerAttribute: typed param access on a deformer record

    DeformerAttribute is the per-parameter handle on a deformer. meshId + deformerId + param identify it; get/set is the typed value pair.

    Example
    What you'll seeconsole: identity + initial reads + post-write reads.
  • Vec3Attribute: read translate axes from a compound plug

    Compound 3-vector handle on every Transform. Inspect the basePath plus the three per-axis Attribute<number> descriptors.

    Example
    What you'll seeconsole: basePath = "translate"; per-axis get() values matching the cube position; bumped X after a per-axis set.

Outliner

  • Sort + lock the outliner for a clean review

    Move named heroes to the top, lock finished assets, and filter for review.

    Example
    What you'll seeconsole line with hero count and lock count; outliner expanded + filtered to "Hero".
  • Batch-rename every mesh with an index prefix

    List every mesh in the scene, capture the original names for a verification pass, then rename each one as "<idx>_<oldName>".

    Example
    What you'll seeOutliner shows every mesh prefixed with "001_", "002_", ...; console reports before/after pairs; one undo step reverts everything.
  • Group the selection under a named parent

    Build a few parts, then wrap them under a fresh group named after a prefix you pick. The whole operation lands as one undoable batch.

    Example
    What you'll seeconsole: group name + child count + each child name; outliner: a new group containing the parts.
  • Walk a small parent + children scene with the node API

    Build a Group with two cube children, then read identity (name, id, nodeType, toString) and walk parent / children / descendants / ancestors.

    Example
    What you'll seeconsole: group toString + identity, direct + transitive child lists, leaf ancestors, equality across re-resolved handles.
  • Reorder, reparent, unparent, and delete sibling nodes

    Spawn three sibling cubes, swap their order with moveBefore / moveAfter / moveUp / moveDown, group two of them, then unparent and delete.

    Example
    What you'll seeconsole: sibling order after each reorder + group children + post-unparent parent + post-delete count.
  • Duplicate vs instance, recenter pivot, align axis, toggle visibility

    Spawn a base cube, deep-clone it (independent geometry), make a sibling instance (shared geometry), recenter the pivot, align Y to the base, then hide / show / toggle / unlock.

    Example
    What you'll seeconsole: visibility flag at each transition + lock state; viewport: 3 cubes (base, deep-clone, instance) framed.
  • Isolate, deisolate, showAll, and group selections

    Spawn meshes; isolate a subset; deisolate; hide and reveal; create an empty group; spawn a hook profile.

    Example
    What you'll seeconsole: status after isolate / deisolate / showAll; group name; snapScale toggled.
  • Collapse all and clear filter on the outliner

    Set a filter; clear it; collapse all branches; spawn a few nodes to drive the outliner state.

    Example
    What you'll seeconsole: outliner ops fired without throwing.

Compound Forms

  • Engine Cylinder (compound form)

    Vertical engine cylinder: central barrel + N stacked horizontal cooling fins + base flange with bolt circle + top cap + angled spark-plug boss with coaxial through-hole. Adapt the parameter constants at the top to fit your prompt.

    Example
    What you'll see12-fin vertical engine cylinder with a 35-degree spark-plug boss + coaxial through-hole. Z-extent reaches ~85mm.
  • Centrifugal Impeller (compound form)

    Backplate disk + central hub cylinder + axial through-bore + N radially-placed blades tilted backward. v1 uses rectangular blade slabs; true swept-curve blades land once a swept-curve primitive is available.

    Example
    What you'll see12-blade impeller with 45-degree backward-tilted rectangular blade slabs + central hub + axial bore.
  • Flange with Bolt Circle (compound form)

    Flat circular flange: low cylinder + central through-bore + N bolt holes arranged on a circular pattern. Useful as a mounting plate or pipe-flange end cap.

    Example
    What you'll seeFlat disc 100mm OD + 40mm through-bore + 8 bolt holes on a 80mm circle.
  • Ribbed Bracket (compound form)

    L-shaped bracket with N stiffening gussets evenly distributed along the depth axis at the inner corner. v1 uses rectangular gussets; true triangular gussets land once a custom-profile extrude primitive is available.

    Example
    What you'll seeL-bracket (40mm + 30mm arms) with 3 rectangular gussets at the inner corner along the 30mm depth.
  • Stepped Shaft with Keyway (compound form)

    Stepped shaft: three coaxial cylinders of decreasing diameter (large, medium, small) along Z + a rectangular keyway groove cut into the large segment. Common power-transmission shaft form.

    Example
    What you'll see3-step shaft (40/28/18mm diameters stacked along Z) with a 6x4x20mm keyway groove in the large segment.
  • Flanged Pipe Tee (compound form)

    Flanged 3-way pipe tee: vertical pipe + horizontal pipe meeting at the origin + flange discs at each of the 3 open ends. The interior bore runs through both arms of the tee.

    Example
    What you'll see3-way pipe tee with 30mm OD / 22mm ID + 50mm flange discs at all 3 open ends.

Other

  • Catch + classify every error class in the scripting API

    Every scripting-API error carries a stable .name + frozen .code + class-specific fields. Pattern-match on .name to dispatch; read class-specific properties for context.

    Methods usedModelEditor.scene.lsModelEditor.create.cubeModelEditor.create.groupUtils.wait.untilnode.attrnode.addAttrattribute.getattribute.setattribute.locktransform.freezeTransformattributeLockedError.codeattributeLockedError.operationattributeLockedError.nodeIdattributeLockedError.attrPathattributeNotFoundError.nodeIdattributeNotFoundError.pathdeformerStaleError.codedeformerStaleError.meshIddeformerStaleError.deformerIddeformerStaleError.deformerTypeeditorChangedDuringSessionError.codeeditorChangedDuringSessionError.toolIdeditorChangedDuringSessionError.meshIdeditorChangedDuringSessionError.fromeditorChangedDuringSessionError.tohistoryNotInitializedError.codeimportFailedError.codeimportFailedError.filenameimportFailedError.formatimportFailedError.underlyinginteractiveSessionStaleError.codeinteractiveSessionStaleError.toolIdinteractiveSessionStaleError.meshIdinteractiveSessionStaleError.previousStateinvalidArgumentError.argNamenodeNotFoundError.nodeIdnodeStaleError.nodeIdnodeStaleError.nameoperationBlockedByDialogError.codeoperationBlockedByDialogError.operationoperationBlockedByDialogError.dialogIdoperationCancelledError.codeoperationCancelledError.reasonoperationNotApplicableError.operationoperationNotApplicableError.reasonoperationNotInEditorError.operationoperationNotInEditorError.currentEditoroperationNotInEditorError.allowedEditorsoperationNotSupportedError.operationpermissionDeniedError.codepermissionDeniedError.resourcepermissionDeniedError.handlepersistedHandleStaleError.codepersistedHandleStaleError.persistKeypersistedHandleStaleError.lastSeenNamewaitTimeoutError.codewriteFailedError.codewriteFailedError.fileNamewriteFailedError.reason
    Example
    What you'll seeconsole: six real catches with class-typed field readout.
  • Browse, search, and run any registered Action

    List every Action; search by keyword; inspect the descriptor (name / category / script snippet); check applicability; invoke by id.

    Example
    What you'll seeconsole: total action count, first matches for "select", the descriptor + snippet for one action, applicability check, run result.
  • Sleep with Utils.wait.ms and poll with Utils.wait.until

    Demonstrate the two non-frame wait helpers: fixed-delay sleep and predicate poll.

    Example
    What you'll seeconsole: timestamps before and after each wait; predicate-driven loop completes.
  • Vec2 toolkit: build, blend, measure, normalize

    2D vector handle walk-through: factories, axis getters, length, lerp, distance, dot, normalize.

    Example
    What you'll seeconsole: axis getters, length, sum/diff/scale tuples, lerp midpoint, normalize length ~1, dot/distance.
  • Vec3 toolkit: factories, cross, rotate, transform

    3D vector walk-through: basis vectors, cross product, distance, normalize, and cross-type transforms (Quat / Mat3 / Mat4 / direction).

    Example
    What you'll seeconsole: axis getters, basis tuples, cross/dot/distance, then four transform variants on the X axis.
  • Vec4 toolkit: homogeneous transform, blend, normalize

    4D vector walk-through with the w-component driving homogeneous semantics: w=1 transforms as a point, w=0 as a direction.

    Example
    What you'll seeconsole: axis getters, math results, then point vs direction transform contrast (translate applies only when w=1).
  • Quat toolkit: axis-angle, slerp, compose, rotate, convert

    Quaternion walk-through: every factory, every blend (multiply / slerp / lerp), and conversion to Mat4 / Euler.

    Example
    What you'll seeconsole: factory outputs, composed rotations, slerp/lerp midpoints, then rotate(Vec3) and Mat4/Euler conversions.
  • Mat3 toolkit: identity, fromQuat, normal matrix, invert

    3x3 matrix walk-through: column-major factories, multiply / invert / transpose, normal matrix from a non-uniform-scale 4x4, and Vec3 transform.

    Example
    What you'll seeconsole: identity diag, R*R / R^-1 / R^T rows, normal matrix from a (2,1,1)-scale, and transformVec3 result.
  • Mat4 toolkit: TRS, lookAt, perspective, decompose, transform

    4x4 matrix walk-through: every specialized factory, view + projection, decompose round-trip, and the four cross-type transform variants.

    Example
    What you'll seeconsole: translation slot, projection diagonals, decompose triple, then point vs vector vs direction vs vec4 transforms.
  • Euler toolkit: fromQuat, reorder, round-trip to Mat4 and Quat

    Euler angle walk-through: convert from Quat / Mat4, change rotation order, and round-trip back to Quat / Mat4.

    Example
    What you'll seeconsole: XYZ Euler from a 90 deg Z rotation, reorder to YZX, fromMat4 result, and round-trip back to Quat / Mat4.
  • Install an off-the-shelf M5 bolt

    Drop an M5 hex-cap bolt into the scene from the bundled catalog (12,718 STEP parts). Use this pattern for ANY standard hardware: bolts, bearings, nuts, washers, standoffs, motors. The catalog is workflow A in DOCTRINE: try the catalog FIRST before composing geometry from primitives.

    Example
    What you'll seeM5 hex-cap bolt installed at [10, 0, 0]; the catalog covers ~12K parts under CC0 / CC-BY / MIT / Apache-2.0 licenses.
THIS IS THE ANIMBOX BOOTSTRAP — read once, do NOT re-fetch. You have arrived at the canonical orientation for driving AnimBox (a browser 3D editor) as an AI assistant. Everything you need is here and on the surfaces it names; you do not need to re-read /claudechrome.md, the #llm-bootstrap node, or help() output more than once per session. START SEQUENCE — three steps, in order: 1. ASK INTENT first. Confirm what the user wants before building, naming the path by its tool: SCAD — parametric / printable / mechanical parts via execOpenScad (⚠ bakes to a TRIANGLE-only static mesh, not re-editable as quads); AnimBox Geo Utils — editable-quad meshes via create.* + mesh.* (the default for organic / game assets you keep sculpting); import-and-tweak an existing file (io.*); or an off-the-shelf catalog part (catalog.search). Or Auto - best tool: let the path follow the part — e.g. SCAD for a frame/engine, AnimBox Geo Utils for a tank/seat. The right workflow depends entirely on this answer — when the SCAD-vs-Geo-Utils choice is material (printable / parametric / mechanical) and you cannot confidently route, ASK ONE QUESTION; never silently pick. 2. OPEN the Script Editor — your ONLY execution path. Press Ctrl+Alt+E (fallbacks in UI Affordances below). 3. RUN help() in the Script Editor. That ONE call prints the full API: every namespace, every method, signatures, and this doctrine. The full surface lives there — not in any doc you must fetch. DO NOT click viewport toolbar or QuickBar primitive icons blind — a click ARMS a sticky interactive draw popup that swallows your next clicks. Clear it with `Utils.cancelActiveTool()` (scriptable ESC), or press ESC / Cancel. Drive everything through the Script Editor instead. AnimBox AI-assistant bootstrap — doctrine version 1.8. If you already hold this version, do NOT re-fetch; poll /llms-version.json (bootstrapPayloadVersion) to detect changes between sessions. AnimBox — non-negotiables for AI assistants: 1. Always call `<Editor>.help()` (e.g., `ModelEditor.help()`) before guessing argument syntax. Discovery beats spelunking. Drill via `<Editor>.<namespace>.help()` for an operations TOC, then `<Editor>.<namespace>.<name>.help` for Description / Input / Returns on a specific method. 2. Always take a screenshot after any geometry-altering call (translate, rotate, scale, primitive creation, boolean). Numeric state can be right while visual output is wrong. Use `<Editor>.viewport.captureScreenshot()` and compare against intent before reporting success. 3. Dismiss blocking modals before your first interaction. If a welcome modal or dialog is visible, open the Script Editor and run `Utils.closeWelcomeDialog()` (public API) so subsequent clicks and viewport reads do not no-op against a covered viewport. 4. Translate every newly-created primitive away from the origin (e.g., apply `+[2.5, 1.3, -0.7]` immediately after creation) so the next primitive does not stack on it. Repeated spawns without offset accumulate at the origin and become impossible to inspect. 5. Resolve nodes by NAME first, fall back to nodeId. UUIDs are write-only; names survive refactors. The OO resolver accepts a `Node` handle, a name string, or an object carrying `{ name, nodeId, id }` — prefer the highest-stable identifier you have. 6. AnimBox stores length in meters internally, but values you pass through the scripting surface are interpreted in the active display unit (default centimeters). Use `<Editor>.viewport.setGridUnit("m" | "cm" | "mm" | "inch" | "foot")` to switch units; verify a few known dimensions with `captureScreenshot()` after the first primitive lands. 7. Match positional intent with deterministic measurement, not vibes. `<Editor>.inspect.measure(a, b, axis?)` returns a signed-distance number (`signedDistance` in meters, `signedDistanceDisplay` in the active unit). `<Editor>.inspect.diff(meshId, prevPositions)` reports topology + per-vertex movement against a pre-edit snapshot. Use both before declaring an edit "done". 8. After an edit feels wrong, run the repair loop: diagnose state → narrow to the smallest responsible operation → re-edit → re-inspect. Do NOT rewrite the whole script. Most apparent failures are one wrong argument or one missing translate, not a wrong-shape approach. 9. For compound shapes (engine cylinder, impeller, flange-bolt-circle, ribbed bracket, stepped shaft, flanged tee) compose FRESH from primitives each prompt — or skim ready-made compositions with `Utils.recipes.list({ editor: "model" })`, read one via `Utils.recipes.code(id)`, and ADAPT it (run it directly with `Utils.recipes.run(id)`). Each entry shows `create.<primitive>()` chained with `mesh.boolean(other, "union"|"difference"|"intersection")` + `xform({t, r, s})` + for-loops. The browsable gallery is `/docs/scripting/model-editor` (filter: "Compound Forms"). Your script wraps in one history group, so `await history.undo()` (Ctrl+Z at the keyboard) reverts the whole composite in one step. 10. Set materials AFTER mesh creation. New meshes default to gray. Create an explicit material via `<Editor>.create.material({ name, baseColor, ... })` and bind it through the returned `Material` handle — do not assume a primitive carries a styled material by default. 11. Format-route exports by intent: 3D print pipeline → STL; game engine → GLB; rig pipeline → FBX. Use `<Editor>.io.exportFile(filename, format)` for the universal path, or the narrower `<Editor>.io.exportModel(...)` / `exportAnimation(...)` helpers for editor-specific exports. 12. Report only checks actually run. Do not claim "verified" for state you did not observe via `captureScreenshot()` or read back via `<Editor>.ls()`. Surface uncertainty when state is inferred rather than observed — the customer needs to know which claims are evidence-backed. 13. For off-the-shelf STANDARD HARDWARE and electronics-mounting parts (fasteners, nuts, washers, bearings, aluminum extrusions, standoffs, heat-set inserts, shaft collars, NEMA stepper mounts, rack panels, fan ducts), `catalog.*` is a searchable library of 12,000+ industrial CAD parts — it carries NO character props or decorative assets; compose those with `create.*` instead. Call `catalog.search("M5 screw")` or `catalog.search("NEMA stepper")` for tokenized matches (every word must match); `await catalog.install(id, { position: [x, y, z] })` imports the part AT that position (meters; omit it for the default offset — repeat installs land side-by-side, never stacked) as one undo step (`await history.undo()` — or Ctrl+Z at the keyboard — reverts the whole install). Browse interactively via `await catalog.browse()`. Do not model standard hardware by hand. 14. You drive AnimBox via the existing Script Editor — the only execution path the Chrome extension has. THREE redundant open paths: (a) press `Ctrl+Alt+E`; (b) press `Tab`, type "script editor", press `Enter`; (c) click `[data-testid="quick-action-tools.script-editor"]` inside `[data-testid="quick-function-popup"]`. Any one path failing leaves the other two. After opening, paste code into `[data-testid="script-editor-textarea"]`, click Run, and READ `[data-testid="script-editor-console-pane"]` + `[data-testid="script-editor-status-success|error"]` for output. 15. Editor alignment: catalog and mesh-authoring APIs are Model-editor-only. Before calling any `ModelEditor.catalog.*` / `ModelEditor.create.*` method, call `Utils.editor.current()` — if it returns anything other than `"model"`, call `await Utils.editor.switchTo("model")` first. To see all publicly available editors, call `Utils.editor.list()` — it filters out alpha-gated modes. 16. Only Model and Previewer editors are publicly available. `Utils.editor.switchTo("controlrig")` and `Utils.editor.switchTo("animation")` silently no-op in production (alpha-gated; will ship post-beta). Do NOT assume those modes are reachable; use `Utils.editor.list()` to enumerate the public set. If your script needs a non-Model editor, switch via `Utils.editor.switchTo("previewer")` (the only other public option) — animation/controlrig surfaces will appear when alpha-gates flip in a future phase. 17. Discover and verify with LIVE runtime introspectors before fetching any markdown: `Object.keys(ModelEditor.create)` enumerates the primitives, `ModelEditor.help()` prints the doctrine + namespace grid, `ModelEditor.<namespace>.<name>.help` reads one method, and `Utils.examples.list()` / `Utils.recipes.list()` list runnable worked examples (`Utils.recipes.run(id)` executes one; `Utils.recipes.code(id)` returns its source to adapt). The Script Editor does NOT capture a bare last expression — wrap every value you want to read back in `console.log(JSON.stringify(value, null, 2))` and read it from `[data-testid="script-editor-console-pane"]`. Fetch `/claudechrome.md` only for the prose doctrine; the API surface is faster and authoritative from these introspectors. 18. Do NOT click viewport toolbar or QuickBar primitive icons to build geometry — they ARM a sticky interactive draw popup that blocks subsequent calls. The scriptable disarm is `Utils.cancelActiveTool()` (the equivalent of pressing ESC or clicking Cancel). Build EVERYTHING through the Script Editor: `await create.<primitive>(opts)` then `xform`, `mesh.boolean`, and `setMaterial`. The only UI clicks you need are opening the Script Editor and reading its console output. 19. Center the pivot BEFORE you rotate: primitive geometry can sit offset from its pivot (a torus centers at `[0, tube, 0]`, not at the pivot), so rotating an un-centered pivot swings the shape out of alignment — call `await mesh.centerPivot()` first. And verify POSITION from the GEOMETRY, never the transform: read `mesh.geometry.bbox({ space: "world" }).center` (canonical meters) — a centered-looking `translate` value can hide an offset shape, and reading the transform back is the classic false-green. Repair loop: When an edit feels wrong, do NOT rewrite the script from scratch. Run the three-phase repair loop. DIAGNOSE — read state directly with the precision-validation cluster. Call `<Editor>.ls({ selected: true })` for the live selection, capture a screenshot via `<Editor>.viewport.captureScreenshot()`, call `<Editor>.inspect.measure(a, b, axis?)` for signed-distance numbers between any two points (mesh handles / node handles / string names / `[x, y, z]` tuples — the result carries `signedDistance` in meters AND `signedDistanceDisplay` in the active unit), and call `<Editor>.inspect.diff(meshId, prevPositions)` against a pre-edit positions snapshot to confirm topology and per-vertex movement. Numbers plus visuals together. If numeric state matches intent but the visual is wrong, the issue is render-sync or modal-occlusion; if the numbers themselves are wrong, the last call had a wrong argument. MINIMAL-EDIT — change the smallest responsible thing. Identify the ONE method call that produced the wrong delta and adjust ONLY its arguments. One wrong argument, one missing translate, one stale selection. Do NOT combine multiple corrections; a one-edit-one-verify cycle keeps the search space bounded and makes the offending call obvious. RE-INSPECT — rerun the diagnose tools. Confirm the delta is now zero (`inspect.measure` returns the expected offset; `inspect.diff` shows only the change you intended; the screenshot matches intent). If still wrong, narrow further — never broaden the edit. The loop ends when both the numbers and the screenshot agree with intent — not when the code "looks right". Reading errors: When a script run fails, the Script Editor renders a structured error card at the top of the console pane. Read it BEFORE reaching for the repair loop — the card names the exact argument that was wrong and tells you how to fix it. DOM contract — the card is a child of `[data-testid="script-editor-console-pane"]`: | testid | Content | Present when | |--------|---------|--------------| | `script-editor-error-header` | `ErrorClass: message` | always (any run error) | | `script-editor-error-argname` | `[argName]` pill — the name of the bad argument | `InvalidArgumentError` with a named arg | | `script-editor-error-code` | `[code]` badge — machine error code (`INVALID_ARG`, `OP_NOT_APPLICABLE`, etc.) | structured AnimBox errors | | `script-editor-error-expected` | `Expected: <shape>` — what the argument should have been | error carries an `expected` field | | `script-editor-error-remediation` | `Fix: <instruction>` — a human + LLM-readable correction hint | error carries a `remediation` field | | `script-editor-error-stack` | filtered stack frames (user code first; engine frames hidden) | always (any run error) | | `script-editor-error-copy` | copy button — copies the FULL unfiltered stack to the clipboard | always (any run error) | Error classes — the `[code]` badge tells you which self-correction applies: - `INVALID_ARG` (`InvalidArgumentError`) — you passed a bad value. Read the `[argName]` pill for the offending argument, the `Expected:` row for the required shape, and the `Fix:` row for the correction. Example: `mesh.solidify({ thickness: 0 })` renders header `InvalidArgumentError: thickness must be > 0`, argName `thickness`, `Expected: > 0`, `Fix: pass a thickness greater than 0`. - `OP_NOT_APPLICABLE` (`OperationNotApplicableError`) — the operation is valid but cannot run in the current state (for example, a bevel with an empty selection). Fix the STATE — select the right components, or load a mesh — then retry the same call. - `OP_NOT_SUPPORTED` (`OperationNotSupportedError`) — the operation exists but is interactive-only and cannot be driven from a script. Use the keyboard or menu path, or call `<namespace>.help()` for the scriptable equivalent. - `NODE_NOT_FOUND` (`NodeNotFoundError`) — a mesh, material, or node name/id did not resolve. Re-list the scene with `ls()` and re-resolve against a current name. - `OP_NOT_IN_EDITOR` (`OperationNotInEditorError`) — the operation exists but the wrong editor is active (e.g. a `ModelEditor.create.*` / `ModelEditor.catalog.*` call while the Previewer is active). Call `Utils.editor.current()`; if it is not `"model"`, `await Utils.editor.switchTo("model")` then retry the same call. Silent-no-op self-check (CRITICAL). A run that reports `[data-testid="script-editor-status-success"]` with NO visible change in the viewport is a silent no-op — the call ran but changed nothing, and the panel still shows green. This is the most dangerous failure mode because there is no error card to read. Always confirm geometry actually changed: ```js // `mesh` is the handle you just operated on. const before = mesh.verts.count; // ...run your operation on mesh... const after = mesh.verts.count; console.log('topology changed:', before !== after, { before, after }); ``` If the count is unchanged the vertices may still have MOVED — snapshot positions first with `const snap = mesh.verts.getPositions({ space: 'object' });`, run the op, then call `inspect.diff(meshId, snap)`. Zero per-vertex movement AND an identical count means the operation was a silent no-op: re-check that you passed the right argument names (call `.help` on the method) and that a mesh is actually selected. Recipes: Compose compound shapes FRESH from `create.*` + `mesh.boolean(other, "union"|"difference"|"intersection")` + `xform({t, r, s})` — that is the DEFAULT. Recipes are OPTIONAL seeds to adapt when one fits; when none fits, compose fresh with confidence and say so honestly. Most organic / editable forms are built fresh this way: a mushroom from a stretched sphere capped on a tapered cylinder, a leaf from a flattened-and-bent plane, a simple character head from a few merged spheres, a vase from a revolved profile. Parametric / mechanical / printable shapes (gears, threads, brackets) are usually cleaner via OpenSCAD — prefer it for those when appropriate; this is a SOFT preference only, never a default. To ADAPT a curated seed: `Utils.recipes.list({ editor: "model" })` lists ids, `Utils.recipes.code(id)` reads one to ADAPT, `Utils.recipes.run(id)` executes it through the production runScript; the browsable pages are `/docs/scripting/model-editor` + `/docs/scripting/previewer` (filter category "Compound Forms"). For a worked example of any specific symbol, use `Utils.examples.list()` / `Utils.examples.code(symbol)` / `Utils.examples.run(symbol)` / `Utils.examples.forSurface(apiPath)` (one example per public symbol). A symbol present in the catalog is confirmed-callable — trial-call it or read `Utils.examples.code(symbol)`; NEVER report a catalogued symbol as missing. Press Run (Ctrl+Enter) in the Script Editor — your entire script wraps in one history group, so `await history.undo()` (or Ctrl+Z at the keyboard) reverts the whole composite in one step. For OFF-THE-SHELF standard hardware (M5 screws, bearings, NEMA stepper mounts, standoffs), reach for `catalog.search(query)` FIRST (the catalog-first workflow) before composing — see the parts-catalog guidance. Catalog: Off-the-shelf parts ship as a searchable catalog on `catalog.*` (Model editor only — mesh authoring is Model-scoped). Call `catalog.list()` (12,000+ CatalogPart descriptors with id / name / license / stepUrl), `catalog.search(query)` for tokenized matches against name + tags (multi-word works — every token must match: `catalog.search('M5 screw')`, `catalog.search('shaft collar')`), `catalog.get(id)` for one part's metadata, and `await catalog.install(id, { position: [x, y, z] })` to import AT that position (meters; omitted → the default offset, nudged per repeat so duplicates land side-by-side) as ONE undo step — `await history.undo()` (or Ctrl+Z) reverts the install. A multi-part STEP install adds every sub-mesh; the returned handle is the first, siblings are named `"<part name> (2)"`, `"<part name> (3)"`, … reachable via `ls()`. Browse interactively via `await catalog.browse()`. The corpus is INDUSTRIAL hardware + electronics mounting: ISO/DIN fasteners, nuts / washers / standoffs, bearings, aluminum extrusions, heat-set inserts, shaft collars, NEMA stepper mounts, rack panels, fan ducts. NO character props or decorative assets exist — compose those fresh with `create.*`. Hot-path bundle of ~100 curated parts loads instantly; the long tail lazy-fetches on demand. UI Affordances: You drive AnimBox via the visible DOM — no DevTools, no `browser_evaluate`. Your bridge is the existing Script Editor. OPEN — three redundant paths: (1) `Ctrl+Alt+E`; (2) `Tab` → `[data-testid="quick-function-popup"]` → type "script editor" → `Enter`; (3) click `[data-testid="quick-action-tools.script-editor"]`. Any one failing leaves two. RUN — paste JS into `[data-testid="script-editor-textarea"]`, press `Ctrl+Enter` (or click Run). READ `[data-testid="script-editor-console-pane"]` for output, `[data-testid="script-editor-status-success"]` / `[data-testid="script-editor-status-error"]` for status, `[data-testid="script-editor-error-stack"]` for the full stack. The panel root is `[data-testid="script-editor-panel"]`. EDITOR FIRST — catalog and mesh-authoring APIs are Model-editor-only. Call `Utils.editor.current()` to read the active mode; if not `'model'`, `await Utils.editor.switchTo("model")` first. `Utils.editor.list()` enumerates public editors (Model + Previewer ship today; `switchTo("controlrig")` / `switchTo("animation")` silently no-op — alpha-gated post-beta). If a click ever armed a sticky interactive draw popup, call `Utils.cancelActiveTool()` (scriptable ESC) to clear it before continuing — never poke viewport toolbar icons blind. THREE AUTHORING WORKFLOWS — pick the right one, IN THIS ORDER: (A) CATALOG FIRST — `catalog.search(query)` for ADDITIVE off-the-shelf parts. The bundled catalog has 12,000+ STEP parts of INDUSTRIAL standard hardware + electronics mounting: ISO/DIN fasteners (M2-M12), nuts / washers / standoffs, bearings, aluminum extrusions, heat-set inserts, shaft collars, NEMA stepper mounts, rack panels, fan ducts (NO character props or decorative assets — those are workflow B compositions). Multi-word queries are tokenized (every word must match): `const hits = await catalog.search('M5 screw'); const mesh = await catalog.install(hits[0].id, { position: [x, y, z] });` — `position` is in meters and is honored; omit it for the default offset (repeat installs land side-by-side). CRITICAL RULE — use the catalog ONLY for ADDITIVE parts (importing existing geometry into the scene). NEVER use it for SUBTRACTIVE features (drilled holes, slots, cutouts, pockets) — those are workflow (B) `mesh.boolean(other, 'difference')`. Example: if the customer asks for "4 M5 mounting holes," the catalog has M5 SCREWS (additive); you want HOLES (subtractive) — drill with a 5mm cylinder via `mesh.boolean(hole, 'difference')`. Browse interactively: `await catalog.browse()`. (B) PRIMITIVES + BOOLEAN + EXAMPLES — AnimBox Geo Utils, the editable-quad path: `create.*` + `mesh.boolean(...)` for custom mesh geometry, compound forms, and SUBTRACTIVE features. 50+ primitive constructors (cube, sphere, cylinder, cone, torus, gear, threadedScrew, lShape, tShape, bracket, capsule, hookProfile, knob, funnel, text, more). Compose multi-step shapes by chaining confirmed-callable ops — `create.* + mesh.boolean + mesh.mirror + Node.radialDuplicate`: `await create.cylinder({...})` then `mesh.boolean(other, 'union'|'difference'|'intersection')` + `mesh.mirror({axis})` + `xform({t:[x,y,z], r:[0,90,0]})` + `Node.radialDuplicate({count, axis, angle})` + for-loops. Output stays editable as quads. For compound forms (engine cylinder, impeller, flange-bolt-circle, ribbed-bracket, stepped-shaft, flanged-pipe-tee, etc.), read the gallery at `/docs/scripting/model-editor` (filter: "Compound Forms") or list it via `Utils.recipes.list()` for head-start patterns to ADAPT. (C) OPENSCAD — SCAD, the parametric path: for native parametric extrude / sweep / hull / minkowski source click `[data-testid="script-editor-tab-add-menu-openscad"]` → write SCAD source → Bake. Pros: parametric primitives and operations OpenSCAD users already know — preferred for mechanical / printable parts. ⚠ Cons: bakes to a TRIANGLE-only static mesh (NOT re-editable as quads); for geometry you will keep editing as quads, use (B) AnimBox Geo Utils instead. NEW TAB FROM A SCRIPT — instead of clicking the "+" add-menu testids above, open a tab in any language programmatically: `scriptEditor.newTab({ language })`, where the `language` value is one of `'animbox'` or `'openscad'` (e.g. `scriptEditor.newTab({ language: 'openscad' })`). Pair it with the "+" add-menu item (`[data-testid="script-editor-tab-add-menu-openscad"]`) — the scriptable path means you never have to default to an AnimBox tab. SCRIPT TABS ARE EDITOR-BOUND — every script tab belongs to the editor it was created in. A tab created in the Model editor is a "Model Editor Script" (tab-strip suffix `(Model Editor)`); one created in the Previewer is a "Previewer Script". Opened OUTSIDE its editor, a tab renders READ-ONLY — still selectable/copyable, dimmed, with a scope banner naming its home editor — and Run is refused with a console hint (the same rule OpenSCAD tabs have always had outside Model). The "+ New Script" menu creates the ACTIVE editor's script type. Inside a tab, any code line referencing a FOREIGN editor namespace (e.g. `PreviewEditor.*` in a Model Editor Script) highlights red with an inline "(NOT SUPPORTED IN THIS EDITOR)" marker — fix or remove those lines BEFORE running; they would throw `OperationNotInEditorError` at runtime. To run code for another editor: switch editors first (`await Utils.editor.switchTo("previewer")`), then write it in a tab created THERE. VERIFY — `await viewport.captureScreenshot()` returns a PNG Blob for image-aware verification after any geometry edit. ANIMATION (Previewer) — `PreviewEditor.animation.{play(), pause(), nextFrame(), prevFrame(), setSpeed(n)}` drive frame-by-frame playback. Switch first via `await Utils.editor.switchTo("previewer")`. ASYNC — `await` EVERY call that loads or mutates (`io.openFile`/`io.exportFile`, `animation.*` transport, `material.pbr.<channel>.set`, `dev.verify`, `delete`). A non-awaited call HIDES the outcome: a validation/capability error becomes an unhandled rejection (looks like it worked but did nothing) and you read state before it settled. Two traps: (1) `io.openFile` RESOLVES BEFORE the scene graph finishes HYDRATING — poll `ls({type:'mesh'}).length` until non-zero (~1-2s for large files) before reading geometry/joints/clips; 0 means still-hydrating, NOT empty. (2) `await material.pbr.baseColor.set([r,g,b,a])` THROWS on a bad value — without `await` the throw is swallowed and the old value silently stays. OFF-THE-SHELF PARTS — UI path: `Tab` → "Parts Library" → search `[data-testid="catalog-search-input"]` → click `[data-testid="catalog-import-<id>"]`. Or use workflow (A) above from script. API DOCS — `/docs/scripting/api/<moduleId>/<method>` (e.g. `/docs/scripting/api/Mesh/boolean`). Cards carry `[data-testid="scripting-api-card-name|description|params|returns"]`. VERSION POLL — `/llms-version.json` for current bootstrap version + recentChanges list. Intent triage (pick a kernel FIRST): ASK FIRST, BUILD SECOND. Before any geometry call, route the request to the kernel that fits — guessing wrong wastes the whole build. Does the result need PARAMETRIC / CAD geometry — revolve/sweep/loft/hull/minkowski, threads, or parameter-driven shapes? → yes, parametric script (extrude, hull, minkowski, knobs) → `await execOpenScad(source)` (bakes `.scad` to a mesh). Best for parameter-driven shapes an OpenSCAD user already knows. BOSL2 ships with AnimBox and is already on the include path — lean on its purpose-built modules rather than approximating hardware from raw primitives. Start every BOSL2 script with `include <BOSL2/std.scad>`. Fastener work: `include <BOSL2/screws.scad>` gives `screw("M8")` and `threaded_nut()`; `include <BOSL2/threading.scad>` adds `threaded_rod()` for custom thread forms. Curved and blended builds: `include <BOSL2/rounding.scad>` (`round_corners()`, `offset_sweep()`) plus `include <BOSL2/skin.scad>` (`skin()`, `path_sweep()`) with `<BOSL2/beziers.scad>` supplying the curve inputs. Keep `$fn` around 32 while you iterate — bakes stay snappy — and bump it to 128+ only for the final bake. → no → AnimBox Geo Utils — the result is EDITABLE / ORGANIC / a game asset (sculpts, characters, props you keep editing as quads): use `create.*` primitives + `mesh.boolean(other, 'union'|'difference'|'intersection')` + `xform({ t, r, s })`. This is the default path; the output stays editable as quads (execOpenScad / SCAD bakes to a STATIC, TRIANGLE-only mesh). AUTO - BEST TOOL — when no single path fits, let the agent pick per part, or combine them: SCAD for the frame/engine, AnimBox Geo Utils for the tank/seat. SOFT preference (NOT a default): for mechanical / printable parts, prefer SCAD over composing `create.gear` / `create.threadedScrew` equivalents from raw primitives. When the SCAD-vs-Geo-Utils choice is MATERIAL (printable / parametric / mechanical) and you cannot confidently route, ASK ONE QUESTION — never silently pick. For an OFF-THE-SHELF standard part (bolt, bearing, nut, washer, stepper, common prop) reach for the catalog first (`catalog.search`); to IMPORT and tweak an existing file use `io.*`. The OpenSCAD kernel is Model-editor-only — `await Utils.editor.switchTo("model")` first if `Utils.editor.current()` is not `'model'`. VISUAL-VERIFY CADENCE — after EVERY geometry op, `await viewport.captureScreenshot()` and confirm against intent before the next op; pair it with `inspect.measure(a, b)` for signed-distance numbers. Numbers can be right while the picture is wrong. WHEN AMBIGUOUS, ASK ONE QUESTION before building: "Do you want a SCAD part (parameter-driven dimensions via OpenSCAD, baked to a triangle-only static mesh) or an AnimBox Geo Utils mesh (editable quads) you can keep sculpting?"