|
import gradio as gr |
|
import matplotlib.pyplot as plt |
|
import matplotlib.patches as patches |
|
import numpy as np |
|
import plotly.graph_objects as go |
|
|
|
|
|
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 |
|
|
|
|
|
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) |
|
|
|
|
|
def draw_floor_plan_3d_plotly(rooms, colors): |
|
fig = go.Figure() |
|
room_height = 3 |
|
|
|
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') |
|
|
|
|
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
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() |
|
|