anabury's picture
Update
2070826 verified
import gradio as gr
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
import plotly.graph_objects as go
# ---------------- Room creation ----------------
def create_room(x, y, width, height, room_type, label=None):
room = {
'x': x,
'y': y,
'width': width,
'height': height,
'type': room_type,
'label': label or room_type
}
return room
# ---------------- 2D Drawing ----------------
def draw_room_2d(ax, room, colors):
rect = patches.Rectangle((room['x'], room['y']), room['width'], room['height'],
linewidth=1, edgecolor='black', facecolor=colors.get(room['type'], 'white'),
alpha=0.7)
ax.add_patch(rect)
ax.text(room['x'] + room['width']/2, room['y'] + room['height']/2,
room['label'], ha='center', va='center', fontsize=9)
# ---------------- 3D Plotly Drawing ----------------
def draw_floor_plan_3d_plotly(rooms, colors):
fig = go.Figure()
room_height = 3 # default height
for room in rooms:
x0, y0 = room['x'], room['y']
dx, dy, dz = room['width'], room['height'], room_height
color = colors.get(room['type'], 'lightgray')
# Draw 3D box using mesh3d
fig.add_trace(go.Mesh3d(
x=[x0, x0+dx, x0+dx, x0, x0, x0+dx, x0+dx, x0],
y=[y0, y0, y0+dy, y0+dy, y0, y0, y0+dy, y0+dy],
z=[0, 0, 0, 0, dz, dz, dz, dz],
color=color,
opacity=0.7,
flatshading=True,
name=room['label']
))
fig.update_layout(scene=dict(
xaxis_title='Length',
yaxis_title='Width',
zaxis_title='Height',
aspectmode='data'
))
return fig
# ---------------- Floor plan generation ----------------
def generate_building_plan(length, width, bedrooms, bathrooms, kitchen_size, living_room_size,
entry_direction, car_parking, include_garden, include_balcony):
scale_factor = min(length, width) / 10
colors = {
'bedroom': 'lightblue',
'bathroom': 'lightpink',
'kitchen': 'lightyellow',
'living': 'lightgreen',
'hallway': 'whitesmoke',
'parking': 'lightgray',
'garden': 'palegreen',
'balcony': 'lavender'
}
rooms = []
center_x, center_y = length/2, width/2
# Horizontal layout demo
living_area = length * width * living_room_size / 100
living_width = min(width * 0.6, np.sqrt(living_area * 1.5))
living_length = living_area / living_width
kitchen_area = length * width * kitchen_size / 100
kitchen_width = min(width * 0.4, np.sqrt(kitchen_area))
kitchen_length = kitchen_area / kitchen_width
bedroom_total_area = (length*width - living_area - kitchen_area) * 0.7
bedroom_area = bedroom_total_area / bedrooms
bedroom_width = np.sqrt(bedroom_area)
bedroom_length = bedroom_area / bedroom_width
current_x = 0
rooms.append(create_room(current_x, 0, living_length, living_width, 'living', 'Living Room'))
current_x += living_length
rooms.append(create_room(current_x, 0, kitchen_length, kitchen_width, 'kitchen', 'Kitchen'))
current_x += kitchen_length
for i in range(bedrooms):
rooms.append(create_room(current_x, 0, bedroom_length, bedroom_width, 'bedroom', f'Bedroom {i+1}'))
current_x += bedroom_length
if include_garden:
rooms.append(create_room(0, 0, scale_factor*4, scale_factor*4, 'garden', 'Garden'))
if include_balcony:
rooms.append(create_room(center_x - scale_factor*2.5, 0, scale_factor*5, scale_factor*2, 'balcony', 'Balcony'))
return rooms, colors
# ---------------- Gradio interface ----------------
def generate_plan_gradio(length, width, bedrooms, bathrooms, kitchen_size, living_room_size,
entry_direction, car_parking, include_garden, include_balcony, view_type):
rooms, colors = generate_building_plan(length, width, bedrooms, bathrooms, kitchen_size, living_room_size,
entry_direction, car_parking, include_garden, include_balcony)
if view_type == "2D":
fig, ax = plt.subplots(figsize=(10,8))
ax.set_xlim(-1, length+1)
ax.set_ylim(-1, width+1)
ax.set_aspect('equal')
ax.set_xticks([])
ax.set_yticks([])
for room in rooms:
draw_room_2d(ax, room, colors)
fig.tight_layout()
return fig
else:
fig = draw_floor_plan_3d_plotly(rooms, colors)
return fig
iface = gr.Interface(
fn=generate_plan_gradio,
inputs=[
gr.Slider(5,50,value=15,label="Plot Length (ft)"),
gr.Slider(5,50,value=12,label="Plot Width (ft)"),
gr.Slider(1,5,value=2,label="Number of Bedrooms"),
gr.Slider(1,3,value=1,label="Number of Bathrooms"),
gr.Slider(5,20,value=10,label="Kitchen Size (%)"),
gr.Slider(15,40,value=25,label="Living Room Size (%)"),
gr.Dropdown(["North","South","East","West"], value="North", label="Entry Direction"),
gr.Checkbox(value=True, label="Include Car Parking"),
gr.Checkbox(value=False, label="Include Garden"),
gr.Checkbox(value=False, label="Include Balcony"),
gr.Radio(["2D","3D"], value="2D", label="View Type")
],
outputs=gr.Plot(),
title="Advanced Building Plan Generator",
description="Generate interactive 2D and fully interactive 3D floor plans with Plotly."
)
iface.launch()