← Test Lab — Gemini — 2026-05-15T12:44

Roof Support Ledger

v1 Gemini approved

Create a continuous rectangular timber ledger (ring beam), outer dimensions 2800x1800x45mm, with a hollow center (inner cutout 2710x1710x45mm, creating a 45mm cross-section). Fastens to SIP interior walls to provide face bearing support for the flat roof.

Dependencies

west_wall_assembly.ledger_mount north_wall_assembly.ledger_mount east_wall_assembly.ledger_mount

Interfaces Provided

roof_bearing (face)
◉
Agent initialized (status: waiting_for_dependencies, action: check_dependencies)
◉
Provider: google | Profile: quality
◇
Received interface west_wall_assembly.ledger_mount: %{name: "ledger_mount", type: "face", value: %{}, agent_id: "west_wall_assembly"}
◇
Received interface west_wall_assembly.back_spline: %{name: "back_spline", type: "spline", value: %{}, agent_id: "west_wall_assembly"}
◇
Received interface north_wall_assembly.ledger_mount: %{name: "ledger_mount", type: "face", value: %{}, agent_id: "north_wall_assembly"}
◇
Received interface north_wall_assembly.side_spline_right: %{name: "side_spline_right", type: "spline", value: %{}, agent_id: "north_wall_assembly"}
◇
Received interface east_wall_assembly.ledger_mount: %{name: "ledger_mount", type: "face", value: %{}, agent_id: "east_wall_assembly"}
◉
All dependencies resolved, starting generation
◉
Generating v1
○
Calling Gemini API for code generation (gemini-3.1-pro-preview)...
◉
Generation token budget: max_tokens=12288, thinking_budget=0 (retry_count=0)
●
Received response (635 tokens)
◆
roof_ledger_v1.py · 51 lines
import FreeCAD
import Part
from FreeCAD import Vector, Placement, Rotation

# Force load PartDesign module before any PartDesign:: calls
FreeCAD.loadModule("PartDesign")
import PartDesign

# === PARAMETRIC CONSTANTS ===
OUTER_LENGTH = 2800.0  # mm
OUTER_WIDTH = 1800.0   # mm
HEIGHT = 45.0          # mm

INNER_LENGTH = 2710.0  # mm
INNER_WIDTH = 1710.0   # mm

# === DOCUMENT & BODY ===
doc = FreeCAD.ActiveDocument or FreeCAD.newDocument("RoofSupportLedger")
body = doc.addObject("PartDesign::Body", "Body")

# === SKETCHES & FEATURES ===

# 1. Outer Frame (Base Shape)
outer_box = doc.addObject("PartDesign::AdditiveBox", "OuterShell")
outer_box.Length = OUTER_LENGTH
outer_box.Width = OUTER_WIDTH
outer_box.Height = HEIGHT
# Placed at origin to satisfy local coordinate rules (Left/back edge at X=0, Y=0, Base at Z=0)
outer_box.Placement = Placement(Vector(0, 0, 0), Rotation())
body.addObject(outer_box)
doc.recompute()

# 2. Inner Cutout (Hollow Center)
inner_cutout = doc.addObject("PartDesign::SubtractiveBox", "InnerCutout")
inner_cutout.Length = INNER_LENGTH
inner_cutout.Width = INNER_WIDTH
inner_cutout.Height = HEIGHT + 2.0  # Slightly taller to ensure a clean through-cut

# Calculate offsets to center the cutout (creates the 45mm uniform cross-section)
cutout_x = (OUTER_LENGTH - INNER_LENGTH) / 2.0
cutout_y = (OUTER_WIDTH - INNER_WIDTH) / 2.0
cutout_z = -1.0  # Start slightly below base to avoid zero-thickness faces

inner_cutout.Placement = Placement(Vector(cutout_x, cutout_y, cutout_z), Rotation())
body.addObject(inner_cutout)
doc.recompute()

# === FINAL ===
doc.recompute()
if FreeCAD.GuiUp:
    FreeCAD.Gui.ActiveDocument.ActiveView.fitAll()
●
Executing in FreeCAD...
◉
StepAnalyzer failed: FreeCAD could not read STEP file: FreeCAD exception thrown (File to load not existing or not readable) — skipping
●
FreeCAD execution succeeded
●
Exported: model.stl
◉
Generation succeeded and component was auto-approved (v1)
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
v0.0.985