Update
Browse files
app.py
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import matplotlib.pyplot as plt
|
3 |
+
import matplotlib.patches as patches
|
4 |
+
import numpy as np
|
5 |
+
import plotly.graph_objects as go
|
6 |
+
|
7 |
+
# ---------------- Room creation ----------------
|
8 |
+
def create_room(x, y, width, height, room_type, label=None):
|
9 |
+
room = {
|
10 |
+
'x': x,
|
11 |
+
'y': y,
|
12 |
+
'width': width,
|
13 |
+
'height': height,
|
14 |
+
'type': room_type,
|
15 |
+
'label': label or room_type
|
16 |
+
}
|
17 |
+
return room
|
18 |
+
|
19 |
+
# ---------------- 2D Drawing ----------------
|
20 |
+
def draw_room_2d(ax, room, colors):
|
21 |
+
rect = patches.Rectangle((room['x'], room['y']), room['width'], room['height'],
|
22 |
+
linewidth=1, edgecolor='black', facecolor=colors.get(room['type'], 'white'),
|
23 |
+
alpha=0.7)
|
24 |
+
ax.add_patch(rect)
|
25 |
+
ax.text(room['x'] + room['width']/2, room['y'] + room['height']/2,
|
26 |
+
room['label'], ha='center', va='center', fontsize=9)
|
27 |
+
|
28 |
+
# ---------------- 3D Plotly Drawing ----------------
|
29 |
+
def draw_floor_plan_3d_plotly(rooms, colors):
|
30 |
+
fig = go.Figure()
|
31 |
+
room_height = 3 # default height
|
32 |
+
|
33 |
+
for room in rooms:
|
34 |
+
x0, y0 = room['x'], room['y']
|
35 |
+
dx, dy, dz = room['width'], room['height'], room_height
|
36 |
+
color = colors.get(room['type'], 'lightgray')
|
37 |
+
|
38 |
+
# Draw 3D box using mesh3d
|
39 |
+
fig.add_trace(go.Mesh3d(
|
40 |
+
x=[x0, x0+dx, x0+dx, x0, x0, x0+dx, x0+dx, x0],
|
41 |
+
y=[y0, y0, y0+dy, y0+dy, y0, y0, y0+dy, y0+dy],
|
42 |
+
z=[0, 0, 0, 0, dz, dz, dz, dz],
|
43 |
+
color=color,
|
44 |
+
opacity=0.7,
|
45 |
+
flatshading=True,
|
46 |
+
name=room['label']
|
47 |
+
))
|
48 |
+
fig.update_layout(scene=dict(
|
49 |
+
xaxis_title='Length',
|
50 |
+
yaxis_title='Width',
|
51 |
+
zaxis_title='Height',
|
52 |
+
aspectmode='data'
|
53 |
+
))
|
54 |
+
return fig
|
55 |
+
|
56 |
+
# ---------------- Floor plan generation ----------------
|
57 |
+
def generate_building_plan(length, width, bedrooms, bathrooms, kitchen_size, living_room_size,
|
58 |
+
entry_direction, car_parking, include_garden, include_balcony):
|
59 |
+
scale_factor = min(length, width) / 10
|
60 |
+
colors = {
|
61 |
+
'bedroom': 'lightblue',
|
62 |
+
'bathroom': 'lightpink',
|
63 |
+
'kitchen': 'lightyellow',
|
64 |
+
'living': 'lightgreen',
|
65 |
+
'hallway': 'whitesmoke',
|
66 |
+
'parking': 'lightgray',
|
67 |
+
'garden': 'palegreen',
|
68 |
+
'balcony': 'lavender'
|
69 |
+
}
|
70 |
+
|
71 |
+
rooms = []
|
72 |
+
center_x, center_y = length/2, width/2
|
73 |
+
|
74 |
+
# Horizontal layout demo
|
75 |
+
living_area = length * width * living_room_size / 100
|
76 |
+
living_width = min(width * 0.6, np.sqrt(living_area * 1.5))
|
77 |
+
living_length = living_area / living_width
|
78 |
+
kitchen_area = length * width * kitchen_size / 100
|
79 |
+
kitchen_width = min(width * 0.4, np.sqrt(kitchen_area))
|
80 |
+
kitchen_length = kitchen_area / kitchen_width
|
81 |
+
bedroom_total_area = (length*width - living_area - kitchen_area) * 0.7
|
82 |
+
bedroom_area = bedroom_total_area / bedrooms
|
83 |
+
bedroom_width = np.sqrt(bedroom_area)
|
84 |
+
bedroom_length = bedroom_area / bedroom_width
|
85 |
+
|
86 |
+
current_x = 0
|
87 |
+
rooms.append(create_room(current_x, 0, living_length, living_width, 'living', 'Living Room'))
|
88 |
+
current_x += living_length
|
89 |
+
rooms.append(create_room(current_x, 0, kitchen_length, kitchen_width, 'kitchen', 'Kitchen'))
|
90 |
+
current_x += kitchen_length
|
91 |
+
for i in range(bedrooms):
|
92 |
+
rooms.append(create_room(current_x, 0, bedroom_length, bedroom_width, 'bedroom', f'Bedroom {i+1}'))
|
93 |
+
current_x += bedroom_length
|
94 |
+
if include_garden:
|
95 |
+
rooms.append(create_room(0, 0, scale_factor*4, scale_factor*4, 'garden', 'Garden'))
|
96 |
+
if include_balcony:
|
97 |
+
rooms.append(create_room(center_x - scale_factor*2.5, 0, scale_factor*5, scale_factor*2, 'balcony', 'Balcony'))
|
98 |
+
|
99 |
+
return rooms, colors
|
100 |
+
|
101 |
+
# ---------------- Gradio interface ----------------
|
102 |
+
def generate_plan_gradio(length, width, bedrooms, bathrooms, kitchen_size, living_room_size,
|
103 |
+
entry_direction, car_parking, include_garden, include_balcony, view_type):
|
104 |
+
rooms, colors = generate_building_plan(length, width, bedrooms, bathrooms, kitchen_size, living_room_size,
|
105 |
+
entry_direction, car_parking, include_garden, include_balcony)
|
106 |
+
|
107 |
+
if view_type == "2D":
|
108 |
+
fig, ax = plt.subplots(figsize=(10,8))
|
109 |
+
ax.set_xlim(-1, length+1)
|
110 |
+
ax.set_ylim(-1, width+1)
|
111 |
+
ax.set_aspect('equal')
|
112 |
+
ax.set_xticks([])
|
113 |
+
ax.set_yticks([])
|
114 |
+
for room in rooms:
|
115 |
+
draw_room_2d(ax, room, colors)
|
116 |
+
fig.tight_layout()
|
117 |
+
return fig
|
118 |
+
else:
|
119 |
+
fig = draw_floor_plan_3d_plotly(rooms, colors)
|
120 |
+
return fig
|
121 |
+
|
122 |
+
iface = gr.Interface(
|
123 |
+
fn=generate_plan_gradio,
|
124 |
+
inputs=[
|
125 |
+
gr.Slider(5,50,value=15,label="Plot Length (ft)"),
|
126 |
+
gr.Slider(5,50,value=12,label="Plot Width (ft)"),
|
127 |
+
gr.Slider(1,5,value=2,label="Number of Bedrooms"),
|
128 |
+
gr.Slider(1,3,value=1,label="Number of Bathrooms"),
|
129 |
+
gr.Slider(5,20,value=10,label="Kitchen Size (%)"),
|
130 |
+
gr.Slider(15,40,value=25,label="Living Room Size (%)"),
|
131 |
+
gr.Dropdown(["North","South","East","West"], value="North", label="Entry Direction"),
|
132 |
+
gr.Checkbox(value=True, label="Include Car Parking"),
|
133 |
+
gr.Checkbox(value=False, label="Include Garden"),
|
134 |
+
gr.Checkbox(value=False, label="Include Balcony"),
|
135 |
+
gr.Radio(["2D","3D"], value="2D", label="View Type")
|
136 |
+
],
|
137 |
+
outputs=gr.Plot(),
|
138 |
+
title="Advanced Building Plan Generator",
|
139 |
+
description="Generate interactive 2D and fully interactive 3D floor plans with Plotly."
|
140 |
+
)
|
141 |
+
|
142 |
+
iface.launch()
|