← Skills

SIP Wall Construction

Native Read-only

SIP panel specs, spline types, wall assembly code, corner conditions, and plate rules. Injected to agents building wall components.

/skills/sip_walls.md

Estimated tokens
2728
Characters
10911
Source
Native

Markdown

# SIP Wall Construction Skill

## SIP Panel Specifications (Metric)

All dimensions in millimetres. OSB facing is 11mm each side.

| Name         | Total Thickness | Core (EPS) | Approx. R-Value |
|--------------|-----------------|------------|-----------------|
| SIP-100      | 122mm           | 100mm      | R-15            |
| SIP-150      | 172mm           | 150mm      | R-23            |
| SIP-200      | 222mm           | 200mm      | R-30            |
| SIP-250      | 272mm           | 250mm      | R-38            |
| SIP-300      | 322mm           | 300mm      | R-45            |

**Standard panel widths:** 1200mm (preferred) or 1220mm
**Standard panel heights:** 2400mm, 2700mm, 3000mm (custom heights available)
**OSB face thickness:** 11mm each side

Wall panels orient with height vertical (Z-axis). Roof panels orient with height along slope.

---

## Panel FreeCAD Code Pattern

Model each SIP panel as a 3-layer fused solid: two OSB faces + EPS foam core.

```python
import FreeCAD, Part, math
from FreeCAD import Vector

# === PARAMETERS ===
PANEL_WIDTH = 1200       # mm
PANEL_HEIGHT = 2700      # mm
CORE_THICKNESS = 150     # mm (SIP-150)
FACE_THICKNESS = 11      # mm OSB each side
TOTAL_THICKNESS = CORE_THICKNESS + 2 * FACE_THICKNESS  # 172mm

# === BUILD PANEL ===
doc = FreeCAD.ActiveDocument or FreeCAD.newDocument("SIP_Panel")

face1 = Part.makeBox(PANEL_WIDTH, FACE_THICKNESS, PANEL_HEIGHT,
                     Vector(0, 0, 0))
core  = Part.makeBox(PANEL_WIDTH, CORE_THICKNESS, PANEL_HEIGHT,
                     Vector(0, FACE_THICKNESS, 0))
face2 = Part.makeBox(PANEL_WIDTH, FACE_THICKNESS, PANEL_HEIGHT,
                     Vector(0, FACE_THICKNESS + CORE_THICKNESS, 0))

panel = face1.fuse(core).fuse(face2)

obj = doc.addObject("Part::Feature", "SIP_Panel")
obj.Shape = panel
doc.recompute()
```

---

## Spline Types and Geometry

Splines join adjacent panels at vertical (wall) and lateral (roof) edges.

### Surface Spline
Thin OSB/plywood strip inserted into a routed groove in the panel foam face.
- Width: 45mm
- Thickness: 18mm
- Height: matches panel height
- Sits centred in the panel thickness, recessed 15mm into each panel face

```python
SPLINE_WIDTH = 45
SPLINE_THICKNESS = 18
SPLINE_HEIGHT = PANEL_HEIGHT

spline = Part.makeBox(SPLINE_THICKNESS, SPLINE_WIDTH, SPLINE_HEIGHT,
                      Vector(joint_x - SPLINE_THICKNESS / 2,
                             (TOTAL_THICKNESS - SPLINE_WIDTH) / 2,
                             0))
```

### Block Spline (most common)
Solid timber friction-fitted between panel foam cores at a joint.
- 45 × 90mm for SIP-100/SIP-150 walls
- 45 × 140mm for SIP-200+ walls
- Height: matches panel height

```python
SPLINE_W = 45
SPLINE_D = 90   # or 140 for thicker panels

spline = Part.makeBox(SPLINE_W, SPLINE_D, PANEL_HEIGHT,
                      Vector(joint_x,
                             (TOTAL_THICKNESS - SPLINE_D) / 2,
                             BOTTOM_PLATE_H))
```

### LVL Spline
Engineered lumber for structural or high-load joints. Same geometry as block spline but specified as LVL material. Size to load — minimum 45 × 90mm.

### Double Block Spline (corners)
Two block splines side by side at corner junctions. Used where extra structural capacity is needed at L-corners and wall-to-roof junctions.

---

## Wall Assembly

**Every wall is a sequence of individual 1200mm SIP panels joined by block splines, sitting on a pressure-treated bottom plate. Never model a wall as a single box.**

```
┌─────────────────────────────────────┐  ← double top plate (2× 45×90mm)  Z = BOTTOM_PLATE_H + PANEL_HEIGHT
│  Panel  │Sp│  Panel  │Sp│  Panel  │  ← SIP panels                        Z = BOTTOM_PLATE_H (= 90)
└─────────────────────────────────────┘  ← PT bottom plate (45×90mm)        Z = 0
══════════════════════════════════════   ← slab top / floor level            Z = 0
```

**Bottom plate (mandatory — generated by the wall component, not the foundation):**
45 × 90mm pressure-treated timber, full wall length, sits at Z=0 on the slab DPC. The SIP panels start at Z=90 on top of this plate. If the wall code does not include a bottom plate at Z=0, the panels will be floating directly on concrete — this is wrong.

**Top plate:** Double 45 × 90mm timber, full wall length, nailed through OSB face into foam.

**Wall height** = BOTTOM_PLATE_H + PANEL_HEIGHT + TOP_PLATE_H = 90 + panel_height + 180mm

### Panel Count Calculation

Always calculate how many full 1200mm panels fit and what remainder is needed:

```python
full_panels = WALL_LENGTH // 1200          # number of full-width panels
remainder   = WALL_LENGTH % 1200           # width of last custom panel (0 = exact fit)
panel_count = full_panels + (1 if remainder > 0 else 0)
panel_widths = [1200] * full_panels + ([remainder] if remainder > 0 else [])
```

Common wall lengths:
| Wall length | Full panels | Remainder panel |
|-------------|-------------|-----------------|
| 2400mm      | 2           | none            |
| 3000mm      | 2           | 600mm           |
| 3600mm      | 3           | none            |
| 4800mm      | 4           | none            |
| 6000mm      | 5           | none            |
| 9000mm      | 7           | 600mm           |

### Wall Assembly Code

```python
import FreeCAD, Part
from FreeCAD import Vector

# === WALL PARAMETERS ===
WALL_LENGTH = 3000        # example: 3m wall = 2 full panels + 1×600mm remainder
PANEL_HEIGHT = 2700
CORE_THICKNESS = 150
FACE_THICKNESS = 11
TOTAL_THICKNESS = CORE_THICKNESS + 2 * FACE_THICKNESS   # 172mm for SIP-150
BOTTOM_PLATE_H = 90       # PT timber bottom plate — MANDATORY
TOP_PLATE_H = 180         # double top plate (2× 45mm)
SPLINE_W = 45
SPLINE_D = 90

doc = FreeCAD.ActiveDocument or FreeCAD.newDocument("Wall")

# --- Panel widths (calculated, not hardcoded) ---
full_panels = WALL_LENGTH // 1200
remainder   = WALL_LENGTH % 1200
panel_widths = [1200] * full_panels + ([remainder] if remainder > 0 else [])

# === STEP 1: Bottom plate (MANDATORY — wall sits on this, not directly on slab) ===
# Depth = CORE_THICKNESS (not TOTAL_THICKNESS) — plate slots into the foam groove.
# OSB skins (FACE_THICKNESS each) overhang on both faces; offset plate by FACE_THICKNESS.
bp = Part.makeBox(WALL_LENGTH, CORE_THICKNESS, BOTTOM_PLATE_H, Vector(0, FACE_THICKNESS, 0))
parts = [bp]

# === STEP 2: SIP panels and block splines — one panel per entry in panel_widths ===
x = 0
for i, pw in enumerate(panel_widths):
    # Three-layer SIP panel
    face1 = Part.makeBox(pw, FACE_THICKNESS, PANEL_HEIGHT,
                         Vector(x, 0, BOTTOM_PLATE_H))
    core  = Part.makeBox(pw, CORE_THICKNESS, PANEL_HEIGHT,
                         Vector(x, FACE_THICKNESS, BOTTOM_PLATE_H))
    face2 = Part.makeBox(pw, FACE_THICKNESS, PANEL_HEIGHT,
                         Vector(x, FACE_THICKNESS + CORE_THICKNESS, BOTTOM_PLATE_H))
    parts.extend([face1, core, face2])
    x += pw
    # Block spline at joint between this panel and the next
    if i < len(panel_widths) - 1:
        sp = Part.makeBox(SPLINE_W, SPLINE_D, PANEL_HEIGHT,
                          Vector(x - SPLINE_W / 2,
                                 (TOTAL_THICKNESS - SPLINE_D) / 2,
                                 BOTTOM_PLATE_H))
        parts.append(sp)

# === STEP 3: Double top plate ===
# Same rule as bottom plate: CORE_THICKNESS depth, offset by FACE_THICKNESS.
tp = Part.makeBox(WALL_LENGTH, CORE_THICKNESS, TOP_PLATE_H,
                  Vector(0, FACE_THICKNESS, BOTTOM_PLATE_H + PANEL_HEIGHT))
parts.append(tp)

wall = parts[0]
for p in parts[1:]:
    wall = wall.fuse(p)

feature = doc.addObject("Part::Feature", "Wall")
feature.Shape = wall
doc.recompute()
```

---

## Corner Conditions

### L-Corner (external corner)
One wall panel face butts into the exterior face of the perpendicular wall's end panel. A double block spline fills the interior gap. The corner panel sits flush with the exterior face.

```
Plan view (top down):
 ┌──────────────────┐
 │  Wall A panels   │
 │                  ├──┐
 │                  │  │ Wall B
 └──────────────────┘  │ panels
       ↑               │
  double spline here   │
```

- Wall A runs full length to the outer face
- Wall B's end panel butts to Wall A's exterior OSB face
- A double block spline (2× 45×90mm) fills the corner pocket on Wall B's end

### T-Corner (interior partition meeting exterior wall)
Interior wall panel butts into the face of the exterior wall panel. Single block spline at junction. Interior wall bottom plate runs to exterior wall face.

---

## MANDATORY: Panel Span Splitting — Walls

Standard SIP stock is 2440mm × 1220mm. At wall heights above 2440mm, the panel must be vertically split.

### Wall Height Splice (if wall height > 2440mm)

Standard wall heights (2400mm, 2700mm, 3000mm) already come from manufacturer. Heights up to 2700mm fit within a single panel. At 3000mm the panel height is exactly at the 2440mm limit — use a 2440mm lower course + 560mm upper course:

```python
WALL_HEIGHT = 3000    # total panel height needed

if WALL_HEIGHT <= 2440:
    course_heights = [WALL_HEIGHT]    # single course
else:
    n_courses = math.ceil(WALL_HEIGHT / 2440)
    section_h  = WALL_HEIGHT / n_courses
    course_heights = [section_h] * n_courses

# For each course, build the panel loop. Between courses, add a horizontal LVL spline:
# LVL_SPLINE = Part.makeBox(WALL_LENGTH, CORE_THICKNESS, 45,
#                            Vector(0, FACE_THICKNESS, z_splice - 22.5))
```

---

## ⚠ Non-Negotiable Wall Rules

1. **Walls are always multiple panels — never a single box.**
   Every wall MUST be built using the panel loop (individual 1200mm-wide SIP panels with block splines between them). A wall modelled as one `Part.makeBox` is wrong regardless of wall length.

2. **Every wall component generates its own bottom plate.**
   The wall component (not the foundation) creates a 45×90mm PT timber bottom plate at Z=0 as the very first solid. The SIP panels sit on top of it at Z=90. A wall whose panels start at Z=0 is missing its bottom plate.

7. **Sole plates and top plates MUST use CORE_THICKNESS as their depth, offset by FACE_THICKNESS.**
   The timber plate slots into the routed groove in the SIP foam. The OSB skins overhang on both sides. A plate as wide as TOTAL_THICKNESS cannot enter the groove — it is 11mm too wide on each face.

   **Formula:** plate depth = `CORE_THICKNESS`, Y-offset = `FACE_THICKNESS`

   ```python
   # CORRECT — plate fits in the foam channel
   bp = Part.makeBox(WALL_LENGTH, CORE_THICKNESS, BOTTOM_PLATE_H,
                     Vector(0, FACE_THICKNESS, 0))
   tp = Part.makeBox(WALL_LENGTH, CORE_THICKNESS, TOP_PLATE_H,
                     Vector(0, FACE_THICKNESS, BOTTOM_PLATE_H + PANEL_HEIGHT))

   # WRONG — plate is full SIP thickness, cannot slot into panel
   # bp = Part.makeBox(WALL_LENGTH, TOTAL_THICKNESS, BOTTOM_PLATE_H, Vector(0, 0, 0))
   ```
v0.0.170