Wall Module Specification
Wall Module Schema → FreeCAD Geometry Compiler
https://chatgpt.com/share/69707955-7ca4-8010-850a-ca6cef5201ee
This page defines the canonical transformation from a wall module specification (schema instance) into deterministic CAD geometry in FreeCAD.
Scope
- Wall modules built from 2x6 framing, 24" OC
- Optional OSB sheathing on Face A (7/16")
- Optional openings:
- Window (RO width/height, sill height, x position)
- Door (RO width/height, centered in 4' module by default)
- Flush-built header: (2) 2x12 members, biased to Face A
Canonical Principle
A module is defined as data (specification), not as geometry. CAD geometry is a compiled artifact produced deterministically from the spec.
Inputs
Required fields
- module.id
- module.width_in
- module.height_in
- module.stud_spacing_oc_in (default 24)
- plates.top_plate_count (default 2)
- plates.bottom_plate_count (default 1)
- sheathing.thickness_in (default 7/16), sheathing.side = "A"
- openings[] (optional)
Opening fields
For each opening in openings[]:
- opening.id
- opening.type: "window" or "door"
- opening.rough_opening.width_in, height_in
- window: opening.sill_height_from_bottom_in
- placement:
- window: opening.x_from_left_in
- door: opening.centered_in_module=true OR opening.x_from_left_in
- header: lumber="2x12", members=2, bias_to_face="A"
Coordinate System (CAD Convention)
- X = module width (left→right)
- Y = wall thickness (Face A at y=0; Face B at y=+5.5)
- Z = height (bottom at z=0)
All schema lengths are in inches. Compiler converts to mm for FreeCAD internal units.
Output (Geometry Contract)
FreeCAD document (.FCStd) containing:
- Containers (groups):
- WallModule
- Framing
- Plates
- Studs
- Openings (per-opening subgroups)
- Sheathing
- Framing
- WallModule
- Solid bodies for each physical part:
- Plates, studs, kings, jacks, headers, sills, cripples
- OSB panels (as thin solids on Face A)
- Deterministic naming for downstream drawing + BOM automation:
- Example: TP_0, BP_0, STUD_03, W1_JACK_L, D1_HEADER_2PLY_2X12, OSB_00, etc.
Compiler Pipeline
Step 0: Validate Spec
- Confirm required fields exist
- Confirm module width/height are within allowed ranges (implementation-defined)
- Confirm door constraints (v0 default):
- single door module width must be 48" unless explicitly overridden
Step 1: Derive Constants
Assume nominal-to-actual conversions:
- 2x thickness = 1.5"
- 2x6 depth = 5.5"
- 2x12 depth = 11.25"
Compute:
- wall_thickness = 5.5"
- plate_thickness = 1.5"
- stud_length = module.height_in - plate_thickness*(top_plate_count + bottom_plate_count)
Step 2: Place Plates
- Bottom plate(s) at z = 0..1.5"
- Top plate(s) at z = module.height_in - 1.5*top_plate_count .. module.height_in
- Door special case (v0): split bottom plate around door RO span
Step 3: Generate Base Stud Grid
Define stud centerlines with 24" OC:
- Always include end studs
- Interior studs at: x = x_start + n*OC
Create studs as 1.5" x 5.5" x stud_length solids placed at:
- y = 0
- z = 1.5*bottom_plate_count
Step 4: Compile Openings (Replace Studs + Add Framing)
For each opening: 1. Compute RO rectangle:
- x0, x1 from placement + RO width
- z0, z1 from sill height (window) or 0 (door) + RO height
2. Remove any base studs whose x-span overlaps [x0, x1] 3. Add kings (full height) at the outside of the opening assembly 4. Add jacks (trimmers) at opening edges from bottom plates up to header bearing 5. Add header:
- length = RO.width + 2*1.5" (v0 bearing rule)
- depth = 11.25" (2x12)
- thickness = 3.0" (two 2x members laminated)
- biased to Face A: header placed at y=0..3.0"
6. Add cripples above header up to underside of top plates on the 24" grid 7. Window only:
- Add sill member at z = sill_height + 1.5" (v0)
- Add cripples below sill down to top of bottom plates
Step 5: Panelize OSB Sheathing on Face A
Place OSB as thin solids on Face A at y = -OSB_thickness..0.
Height sourcing policy:
- If module.height_in <= 108": use a single 9' sheet (cut to height)
- Else if module.height_in <= 120": use a single 10' sheet (cut to height)
- Else: use 8' sheet + remainder pieces to reach full height
Width policy (v0):
- If width <= 48": one panel (rip to width)
- If width <= 96": two panels (48" + remainder)
- If width > 96": tile in 48" increments + remainder
The panelizer outputs a list of rectangles {w,h,x,z} which become OSB solids.
Step 6: Emit Geometry
The compiler creates FreeCAD objects using primitive solids (Part::Box or PartDesign solids):
- Each part is created as a separate object
- Each part has deterministic name and placement
- Objects are added into the group tree for downstream automation
Step 7: Recompute + Save
- doc.recompute()
- doc.saveAs("<module.id>.FCStd")
Minimal Pseudocode
spec = load(schema_instance)
validate(spec)
W,H,OC = spec.module.width, spec.module.height, spec.module.stud_spacing_oc
top_n, bot_n = spec.plates.top_count, spec.plates.bottom_count
stud_len = H - 1.5*(top_n + bot_n)
create_plates(W,H,top_n,bot_n)
stud_centers = make_stud_centers(W, OC)
base_studs = create_studs(stud_centers, stud_len)
for opening in spec.openings:
ro = compute_opening_rect(opening, W)
delete_overlapping_studs(base_studs, ro.x0, ro.x1)
add_kings_and_jacks(ro)
add_header(ro, members=2, size="2x12", bias="FaceA")
add_cripples_above(ro)
if opening.type == "window":
add_sill(ro)
add_cripples_below(ro)
panels = panelize_osb(W,H, spec.sheathing.policy)
create_osb_solids(panels, face="A")
recompute_and_save()
Determinism Rules
To ensure compile reproducibility:
- No interactive sketching
- No manual edits downstream of compilation
- Stable naming conventions for every generated part
- Same spec input must produce identical part counts, placements, and names
Notes
This is a geometry compiler spec, not a structural engineering standard. Structural detailing (nailing schedules, corner conditions, advanced header sizing, etc.) are layered as additional schema fields and compiler rules in later versions.