Update app.py
Browse files
app.py
CHANGED
|
@@ -47,49 +47,88 @@ lawn = st.checkbox("Lawn/Garden 🌳")
|
|
| 47 |
if st.button("Generate Professional Plan"):
|
| 48 |
prompt = f"""
|
| 49 |
Design a house plan for a {plot_length}x{plot_width} ft plot following architectural best practices.
|
| 50 |
-
Return response in JSON format with:
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
"""
|
| 56 |
-
|
| 57 |
try:
|
| 58 |
response = client.chat.completions.create(
|
| 59 |
messages=[{"role": "user", "content": prompt}],
|
| 60 |
model="llama3-70b-8192",
|
| 61 |
-
response_format={"type": "json_object"}
|
|
|
|
| 62 |
)
|
|
|
|
|
|
|
| 63 |
plan = json.loads(response.choices[0].message.content)
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
st.success("✅ Professionally Designed Plan Generated!")
|
| 66 |
|
| 67 |
# --- 2D Visualization ---
|
| 68 |
st.header("📐 2D Floor Plan")
|
| 69 |
|
| 70 |
-
# Create figure
|
| 71 |
fig, ax = plt.subplots(figsize=(10, 8))
|
|
|
|
| 72 |
|
| 73 |
# Plot rooms
|
| 74 |
-
for room in plan['floor_plan']['rooms']:
|
| 75 |
rect = plt.Rectangle(
|
| 76 |
(room['x'], room['y']),
|
| 77 |
room['width'],
|
| 78 |
room['height'],
|
| 79 |
linewidth=2,
|
| 80 |
edgecolor='black',
|
| 81 |
-
facecolor=
|
| 82 |
ax.add_patch(rect)
|
| 83 |
|
| 84 |
# Add room label
|
| 85 |
center_x = room['x'] + room['width']/2
|
| 86 |
center_y = room['y'] + room['height']/2
|
| 87 |
ax.text(center_x, center_y,
|
| 88 |
-
f"{room['width']}x{room['height']}ft",
|
| 89 |
ha='center', va='center', fontsize=8)
|
| 90 |
|
| 91 |
# Plot washrooms
|
| 92 |
-
for washroom in plan['floor_plan']
|
| 93 |
rect = plt.Rectangle(
|
| 94 |
(washroom['x'], washroom['y']),
|
| 95 |
washroom['width'],
|
|
@@ -99,6 +138,10 @@ if st.button("Generate Professional Plan"):
|
|
| 99 |
facecolor='lightblue',
|
| 100 |
hatch='/')
|
| 101 |
ax.add_patch(rect)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
|
| 103 |
# Set plot limits and labels
|
| 104 |
ax.set_xlim(0, plot_length)
|
|
@@ -112,26 +155,26 @@ if st.button("Generate Professional Plan"):
|
|
| 112 |
# --- 3D Visualization ---
|
| 113 |
st.header("✨ 3D Visualization")
|
| 114 |
|
| 115 |
-
# Create simple 3D representation
|
| 116 |
fig_3d = go.Figure()
|
| 117 |
|
| 118 |
# Add rooms as 3D boxes
|
| 119 |
-
for room in plan['floor_plan']['rooms']:
|
| 120 |
fig_3d.add_trace(go.Mesh3d(
|
| 121 |
x=[room['x'], room['x'], room['x']+room['width'], room['x']+room['width'], room['x']],
|
| 122 |
y=[room['y'], room['y']+room['height'], room['y']+room['height'], room['y'], room['y']],
|
| 123 |
z=[0, 0, 0, 0, 0],
|
| 124 |
-
opacity=0.
|
| 125 |
-
color='
|
| 126 |
-
|
|
|
|
| 127 |
))
|
| 128 |
fig_3d.add_trace(go.Mesh3d(
|
| 129 |
x=[room['x'], room['x'], room['x']+room['width'], room['x']+room['width'], room['x']],
|
| 130 |
y=[room['y'], room['y']+room['height'], room['y']+room['height'], room['y'], room['y']],
|
| 131 |
z=[10, 10, 10, 10, 10],
|
| 132 |
-
opacity=0.
|
| 133 |
-
color='
|
| 134 |
-
|
| 135 |
))
|
| 136 |
|
| 137 |
fig_3d.update_layout(
|
|
@@ -142,7 +185,8 @@ if st.button("Generate Professional Plan"):
|
|
| 142 |
aspectmode='manual',
|
| 143 |
aspectratio=dict(x=1, y=plot_width/plot_length, z=0.2)
|
| 144 |
),
|
| 145 |
-
margin=dict(r=20, l=10, b=10, t=30)
|
|
|
|
| 146 |
)
|
| 147 |
st.plotly_chart(fig_3d)
|
| 148 |
|
|
@@ -159,8 +203,10 @@ if st.button("Generate Professional Plan"):
|
|
| 159 |
for warning in plan['warnings']:
|
| 160 |
st.markdown(f"- ⚠️ {warning}")
|
| 161 |
|
|
|
|
|
|
|
| 162 |
except Exception as e:
|
| 163 |
-
st.error(f"Error: {e}.
|
| 164 |
|
| 165 |
# Footer
|
| 166 |
st.markdown("---")
|
|
|
|
| 47 |
if st.button("Generate Professional Plan"):
|
| 48 |
prompt = f"""
|
| 49 |
Design a house plan for a {plot_length}x{plot_width} ft plot following architectural best practices.
|
| 50 |
+
Return response in STRICT JSON format with these EXACT keys:
|
| 51 |
+
{{
|
| 52 |
+
"floor_plan": {{
|
| 53 |
+
"rooms": [
|
| 54 |
+
{{
|
| 55 |
+
"name": "string",
|
| 56 |
+
"x": number,
|
| 57 |
+
"y": number,
|
| 58 |
+
"width": number,
|
| 59 |
+
"height": number
|
| 60 |
+
}}
|
| 61 |
+
],
|
| 62 |
+
"washrooms": [
|
| 63 |
+
{{
|
| 64 |
+
"name": "string",
|
| 65 |
+
"x": number,
|
| 66 |
+
"y": number,
|
| 67 |
+
"width": number,
|
| 68 |
+
"height": number
|
| 69 |
+
}}
|
| 70 |
+
]
|
| 71 |
+
}},
|
| 72 |
+
"visualization_tips": ["string"],
|
| 73 |
+
"material_suggestions": ["string"],
|
| 74 |
+
"warnings": ["string"]
|
| 75 |
+
}}
|
| 76 |
+
|
| 77 |
+
Requirements:
|
| 78 |
+
1. All dimensions must be numbers (not arrays)
|
| 79 |
+
2. Positions must be x,y coordinates as separate numbers
|
| 80 |
+
3. Room names should be clear (e.g., "Master Bedroom")
|
| 81 |
+
4. Include at least {master_bed} master bedroom(s) and {bedrooms} standard bedroom(s)
|
| 82 |
"""
|
| 83 |
+
|
| 84 |
try:
|
| 85 |
response = client.chat.completions.create(
|
| 86 |
messages=[{"role": "user", "content": prompt}],
|
| 87 |
model="llama3-70b-8192",
|
| 88 |
+
response_format={"type": "json_object"},
|
| 89 |
+
temperature=0.3 # More deterministic output
|
| 90 |
)
|
| 91 |
+
|
| 92 |
+
# Parse and validate response
|
| 93 |
plan = json.loads(response.choices[0].message.content)
|
| 94 |
+
|
| 95 |
+
# Validate required fields
|
| 96 |
+
required_keys = ["floor_plan", "visualization_tips", "material_suggestions", "warnings"]
|
| 97 |
+
for key in required_keys:
|
| 98 |
+
if key not in plan:
|
| 99 |
+
raise ValueError(f"Missing required key: {key}")
|
| 100 |
+
|
| 101 |
+
if "rooms" not in plan["floor_plan"]:
|
| 102 |
+
raise ValueError("Missing rooms in floor plan")
|
| 103 |
+
|
| 104 |
st.success("✅ Professionally Designed Plan Generated!")
|
| 105 |
|
| 106 |
# --- 2D Visualization ---
|
| 107 |
st.header("📐 2D Floor Plan")
|
| 108 |
|
|
|
|
| 109 |
fig, ax = plt.subplots(figsize=(10, 8))
|
| 110 |
+
colors = plt.cm.tab20.colors
|
| 111 |
|
| 112 |
# Plot rooms
|
| 113 |
+
for i, room in enumerate(plan['floor_plan']['rooms']):
|
| 114 |
rect = plt.Rectangle(
|
| 115 |
(room['x'], room['y']),
|
| 116 |
room['width'],
|
| 117 |
room['height'],
|
| 118 |
linewidth=2,
|
| 119 |
edgecolor='black',
|
| 120 |
+
facecolor=colors[i % len(colors)])
|
| 121 |
ax.add_patch(rect)
|
| 122 |
|
| 123 |
# Add room label
|
| 124 |
center_x = room['x'] + room['width']/2
|
| 125 |
center_y = room['y'] + room['height']/2
|
| 126 |
ax.text(center_x, center_y,
|
| 127 |
+
f"{room.get('name', 'Room')}\n{room['width']}x{room['height']}ft",
|
| 128 |
ha='center', va='center', fontsize=8)
|
| 129 |
|
| 130 |
# Plot washrooms
|
| 131 |
+
for washroom in plan['floor_plan'].get('washrooms', []):
|
| 132 |
rect = plt.Rectangle(
|
| 133 |
(washroom['x'], washroom['y']),
|
| 134 |
washroom['width'],
|
|
|
|
| 138 |
facecolor='lightblue',
|
| 139 |
hatch='/')
|
| 140 |
ax.add_patch(rect)
|
| 141 |
+
ax.text(washroom['x'] + washroom['width']/2,
|
| 142 |
+
washroom['y'] + washroom['height']/2,
|
| 143 |
+
"Bath",
|
| 144 |
+
ha='center', va='center', fontsize=8)
|
| 145 |
|
| 146 |
# Set plot limits and labels
|
| 147 |
ax.set_xlim(0, plot_length)
|
|
|
|
| 155 |
# --- 3D Visualization ---
|
| 156 |
st.header("✨ 3D Visualization")
|
| 157 |
|
|
|
|
| 158 |
fig_3d = go.Figure()
|
| 159 |
|
| 160 |
# Add rooms as 3D boxes
|
| 161 |
+
for i, room in enumerate(plan['floor_plan']['rooms']):
|
| 162 |
fig_3d.add_trace(go.Mesh3d(
|
| 163 |
x=[room['x'], room['x'], room['x']+room['width'], room['x']+room['width'], room['x']],
|
| 164 |
y=[room['y'], room['y']+room['height'], room['y']+room['height'], room['y'], room['y']],
|
| 165 |
z=[0, 0, 0, 0, 0],
|
| 166 |
+
opacity=0.7,
|
| 167 |
+
color=f'rgb({colors[i][0]*255},{colors[i][1]*255},{colors[i][2]*255})',
|
| 168 |
+
name=room.get('name', 'Room'),
|
| 169 |
+
showlegend=True
|
| 170 |
))
|
| 171 |
fig_3d.add_trace(go.Mesh3d(
|
| 172 |
x=[room['x'], room['x'], room['x']+room['width'], room['x']+room['width'], room['x']],
|
| 173 |
y=[room['y'], room['y']+room['height'], room['y']+room['height'], room['y'], room['y']],
|
| 174 |
z=[10, 10, 10, 10, 10],
|
| 175 |
+
opacity=0.7,
|
| 176 |
+
color=f'rgb({colors[i][0]*255},{colors[i][1]*255},{colors[i][2]*255})',
|
| 177 |
+
showlegend=False
|
| 178 |
))
|
| 179 |
|
| 180 |
fig_3d.update_layout(
|
|
|
|
| 185 |
aspectmode='manual',
|
| 186 |
aspectratio=dict(x=1, y=plot_width/plot_length, z=0.2)
|
| 187 |
),
|
| 188 |
+
margin=dict(r=20, l=10, b=10, t=30),
|
| 189 |
+
legend=dict(x=1, y=1)
|
| 190 |
)
|
| 191 |
st.plotly_chart(fig_3d)
|
| 192 |
|
|
|
|
| 203 |
for warning in plan['warnings']:
|
| 204 |
st.markdown(f"- ⚠️ {warning}")
|
| 205 |
|
| 206 |
+
except json.JSONDecodeError:
|
| 207 |
+
st.error("Failed to parse the AI response. Please try again.")
|
| 208 |
except Exception as e:
|
| 209 |
+
st.error(f"Error: {str(e)}. Please adjust your inputs and try again.")
|
| 210 |
|
| 211 |
# Footer
|
| 212 |
st.markdown("---")
|