Mac Studio

1:1 procedural model · Blender bpy · dimensionally verified

Launch the interactive 3D viewer →

Mac Studio model, three-quarter hero view
Orbit it, slice it, and change the material live in the interactive viewer.

Verified dimensions

Measured from the evaluated mesh with every modifier applied, against Apple's published tech specs. Not eyeballed — the build script prints these numbers and exits non-zero if any axis drifts past 0.5 mm.

AxisOfficialModelΔ
Width (X)19.70 cm 7.7 in19.7000 cm+0.000 mm
Depth (Y)19.70 cm 7.7 in19.7000 cm+0.000 mm
Height (Z)9.50 cm 3.7 in9.5000 cm+0.000 mm

Height is the full 3.7 in including the rubber feet: the shell is 9.30 cm and the feet add 0.20 cm. Source: apple.com/mac-studio/specs, “Size and Weight” section.

Rendered views

Front elevation
Front
Side profile
Side
Rear
Rear
Top-down
Top
Underside with feet and power button
Underside
Three-quarter hero
Hero
Front panel close-up
Front panel
Rear connector bay close-up
Connector bay
Rear perforated field, straight on
Rear field
Perforation lattice, macro
Perforation macro
Rear at eye level
Rear, eye level
Rear port row close-up
Rear ports

Cycles, 1500×1125, 128 samples, four-light studio setup with a gradient environment and bounce cards. Perforations are on the rear panel only — the front, both sides and the underside are plain aluminium.

What the model contains

Matched against Apple's own product photography, not from memory.

Enclosure

Anodised silver aluminium, 1.05 cm vertical corner radius, 0.48 cm top/bottom edge break, corners tessellated at 20 segments so the arc reads machined rather than faceted. Single-piece block — the top is one continuous surface, not a lid in a tray.

Front

Smooth and uninterrupted above the base band. Two vertical USB-C ports and a horizontal SDXC slot low on the left, a 3.5 mm jack low on the right. Positions are measured off Apple's own front hardware diagram: 16.5%, 24.0%, 37.7% and 83.5% of the panel width. There is no front status light — Touch ID is on the underside. Every opening is a real boolean recess with a socket built wall-by-wall: bright metal walls, shadowed back plate, contact tongue.

Rear

A shallow 0.18 cm connector bay in solid aluminium, holding left to right: 4× USB-C (10 Gbps), 10Gb Ethernet (RJ-45), power inlet, 2× Thunderbolt 5, HDMI, 3.5 mm headphone jack and the Touch ID button. Above and below the bay are two perforated fields.

Ventilation

Three separate fields on the rear panel, each real geometry — one quad ring per hole, no texture. Measured against Apple's rear diagram, from the top of the 9.5 cm height: a perforated field 5–55%, the solid port band 55–70%, a second field 70–80%, a solid transition 80–90%, and the base band 90–100%. The hole lattice is square at a 2 mm pitch with a 1.42 mm radius, which opens 39.6% of the surface.

Every field is confined to the back. The front panel, both side panels and the underside are plain aluminium from edge to edge — the field mask is keyed on each point's position on the outline, and both the recess in the body loft and the hole placement call it, so they cannot drift apart and leave the holes buried in solid metal.

Underside

Four rubber feet and the Touch ID power button, on an otherwise plain aluminium plate.

Every dimension, port position and ventilation boundary here is measured from Apple's own hardware diagrams, not estimated. The blender/ortho_compare.py and tools/face_diff.py pair renders the six faces orthographically and diffs them against those diagrams band by band; the worst zone deviation on the rear is 5.2 of 100 points.

Reproducing

# geometry + .blend + bbox report
blender --background --python blender/build_mac_studio.py

# 12 views (arg 1 = output dir, arg 2 = samples)
blender --background --python blender/render_views.py -- renders 128

# dimension check -> VERIFY_OK / VERIFY_FAIL
blender --background --python blender/verify.py

# port layout, bay material, front positions -> PORTS_OK / PORTS_FAIL
blender --background --python blender/verify_ports.py

# six dead-on orthographic faces, for pixel-diffing
blender --background --python blender/ortho_compare.py

# diff a face against Apple's diagram -> per-zone and per-band deltas
python3 tools/face_diff.py renders/ortho/rear.png reference/hk/hw_back.jpg rear

Camera distance is derived from the model's bounding sphere and the lens FOV, so re-framing survives geometry edits — no hand-tuned distance constants. The orthographic pass exists because the perspective rig's auto-framing reported this machine at h/w 0.75 instead of 0.48, which invalidated every band measurement taken from it.

Blender gotchas hit while building this

Each one produced a plausible-looking wrong result rather than an error.

  1. Non-planar n-gon caps break the EXACT boolean solver. The lofted shell's top and bottom caps are large non-planar n-gons. Booleans against them “succeed” but silently merge the cutter's outer half into the shell, so the bounding box grows by the cutter's overhang. Triangulating the body first fixes it. Guard on polygon vertex counts — data.loop_triangles is a lazily-filled cache and is not a valid “already triangulated” test.
  2. A cutter must straddle the skin. Outer face proud of the surface (discarded), inner face reaching the desired depth. A cutter that does not clearly cross the surface does not produce a recess.
  3. Keep the cutter's bevel small relative to its depth. A 0.16 cm bevel on a 0.60 cm cutter rounds away the part overlapping the skin and reproduces the absorption above.
  4. Make the extrusion direction an explicit parameter. A helper that hard-codes “body extends toward −Y” builds front-panel detail outside the enclosure and inflates the bbox by the part's depth.
  5. Auto-smooth needs edge subdivision. A flat panel lofted as one huge quad shades with visible banding.
  6. Blender 4.x renamed the smooth-shading APIs — shade_auto_smooth (4.2+) / shade_smooth_by_angle (4.1); mesh.use_auto_smooth is gone.
  7. BSDF sockets were renamed in 4.x — Clearcoat→Coat Weight, Transmission→Transmission Weight.
  8. A bevel wider than half the shortest side self-intersects.
  9. At roughness 0.19 the shell is a mirror. Bare area lights give it nothing to reflect, so a gradient world and bounce cards are load-bearing, not decoration.
  10. Exclude studio furniture from bbox measurement or a 40 cm bounce card swamps a 19.7 cm product.
  11. A boolean difference keeps the shell's material on the new faces. The cutter's own material is not carried over unless the target lacks that slot, so a recess comes out shaded in the shell's aluminium instead of the cavity black you assigned. Either add the slot to the body first or repaint the region by volume afterwards.
  12. Row and column pitch must be the same number. Laying out rows evenly across a band and calling it a day drifts the row pitch away from the column pitch; the field then measures 40%, 27%, 40%, 27% in consecutive bands purely from where each band falls against the lattice. A pixel diff is what surfaced it — the render looked fine.
  13. glTF names meshes from the data block, not the object. Every part here is a Cube.001 or Cylinder.004, so the viewer's /Grille/ and /^Port_/ categorisation matched nothing and the per-part toggles did nothing. Copy the object name onto the mesh data before export.
  14. Key a face mask on geometry, not on a single axis or a bare arc length On a rounded square the rear panel and each side panel span the same range of the other axis, so a py-keyed mask lights up the sides and leaves the back bare. Arc length does separate them, but only if the arc is rescaled from the inset profile the holes are laid along onto the reference outline — and half a centimetre of error slides the field onto the side panels. Asking "is this point on the rear panel?" directly, from px/py and the corner radius, is the version that has not moved in three attempts.
  15. Test a face with a ray grid, and test it from the flat A perforation field can be present in the scene and still be invisible. The tubes are cut to the field's full depth; if the shell's recess is shallower the tubes sit inside solid metal, and only a ray fired at the surface tells you so — the objects are all there and the bounding box is correct. A ray grid over one face also grazes the corner arc and reports hits belonging to the neighbouring panel, so check the hit positions, not just the count.

Known deviations