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.

Product photo of the ABENE VHF-680 CNC milling machine with its control pendant
Input. abene_org.png, the reference photo in the project folder.
Cycles render of the procedural Blender model of the VHF-680
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.
First version of the model: simple blocks, flat materials
Version 1. Right layout and parts, simple shapes, flat colours.
Reference photo for comparison
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.
Enlarged crop of the head area of the reference photo
Crop: head. Gearbox, badge, coolant loop, lamp arm.
Render of the rebuilt head area
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.
White powder coat base colour
Paint · base colour
Orange peel normal map
Paint · normal
Brushed stainless base colour, contrast boosted
Stainless · colour (contrast up)
Brushed stainless roughness, contrast boosted
Stainless · roughness
Ground cast iron base colour
Cast iron · colour
Textured black coat normal map
Black coat · normal
Control screen texture
Screen (emission)
Keyboard legend texture
Keyboard legends
ABENE badge texture
Badge

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.
Render of the lower front: chip chute, stainless rail, casters
Lower front. Chamfered tower base, chip chute, stainless rail with screws, casters and levelling feet.
The exported USDZ imported into a clean Blender and rendered
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.
Enlarged crop of the control pendant in the reference photo
Reference crop. Screen nearly fills the bezel.
Render of the corrected pendant with the larger screen
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

FileWhat it is
ABENE_VHF-680.usdzThe exported model: 129 meshes, 27 PBR materials, 21 textures, Y-up, metres, with groups for each moving axis.
ABENE_VHF-680.blendBlender scene with the model, studio lights and camera.
vhf680_model.pyBuilds the whole model. Re-running it replaces the model, and the main dimensions are constants at the top.
make_textures.pyGenerates the texture maps and decals into textures/.
export_usdz.pyRuns the USD export, glass fix, checks and USDZ packaging.
renders/Overview, head, pendant and lower-front renders.

Known limits