Claude Code · Blender 5.2 · MCP for Blender · USDZ
ABENE VHF-680 Build Log
From one product photo and a two-page brochure to a textured, animation-ready USDZ of a CNC milling machine, in five prompts. Each step below shows the prompt as typed, what Claude did in response, and the renders it produced.
Input.abene_org.png, the reference photo in the project folder.Output. The procedural Blender model, Cycles render. The same model is exported as ABENE_VHF-680.usdz.
Prompts
5
Meshes
129
PBR materials
27
Textures
21
Triangles
~130 k
USDZ
11.7 MB
Units / up
m / Y
How the pieces connect
Claude Code writes Python that builds the model, sends it to Blender through the MCP for Blender addon, renders, compares the render with the photo and repeats. Export runs through Blender's USD exporter, then a pxr post-process.
flowchart LR
A["abene_org.png + brochure PDF"] --> B["Claude Code"]
B -- "writes" --> C["make_textures.py vhf680_model.py"]
C -- "execute_code over MCP addon socket :9876" --> D["Blender 5.2"]
D -- "Cycles renders" --> E["Compare with photo"]
E -- "fix and rerun" --> C
D -- "export_usdz.py" --> F["USD export UsdPreviewSurface"]
F --> G["pxr post-process glass opacity, checks"]
G --> H["ABENE_VHF-680.usdz"]
1
Connect Blender and build a first model
Prompti'd like to use blender to model the cnc milling machine depicted in this directory, use the mcp server for blender from this repo https://github.com/ahujasid/mcp-for-blender
What Claude did
Read the directory: the product photo and the two-page brochure, rendered to images with Ghostscript. From the spec table: angle table 900 × 500 mm with 7 T-slots 14 H7, travels X 800 / Y 510 / Z 475 mm, head swivel 0–140°, about 2.2 t.
Cloned the repo and read its README and installer. Found Blender 4.2, 4.5 and 5.2 installed and used 5.2.
Installed the addon with uvx mcp-for-blender install-addon, enabled it in a headless Blender run, and registered the server with claude mcp add blender -- uvx mcp-for-blender (local scope).
MCP tools load when a Claude Code session starts, so Claude used a small socket client to send the addon's execute_code command, the same call the MCP server makes.
Wrote vhf680_model.py, a parametric script of boxes, cylinders and curves (253 objects). One EEVEE render, then one pass to fix exposure and framing.
Version 1. Right layout and parts, simple shapes, flat colours.Reference. Same machine, for comparison.
2
Export to USDZ
Promptexport this to usdz in this directory
What Claude did
Checked the options of Blender's USD exporter in this build, then converted curve and text objects to meshes, because most USDZ viewers (AR Quick Look among them) do not draw curves.
Exported only the machine collection, without floor, lights or camera, Y-up and in metres.
Opened the file with usd-core to verify it: 240 meshes, 19 materials, every mesh bound to a material, size about 3.0 × 2.5 × 2.2 m.
Rebuilt the scene afterwards so the .blend stayed unchanged.
3
Rebuild for accuracy with PBR materials
Prompttry again, try to be more accurate, also use pbr materials, we want to use it in a high end visualization
Follow-up, while Claude was studying the brochure photosuse the png in the directory
Reading the photo
Claude stopped using the brochure photos, which show a different variant, and made 4× enlarged crops of abene_org.png: head, left tower, right tower, pendant, lower front and table.
Details it took from the crops: windows you can see through, a recessed grey band above white kick panels, a light grey table apron over a stainless chip chute, ribbed way covers, a two-axis rotary table, a white head with a black motor and a 3-spoke feed lever, a grey gearbox with an oval badge, a looped blue coolant hose and an e-stop, an aluminium lamp arm, and a pendant with sloped keyboard, button strip, deep monitor housing, handheld handwheel and coiled cables.
Crop: head. Gearbox, badge, coolant loop, lamp arm.Version 2: head. Modelled from that crop.
PBR textures
make_textures.py builds seamless maps from FFT-filtered noise: base colour, roughness and normal for powder coat with orange peel (white, light grey, grey), textured black coat, brushed stainless, ground cast iron and brushed aluminium. UVs are generated in metres divided by each material's tile size, so texture scale is physically consistent.
The same script draws the decals: an iTNC 530 style control screen (used as emission), the TE 530 keyboard with a key layout file so each modelled key cap shows its legend, and the ABENE badge with metallic and roughness masks.
Paint · base colourPaint · normalStainless · colour (contrast up)Stainless · roughnessCast iron · colourBlack coat · normal
Screen (emission)Keyboard legendsBadge
Model version 2
A small builder merges each part's pieces into one mesh, generates UVs, and adds bevels with hardened normals. That gives 129 meshes instead of 253 loose objects.
Real construction instead of blocks: sheet-metal doors with window cut-outs and 6 mm polycarbonate panes, a T-slot table extruded from its cross-section, ribbed covers, a corrugated cable hose built with geometric ribs, and coiled cables built along a smooth centre path.
Parts are grouped by how they move, so they can be animated: Axis_Z → Axis_Y → Axis_X → Fixture → Axis_A → Axis_C, plus Spindle, Feed_Lever, the lamp joints, Pendant, Pendant_Monitor and HR.
Render-and-compare loop on the GPU with Cycles. Fixes from that loop: exposure, blotchy stainless and table textures, a stray black line under the towers, a thicker pendant post, and the coolant hose path.
Lower front. Chamfered tower base, chip chute, stainless rail with screws, casters and levelling feet.USDZ round trip. The exported file loaded into a clean Blender and rendered: geometry, textures, screen and glass come through.
Export pipeline
export_usdz.py exports a USDC with textures using standard USD preview materials, then post-processes it with pxr. Those materials have no transmission setting, so the glass gets opacity 0.12 and IOR 1.585, and the lamp lens is handled the same way. Finally it packages the result as USDZ.
Checks: every mesh has a material and UVs, colour textures are tagged sRGB, roughness, metallic and normal maps are tagged as raw data, Y-up, metres.
4
Correct the monitor
Promptif you watch the monitor and compare, the screen is larger
What Claude did
Measured against the pendant crop: the screen fills about 80 % of the bezel width and 75 % of its height.
Enlarged the LCD from 0.37 × 0.275 m to 0.455 × 0.34 m (a 15" 4:3 panel), moved the softkey row under the screen and the softkey column into the narrow strip on the right.
The Blender window had been closed in the meantime, so Claude reopened the saved file, rebuilt, re-rendered and re-exported the USDZ.
Reference crop. Screen nearly fills the bezel.After the fix. Larger screen, softkeys repositioned, legends on the key caps.
5
Document the process
Promptwe want to show how this was done - create an artifact which describes the steps with the prompts and the results
This page. The images are the renders and textures produced in the session, compressed for the web.
What's in the project folder
File
What it is
ABENE_VHF-680.usdz
The exported model: 129 meshes, 27 PBR materials, 21 textures, Y-up, metres, with groups for each moving axis.
ABENE_VHF-680.blend
Blender scene with the model, studio lights and camera.
vhf680_model.py
Builds the whole model. Re-running it replaces the model, and the main dimensions are constants at the top.
make_textures.py
Generates the texture maps and decals into textures/.
export_usdz.py
Runs the USD export, glass fix, checks and USDZ packaging.
renders/
Overview, head, pendant and lower-front renders.
Known limits
The overall enclosure size (about 2.1 × 1.58 × 2.05 m) is estimated from the photo. The table size and axis travels come from the brochure.
Glass in the USDZ uses opacity, not refraction, because USD preview materials have no transmission setting. Engines such as Omniverse RTX may want their own glass material.
Apple's ARKit compliance checker was not available in the installed usd-core, so it was not run. The round-trip import was used instead.
No subdivision surfaces. Bevels hold up at normal viewing distances but not in extreme close-ups.