cad
Creates and edits parametric CAD parts, assemblies and 2D profiles as Python build123d models that text-to-cad's server builds…
Renders photoreal images and videos of a text-to-cad model, a STEP or an xbf with Blender, for people to look at, such as a hero shot, a README picture, a product post, a turntable or a film of a model's motion or animation. Exports a GLB, loads it with cad.blender, lights and
Claude Code
$ npx -y skills add earthtojake/text-to-cad --skill render --agent claude-code
Codex
$ npx skills add earthtojake/text-to-cad --skill render -a codex -y
Cursor
$ npx skills add earthtojake/text-to-cad --skill render -a cursor -y
Gemini CLI
$ npx skills add earthtojake/text-to-cad --skill render -a gemini-cli -y
GitHub Copilot
$ npx skills add earthtojake/text-to-cad --skill render -a github-copilot -y
OpenCode
$ npx skills add earthtojake/text-to-cad --skill render -a opencode -y
Windsurf
$ npx skills add earthtojake/text-to-cad --skill render -a windsurf -y
name: render description: Renders photoreal images and videos of a text-to-cad model, a STEP or an xbf with Blender, for people to look at, such as a hero shot, a README picture, a product post, a turntable or a film of a model's motion or animation. Exports a GLB, loads it with cad.blender, lights and frames it in a bpy script that `cad run` runs, drafts in EEVEE and finishes in Cycles on the GPU, and can save a .blend. Not for checking geometry, which a snapshot does. license: MIT metadata: repository: earthtojake/text-to-cad
A render is a picture for a person: a hero image, a README picture, a post, a turntable, a film of a mechanism. The model goes to Blender as a GLB, loaded by `cad.blender.load`; the scene (camera, lights, world, engine, output) is an ordinary Python script that imports `bpy`, Blender as a Python module, and `cad run` runs it. Judge geometry with `cad model snapshot`, never with a render: a render's lens, light and depth of field make it a poor measure, so never read a dimension off one.
| Task | Start with | Reference | | --- | --- | --- | | **A still of a model** | Export a GLB, write a `render.py` that loads it, `cad run render.py`. | [The script](#the-script), [scene script](references/scene-script.md) | | **Draft, then a final** | An EEVEE draft at 1080p, looked at, before Cycles. | [Draft then final](references/shots.md#draft-then-final) | | **A pose of a motion or a frame of an animation** | `model.play(name)` and the frame. | [Clips](#load-the-glb) | | **A turntable** | The camera on an empty that turns once. | [Turntables](references/shots.md#turntables) | | **A film of a motion or an animation** | `model.play(name)`, then an mp4. | [Films](references/shots.md#films) | | **Motion blur, depth of field, a glow** | The scene's and the camera's settings; a keyed emission. | [Shots](references/shots.md) | | **Choose looks** | `cad.build123d.materials` in the model. | [Looks](#looks) | | **Give the person a .blend** | `bpy.ops.wm.save_as_mainfile` at the end of the script. | [A .blend](references/shots.md#a-blend-for-a-person) | | **Use the GPU** | Cycles' device, chosen in the script. | [Engines](references/scene-script.md#engines-and-the-gpu) |
Run the `cad` command (`~/.local/bin/cad` where it is not on your PATH; `cad.exe` on Windows). If it is missing, install text-to-cad, outside a sandbox or with its permission:
curl -fsSL https://texttocad.dev/install.sh | sh
On Windows, in PowerShell: `irm https://www.texttocad.dev/install.ps1 | iex`. If the CAD app was only just added, its server may still be starting: try again for up to a minute first. `cad doctor --check` explains any other failure, changing nothing; `cad doctor` repairs what it reports. Tell the person any next step `cad setup` prints.
`cad run render.py` sees `import bpy` and gives the script cad's blender integration: an environment on Python 3.13, the one Blender is built for, holding bpy 5.2.3 (Blender 5.2 LTS) beside cad, made the first time and kept. The script imports what it likes of cad and build123d beside bpy, so one script can build a model, export it and render it. Blender's own preferences, add-ons and extensions folders are cad's, never the person's, so their Blender settings never load into a run; every `cad run` shares them, so an extension or a preference one script installs or saves is there for the next, and a script that needs one sets it up itself. bpy has no build for Intel Macs or Linux on ARM, where `cad run` refuses such a script by name. A `--python` or a header's `requires-python` that leaves 3.13 out is refused the same way; one that admits it (`--python 3.13`) runs on the same environment as none. Nothing here starts the Blender app.
cad model export "$ID" scene.glb --tolerance 0.02 --angle 5
`ID` is the model's id (running its script prints it); a STEP or an xbf exports the same way (`cad step export part.step scene.glb --tolerance 0.02 --angle 5`). The GLB is in metres, Z up once imported, with the assembly's tree as nested empties, a PBR material per look, and each motion and `animation()` as a clip. The viewer's mesh shows its facets in a path tracer or a close camera: `--tolerance` (mm, absolute) and `--angle` (degrees, 1 to 28.5) mesh this file finer, for it alone. The cost is triangles and seconds: a tenth of the tolerance is about three times the segments round a curve and ten times the triangles of a doubly curved face. Start at 0.02 mm and 5 degrees for a close-up of a hand-sized part and coarser for a large assembly seen whole, and export finer when a draft shows facets. Say the file's size when it is large. Export again after every model change: the GLB is a copy.
# render.py: cad run render.py
import math
from pathlib import Path
import bpy
from mathutils import Vector
from cad.blender import load
HERE = Path(__file__).resolve().parent
bpy.ops.wm.read_factory_settings(use_empty=True) # no person's startup file, no default cube
scene = bpy.context.scene
model = load(HERE / "scene.glb") # every part where cad placed it
scene.render.resolution_x, scene.render.resolution_y = 1920, 1080
aim = bpy.data.objects.new("aim", None)
aim.location = model.center
camera = bpy.data.objects.new("camera", bpy.data.cameras.new("camera"))
camera.data.lens = 85
view = math.tan(camera.data.angle / 2) * min(1, scene.render.resolution_y / scene.render.resolution_x)
distance = model.size.length / 2 / view * 1.1 # the whole box in the frame's shorter side
camera.location = model.center + distance * Vector((1, -1, 0.6)).normalized()
camera.constraints.new("TRACK_TO").target = aim
sun = bpy.data.objects.new("sun", bpy.data.lights.new("sun", "SUN"))
sun.data.energy, sun.rotation_euler = 3.0, (0.8, 0.2, 0.6)
for item in (aim, camera, sun):
scene.collection.objects.link(item)
scene.camera = camera
scene.world = bpy.data.worlds.new("Creates and edits parametric CAD parts, assemblies and 2D profiles as Python build123d models that text-to-cad's server builds…
Make an engineering drawing of a part as a PDF - orthographic views with hidden lines and centre marks, real dimensions, hole…
Checks whether a part or an assembly of bonded parts holds under its loads, as a linear static stress study of a STEP, an xbf or…
Create, edit, lay out and review native KiCad circuit boards (.kicad_pcb) and their schematics (.kicad_sch) - parts and nets,…
Prints a part - slices an `.stl`, `.3mf` or `.obj` into printer-ready G-code with OrcaSlicer, headless or in the app, with…
Robot and world descriptions (URDF, SRDF, MJCF) for ROS, MoveIt and MuJoCo. Use to generate a robot description or a MuJoCo scene…
Design banners for social media, ads, website heroes, creative assets, and print. Multiple art direction options with optional…
Use to design, redesign, critique, audit, polish or animate a frontend: websites, landing pages, dashboards, app UI, components,…
Hyperframes-based video template for retro pixel deck motion design. Use when users want a high-fidelity, multi-scene…
Create branded architecture, architecture delta, IT current-state, flowchart, sequence, state machine, ER/data model, timeline,…