← Small Garden House

Exterior Left Wall

v1 Claude approved

Create the exterior left wall, 400mm length x 4200mm width x 1700mm height, SIP panel. It forms a butt joint at both ends with the front and back walls. Cut two 400x1000x1400mm window openings completely through the 400mm thickness.

Dependencies

floor_panel.top_surface front_wall.inner_face back_wall.inner_face

Interfaces Provided

top_surface (face_contact) window_openings (clearance)
◉
Agent initialized (status: waiting_for_dependencies, action: check_dependencies)
◉
Provider: google | Profile: balanced
◉
Provider updated to google / balanced
◇
Received interface floor_panel.top_surface: %{name: "top_surface", type: "face_contact", value: %{}, agent_id: "floor_panel"}
◉
Provider updated to google / balanced
◇
Received interface front_wall.inner_face: %{name: "inner_face", type: "butt_joint", value: %{}, agent_id: "front_wall"}
◇
Received interface front_wall.top_surface: %{name: "top_surface", type: "face_contact", value: %{}, agent_id: "front_wall"}
◇
Received interface front_wall.window_openings: %{name: "window_openings", type: "clearance", value: %{}, agent_id: "front_wall"}
◉
Provider updated to google / balanced
◉
Provider updated to google / balanced
◇
Received interface back_wall.inner_face: %{name: "inner_face", type: "butt_joint", value: %{}, agent_id: "back_wall"}
◉
All dependencies resolved, starting generation
◉
Generating v1
◇
Received interface back_wall.top_surface: %{name: "top_surface", type: "face_contact", value: %{}, agent_id: "back_wall"}
○
Calling Gemini API for code generation (gemini-3.1-pro-preview)...
◉
Generation token budget: max_tokens=12288, thinking_budget=0 (retry_count=0)
◇
Received interface back_wall.window_openings: %{name: "window_openings", type: "clearance", value: %{}, agent_id: "back_wall"}
◉
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
●
Received response (1874 tokens)
◆
left_wall_v1.py · 134 lines
import FreeCAD
import Part
import math
from FreeCAD import Vector

# === PARAMETERS ===
WALL_LENGTH     = 4200
WALL_HEIGHT     = 1700
TOTAL_THICKNESS = 400
FACE_THICKNESS  = 11
CORE_THICKNESS  = TOTAL_THICKNESS - 2 * FACE_THICKNESS  # 378mm

BOTTOM_PLATE_H  = 45
TOP_PLATE_H     = 90
PANEL_HEIGHT    = WALL_HEIGHT - BOTTOM_PLATE_H - TOP_PLATE_H  # 1565mm

SPLINE_W        = 45
SPLINE_D        = 140  # Standard heavy-duty block spline depth

FRAME_W         = 1000
FRAME_H         = 1400

KING_W          = 45
KING_D          = TOTAL_THICKNESS
TRIMMER_W       = 45
TRIMMER_D       = TOTAL_THICKNESS
SILL_H          = 45

CLEAR_W         = FRAME_W
CLEAR_H         = FRAME_H
RO_W            = CLEAR_W + 2 * TRIMMER_W
HEADER_SPAN     = RO_W + 2 * KING_W
FRAME_ZONE_W    = HEADER_SPAN  # 1180mm

# Ensure vertical framing fits exactly within the 1565mm panel height:
# Bottom plate (45) + Sill (45) + Clear void (1400) + Header (120) = 1610mm (base of top plate)
CLEAR_BASE_Z    = BOTTOM_PLATE_H + SILL_H  # 90mm from slab
TRIMMER_H       = SILL_H + CLEAR_H         # 1445mm
HEADER_BASE_Z   = BOTTOM_PLATE_H + TRIMMER_H # 1490mm
HEADER_DEPTH    = PANEL_HEIGHT - TRIMMER_H   # 120mm

# Layout: Two windows spaced symmetrically
OPENING1_X      = 600
OPENING2_X      = 2420

doc = FreeCAD.ActiveDocument or FreeCAD.newDocument("ExteriorLeftWall")
parts = []

# === 1. Bottom plate ===
bp = Part.makeBox(WALL_LENGTH, TOTAL_THICKNESS, BOTTOM_PLATE_H, Vector(0, 0, 0))
parts.append(bp)

# === 2. SIP panel zones ===
def make_panel_zone(x_start, zone_length):
    zone_parts = []
    if zone_length <= 0:
        return zone_parts
    x = x_start
    full = int(zone_length) // 1200
    rem  = int(zone_length) % 1200
    widths = [1200] * full + ([rem] if rem > 0 else [])
    for i, pw in enumerate(widths):
        f1 = Part.makeBox(pw, FACE_THICKNESS, PANEL_HEIGHT, Vector(x, 0, BOTTOM_PLATE_H))
        co = Part.makeBox(pw, CORE_THICKNESS, PANEL_HEIGHT, Vector(x, FACE_THICKNESS, BOTTOM_PLATE_H))
        f2 = Part.makeBox(pw, FACE_THICKNESS, PANEL_HEIGHT, Vector(x, FACE_THICKNESS + CORE_THICKNESS, BOTTOM_PLATE_H))
        zone_parts.extend([f1, co, f2])
        x += pw
        if i < len(widths) - 1:
            sp = Part.makeBox(SPLINE_W, SPLINE_D, PANEL_HEIGHT,
                              Vector(x - SPLINE_W / 2, (TOTAL_THICKNESS - SPLINE_D) / 2, BOTTOM_PLATE_H))
            zone_parts.append(sp)
    return zone_parts

parts.extend(make_panel_zone(0, OPENING1_X))
parts.extend(make_panel_zone(OPENING1_X + FRAME_ZONE_W, OPENING2_X - (OPENING1_X + FRAME_ZONE_W)))
parts.extend(make_panel_zone(OPENING2_X + FRAME_ZONE_W, WALL_LENGTH - (OPENING2_X + FRAME_ZONE_W)))

# === 3. Timber buck framing for openings ===
for ox in [OPENING1_X, OPENING2_X]:
    # King studs
    king_left  = Part.makeBox(KING_W, KING_D, PANEL_HEIGHT, Vector(ox, 0, BOTTOM_PLATE_H))
    king_right = Part.makeBox(KING_W, KING_D, PANEL_HEIGHT, Vector(ox + FRAME_ZONE_W - KING_W, 0, BOTTOM_PLATE_H))
    
    # Trimmer studs
    trimmer_left  = Part.makeBox(TRIMMER_W, TRIMMER_D, TRIMMER_H, Vector(ox + KING_W, 0, BOTTOM_PLATE_H))
    trimmer_right = Part.makeBox(TRIMMER_W, TRIMMER_D, TRIMMER_H, Vector(ox + FRAME_ZONE_W - KING_W - TRIMMER_W, 0, BOTTOM_PLATE_H))
    
    # LVL header
    header = Part.makeBox(HEADER_SPAN, TOTAL_THICKNESS, HEADER_DEPTH, Vector(ox, 0, HEADER_BASE_Z))
    
    # Window sill
    sill = Part.makeBox(CLEAR_W, TOTAL_THICKNESS, SILL_H, Vector(ox + KING_W + TRIMMER_W, 0, BOTTOM_PLATE_H))
    
    parts.extend([king_left, king_right, trimmer_left, trimmer_right, header, sill])

# === 4. Top plate ===
tp = Part.makeBox(WALL_LENGTH, TOTAL_THICKNESS, TOP_PLATE_H, Vector(0, 0, BOTTOM_PLATE_H + PANEL_HEIGHT))
parts.append(tp)

# === 5. Fuse everything into one wall solid ===
wall = parts[0]
for p in parts[1:]:
    wall = wall.fuse(p)

feature = doc.addObject("Part::Feature", "ExteriorLeftWall")
feature.Shape = wall

# === 6. Window Units (Separate Features) ===
UNIT_FRAME_T = 65
GLASS_T = 28

units_fused = None
for ox in [OPENING1_X, OPENING2_X]:
    win_frame = Part.makeBox(CLEAR_W, UNIT_FRAME_T, CLEAR_H,
                             Vector(ox + KING_W + TRIMMER_W,
                                    (TOTAL_THICKNESS - UNIT_FRAME_T) / 2,
                                    CLEAR_BASE_Z))
    glazing   = Part.makeBox(CLEAR_W - 40, GLASS_T, CLEAR_H - 40,
                             Vector(ox + KING_W + TRIMMER_W + 20,
                                    (TOTAL_THICKNESS - GLASS_T) / 2,
                                    CLEAR_BASE_Z + 20))
    unit = win_frame.fuse(glazing)
    
    if units_fused is None:
        units_fused = unit
    else:
        units_fused = units_fused.fuse(unit)

unit_obj = doc.addObject("Part::Feature", "WindowUnits")
unit_obj.Shape = units_fused

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
★
Ready for review (v1)
◉
Provider updated to google / balanced
◉
Provider updated to google
◉
Component approved by user
◉
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
◉
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