← house

Pitched-L Manufacturable SIP Roof Panels

v1 AI approved

Use SIPRoofPanelizer with the exact lower_wing, upper_wing, pitch and stock in pitched_l metadata. Generate separate stock-constrained panels; never emit GableRoom as a fabrication part.

Dependencies

s0_wall_e0.body s0_wall_e1.body s0_wall_e2.body s0_wall_e3.body s0_wall_e4.body s0_wall_e5.body

Interfaces Provided

body (component)
◉
Agent initialized (status: waiting_for_dependencies, action: check_dependencies)
◉
Provider: claude_code | Profile: balanced
◇
Received interface s0_wall_e2.corner_north_east: %{name: "corner_north_east", type: nil, value: %{}, agent_id: "s0_wall_e2"}
◇
Received interface s0_wall_e2.corner_north_west: %{name: "corner_north_west", type: nil, value: %{}, agent_id: "s0_wall_e2"}
◇
Received interface s0_wall_e2.body: %{name: "body", type: "component", value: %{}, agent_id: "s0_wall_e2"}
◇
Received interface s0_wall_e0.corner_south_west: %{name: "corner_south_west", type: nil, value: %{}, agent_id: "s0_wall_e0"}
◇
Received interface s0_wall_e0.corner_south_east: %{name: "corner_south_east", type: nil, value: %{}, agent_id: "s0_wall_e0"}
◇
Received interface s0_wall_e0.body: %{name: "body", type: "component", value: %{}, agent_id: "s0_wall_e0"}
◇
Received interface s0_wall_e3.corner_north_west: %{name: "corner_north_west", type: nil, value: %{}, agent_id: "s0_wall_e3"}
◇
Received interface s0_wall_e3.corner_concave: %{name: "corner_concave", type: nil, value: %{}, agent_id: "s0_wall_e3"}
◇
Received interface s0_wall_e3.body: %{name: "body", type: "component", value: %{}, agent_id: "s0_wall_e3"}
◇
Received interface s0_wall_e5.corner_south_west_upper: %{name: "corner_south_west_upper", type: nil, value: %{}, agent_id: "s0_wall_e5"}
◇
Received interface s0_wall_e5.corner_concave: %{name: "corner_concave", type: nil, value: %{}, agent_id: "s0_wall_e5"}
◇
Received interface s0_wall_e5.body: %{name: "body", type: "component", value: %{}, agent_id: "s0_wall_e5"}
◉
Provider updated to claude_code / balanced
◉
Provider updated to claude_code / balanced
◉
Provider updated to claude_code / balanced
◉
Provider updated to claude_code / balanced
◇
Received interface s0_wall_e1.outer_surface: %{name: "outer_surface", type: "planar_face", value: %{}, agent_id: "s0_wall_e1"}
◇
Received interface s0_wall_e1.inner_surface: %{name: "inner_surface", type: "planar_face", value: %{}, agent_id: "s0_wall_e1"}
◇
Received interface s0_wall_e1.body: %{name: "body", type: "component", value: %{}, agent_id: "s0_wall_e1"}
◇
Received interface s0_wall_e4.outer_surface: %{name: "outer_surface", type: "planar_face", value: %{}, agent_id: "s0_wall_e4"}
◇
Received interface s0_wall_e4.inner_surface: %{name: "inner_surface", type: "planar_face", value: %{}, agent_id: "s0_wall_e4"}
◇
Received interface s0_wall_e4.top_bearing: %{name: "top_bearing", type: "planar_face", value: %{}, agent_id: "s0_wall_e4"}
◇
Received interface s0_wall_e4.body: %{name: "body", type: "component", value: %{}, agent_id: "s0_wall_e4"}
◉
All dependencies resolved, starting generation
◉
Refreshed placement from design spec (bbox %{"x" => 12000.0, "y" => 6000.0, "z" => 2531.4010767585028})
◉
Generating v1
◉
Using deterministic SIPRoofPanelizer design-roof generation
◆
pitched_l_roof_panels_v1.py · 37 lines
import json
import FreeCAD
import Part
from elixifree.domains.sip import SIPRoofPanelizer, SIPRoofStructure

doc = FreeCAD.ActiveDocument or FreeCAD.newDocument("Model")
contract = json.loads("{\"lower_wing\":{\"x0\":0.0,\"x1\":1.2e4,\"y0\":3.0e3,\"y1\":6.0e3},\"pitch_degrees\":30.0,\"stock\":\"SIP-200\",\"upper_wing\":{\"x0\":4.0e3,\"x1\":1.2e4,\"y0\":0.0,\"y1\":6.0e3}}")
skeleton = json.loads("{\"apex_z\":2309.4010767585028,\"edge_roles\":[{\"edge\":0,\"role\":\"gable\",\"valley_adjacent\":false,\"wing\":\"upper\"},{\"edge\":1,\"role\":\"eave\",\"valley_adjacent\":false,\"wing\":\"upper\"},{\"edge\":2,\"role\":\"eave\",\"valley_adjacent\":false,\"wing\":\"lower\"},{\"edge\":3,\"role\":\"gable\",\"valley_adjacent\":false,\"wing\":\"lower\"},{\"edge\":4,\"role\":\"eave\",\"valley_adjacent\":true,\"wing\":\"lower\"},{\"edge\":5,\"role\":\"eave\",\"valley_adjacent\":true,\"wing\":\"upper\"}],\"footprint\":[[4.0e3,0.0],[1.2e4,0.0],[1.2e4,6.0e3],[0.0,6.0e3],[0.0,3.0e3],[4.0e3,3.0e3]],\"pitch_deg\":30.0,\"planes\":[{\"axis\":\"y\",\"direction\":1.0,\"id\":\"lower_south\",\"origin\":3.0e3,\"side\":\"south\",\"tan_pitch\":0.5773502691896257,\"wing\":\"lower\"},{\"axis\":\"y\",\"direction\":-1.0,\"id\":\"lower_north\",\"origin\":6.0e3,\"side\":\"north\",\"tan_pitch\":0.5773502691896257,\"wing\":\"lower\"},{\"axis\":\"x\",\"direction\":1.0,\"id\":\"upper_west\",\"origin\":4.0e3,\"side\":\"west\",\"tan_pitch\":0.5773502691896257,\"wing\":\"upper\"},{\"axis\":\"x\",\"direction\":-1.0,\"id\":\"upper_east\",\"origin\":1.2e4,\"side\":\"east\",\"tan_pitch\":0.5773502691896257,\"wing\":\"upper\"}],\"ridges\":[{\"from\":[0.0,4.5e3,866.0254037844386],\"id\":\"ridge_lower\",\"to\":[1.2e4,4.5e3,866.0254037844386],\"wing\":\"lower\"},{\"from\":[8.0e3,0.0,2309.4010767585028],\"id\":\"ridge_upper\",\"to\":[8.0e3,6.0e3,2309.4010767585028],\"wing\":\"upper\"}],\"type\":\"gable\",\"valley\":{\"adjacent_wings\":[\"lower\",\"upper\"],\"from\":[4.0e3,3.0e3,0.0],\"id\":\"valley\",\"to\":[5.5e3,4.5e3,866.0254037844386]},\"wings\":{\"concave\":[4.0e3,3.0e3],\"lower\":{\"x0\":0.0,\"x1\":1.2e4,\"y0\":3.0e3,\"y1\":6.0e3},\"upper\":{\"x0\":4.0e3,\"x1\":1.2e4,\"y0\":0.0,\"y1\":6.0e3}}}")

panelizer = SIPRoofPanelizer(
    contract["lower_wing"],
    contract["upper_wing"],
    contract["pitch_degrees"],
    stock=contract["stock"],
    skeleton=skeleton,
)
panel_result = panelizer.panelize()
panel_shapes = [part.shape for part in panel_result.parts if part.shape is not None]
if not panel_shapes:
    raise RuntimeError("SIPRoofPanelizer produced no design roof solids")

feature = doc.addObject("Part::Feature", "Body")
feature.Label = "Pitched-L SIP Roof Panels"
feature.addProperty("App::PropertyString", "RoofGenerator")
feature.RoofGenerator = "SIPRoofPanelizer"
feature.addProperty("App::PropertyFloat", "PitchDegrees")
feature.PitchDegrees = float(contract["pitch_degrees"])
feature.addProperty("App::PropertyString", "RoofStock")
feature.RoofStock = contract["stock"]
feature.addProperty("App::PropertyInteger", "PanelCount")
feature.PanelCount = len(panel_shapes)
feature.Shape = Part.makeCompound(panel_shapes)
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 claude_code / balanced
◉
Provider updated to claude_code / balanced
v0.0.985