harrydawitch commited on
Commit
82bf9e5
·
verified ·
1 Parent(s): 0c5d176

Update app/exterior.py

Browse files
Files changed (1) hide show
  1. app/exterior.py +604 -604
app/exterior.py CHANGED
@@ -1,604 +1,604 @@
1
- import os
2
- import subprocess
3
- import time
4
-
5
- from PIL import Image
6
- from io import BytesIO
7
-
8
- import pandas as pd
9
- import numpy as np
10
-
11
- from streamlit_image_select import image_select
12
- from streamlit_image_comparison import image_comparison
13
- import streamlit as st
14
-
15
-
16
- #______________________________Add image________________________________________________________________________________________________________________________________________
17
- def app(pipeline):
18
-
19
- # Initialize session states if they don't exist
20
- if 'lock_settings' not in st.session_state:
21
- st.session_state['lock_settings'] = False
22
- if 'generating_process' not in st.session_state:
23
- st.session_state['generating_process'] = False
24
- if 'generation_complete' not in st.session_state:
25
- st.session_state['generation_complete'] = False
26
- if 'generated_image' not in st.session_state:
27
- st.session_state['generated_image'] = None
28
-
29
-
30
-
31
- with st.container(border= True):
32
- st.header("1. Upload your image", )
33
- uploaded_image = st.file_uploader(
34
- label= "# **Upload you image**",
35
- type= ['png', 'jpg', 'jpeg'],
36
- disabled= st.session_state['lock_settings'],
37
- label_visibility = 'collapsed',
38
- )
39
- if uploaded_image:
40
- st.image(uploaded_image)
41
- pil_img = Image.open(uploaded_image).convert("RGB")
42
-
43
-
44
-
45
-
46
- #_____________________________Add Design Style and Building Type________________________________________________________________________________________________________________________________________
47
-
48
-
49
- style_choices = ["Modern", "Minimalism","Art Deco",
50
- "Art Nouveau","Baroque", "Brutalist", "Classical", "Neo-Classical",
51
- "Cyberpunk", "Deconstructivism", "Futurism", "Sustainable",
52
- "Gothic", "Neo-Futurism", "Victorian"
53
- ]
54
-
55
- functionality_choices = [
56
- "Residential", "Villa", "Office", "Skyscraper",
57
- "Hotel", "School Campus", "Farmhouse", "Playground", "Park", "Apartment",
58
- "Hospital", "Kindergarten", "Church", "Container", "Bridge",
59
- "Resort", "Airport", "Factory", "Stadium", "Temple", "Tree House"
60
- ]
61
-
62
- with st.container(border= True):
63
- st.header("Choose style and functionality", divider= 'blue')
64
- style_col, function_col = st.columns([0.91, 1], border= False)
65
- with style_col:
66
- st.write("**Design Style**")
67
- styles= st.selectbox(label='Style choice',
68
- options= style_choices,
69
- placeholder= "Design style",
70
- label_visibility= 'collapsed',
71
- disabled= st.session_state['lock_settings']
72
- )
73
- with function_col:
74
- st.write("**Functionality**")
75
- functional= st.selectbox(
76
- label='Functionality choice',
77
- options= functionality_choices,
78
- placeholder= "Functionality",
79
- label_visibility= 'collapsed',
80
- disabled= st.session_state['lock_settings']
81
- )
82
-
83
-
84
- #______________________________________Add Detail________________________________________________________________________________________________________________________________________
85
-
86
- def idx2cls(mode:list):
87
- return {i: j for i, j in enumerate(mode)}
88
-
89
- if "season" not in st.session_state:
90
- st.session_state['season'] = ""
91
- if "weather" not in st.session_state:
92
- st.session_state['weather'] = ""
93
- if "day" not in st.session_state:
94
- st.session_state['day'] = ""
95
- if "landscape" not in st.session_state:
96
- st.session_state['landscape'] = ""
97
-
98
- with st.container(border= True):
99
-
100
- st.header("Add Details")
101
- @st.dialog("Choose Season")
102
- def add_season():
103
- season_photos = [r".\app\asset\images\season\Spring.jpg",
104
- r".\app\asset\images\season\Summer.jpg",
105
- r".\app\asset\images\season\Autumn.jpg",
106
- r".\app\asset\images\season\Winter.jpg"]
107
-
108
- season_caps = ["Spring", "Summer", "Autumn", "Winter"]
109
-
110
- season_selection = image_select(label= "",
111
- images = season_photos,
112
- captions= season_caps, return_value= 'index',
113
- )
114
-
115
- season_button = st.button("**Select**",
116
- use_container_width= True,
117
- type='primary')
118
-
119
- idx2class = idx2cls(season_caps)
120
-
121
- if season_button:
122
- st.session_state['season'] = idx2class[season_selection]
123
- st.rerun()
124
-
125
-
126
- @st.dialog("Choose Weather")
127
- def add_weather():
128
- weather_photos = [r".\app\asset\images\weather\Sunny.jpg", r".\app\asset\images\weather\Rainy.jpg",
129
- r".\app\asset\images\weather\Cloudy.jpg", r"E:.\app\asset\images\weather\Foggy.jpg",
130
- r".\app\asset\images\weather\Snowy.jpg", r"E:.\app\asset\images\weather\Storm.jpg"]
131
- weather_caps = ['Sunny', "Rainy", "Cloudy", "Foggy", "Snowy", "Storm"]
132
- weather_selection = image_select(label='',
133
- images= weather_photos,
134
- captions= weather_caps,
135
- return_value= 'index')
136
- weather_button = st.button("**Select**",
137
- use_container_width= True,
138
- type='primary')
139
-
140
- idx2class = idx2cls(weather_caps)
141
- if weather_button:
142
- st.session_state['weather'] = idx2class[weather_selection]
143
- st.rerun()
144
-
145
- @st.dialog("Time of Day")
146
- def add_day():
147
- day_photos = [
148
- r".\app\asset\images\time of day\sunrise.jpg",
149
- r".\app\asset\images\time of day\mid_day.jpg",
150
- r".\app\asset\images\time of day\sunset.jpg",
151
- r".\app\asset\images\time of day\night.jpg"
152
- ]
153
-
154
- day_caps = ["Sunrise", "Mid day", "Sunset", "Night"]
155
- day_selection = image_select(label='',
156
- images= day_photos,
157
- captions= day_caps,
158
- return_value= 'index')
159
- day_button = st.button("**Select**",
160
- use_container_width= True,
161
- type='primary')
162
-
163
- idx2class = idx2cls(day_caps)
164
- if day_button:
165
- st.session_state['day'] = idx2class[day_selection]
166
- st.rerun()
167
-
168
-
169
- @st.dialog("Landscape")
170
- def add_landscape():
171
- landscape_photos = [r".\app\asset\images\landscape\urban.jpg", r".\app\asset\images\landscape\surburban.jpg",
172
- r".\app\asset\images\landscape\coastal.jpg", r".\app\asset\images\landscape\grassland.jpg",
173
- r".\app\asset\images\landscape\forest.jpg", r".\app\asset\images\landscape\tropical.jpg",
174
- r".\app\asset\images\landscape\desert.jpg", r".\app\asset\images\landscape\mountain.jpg",
175
- r".\app\asset\images\landscape\swamp.jpg", r".\app\asset\images\landscape\polar.jpg"]
176
-
177
- landscape_caps = ["Urban", "Suburban", "Coastal", "Grassland", 'Forest',
178
- 'Tropical', "Desert", "Mountain", "Swamp", "Polar"]
179
-
180
- landscape_selection = image_select(label='',
181
- images= landscape_photos,
182
- captions= landscape_caps,
183
- return_value= 'index')
184
- landscape_button = st.button("**Select**",
185
- use_container_width= True,
186
- type='primary')
187
-
188
- idx2class = idx2cls(landscape_caps)
189
- if landscape_button:
190
- st.session_state['landscape'] = idx2class[landscape_selection]
191
- st.rerun()
192
-
193
-
194
- with st.popover(label= "Add Detail",
195
- use_container_width= True,
196
- disabled= st.session_state['lock_settings']):
197
-
198
- first_col, second_col = st.columns([0.5, 0.5], vertical_alignment='center')
199
- with first_col:
200
- if st.button("**Season**", use_container_width= True):
201
- add_season()
202
- if st.button("**Weather**", use_container_width= True):
203
- add_weather()
204
- with second_col:
205
- if st.button("**Time**", use_container_width= True):
206
- add_day()
207
- if st.button("**Landscape**", use_container_width= True):
208
- add_landscape()
209
-
210
- col1, col2 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
211
- col3, col4 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
212
- col5, col6 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
213
- col7, col8 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
214
-
215
- col1.markdown('<p style="font-size:18px; font-weight:bold;">Season:</p>', unsafe_allow_html=True)
216
- col2.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["season"]}</p>', unsafe_allow_html=True)
217
-
218
- col3.markdown('<p style="font-size:18px; font-weight:bold;">Time:</p>', unsafe_allow_html=True)
219
- col4.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["day"]}</p>', unsafe_allow_html=True)
220
-
221
- col5.markdown('<p style="font-size:18px; font-weight:bold;">Weather:</p>', unsafe_allow_html=True)
222
- col6.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["weather"]}</p>', unsafe_allow_html=True)
223
-
224
- col7.markdown('<p style="font-size:18px; font-weight:bold;">Landscape:</p>', unsafe_allow_html=True)
225
- col8.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["landscape"]}</p>', unsafe_allow_html=True)
226
-
227
-
228
- #________________________________Add Prompt and Negative Prompt________________________________________________________________________________________________________________________________________
229
-
230
-
231
- with st.container(border=True):
232
- st.header("Add Prompts")
233
- @st.dialog("Keywords")
234
- def add_keywords():
235
-
236
- with st.container(border= True, height= 270):
237
- st.subheader(body= "View Direction")
238
- views = st.pills(
239
- label= "Choose view",
240
- options= ['Elevation Frontal View', 'Aerial View', 'Close-Up Shot',
241
- 'Street-level View', 'Wide Shot', 'Cropped View'],
242
- selection_mode= 'multi',
243
- label_visibility= 'collapsed'
244
- )
245
- views = [i.lower() for i in views]
246
-
247
- st.subheader(body= "Space Type")
248
- spaces = st.pills(
249
- label= "Choose spaces",
250
- options= ['Residential building', 'Countryside villa', "Office building",
251
- "Office Tower", "Skyscraper", "Stadium Building", "School Building",
252
- "Hotel Building", "Factory Building", "Commercial Building"],
253
- selection_mode= 'multi',
254
- label_visibility= 'collapsed'
255
- )
256
- spaces = [i.lower() for i in spaces]
257
-
258
- st.subheader(body= "Design style")
259
- design = st.pills(
260
- label= "Design style",
261
- options= ["Modern", "Minimalism","Art Deco",
262
- "Art Nouveau","Baroque", "Brutalist", "Classical", "Neo-Classical",
263
- "Cyberpunk", "Deconstructivism", "Futurism",
264
- "Gothic", "Neo-Futurism", "Victorian"],
265
- selection_mode= 'multi',
266
- label_visibility= 'collapsed'
267
- )
268
- design = [i.lower() for i in design]
269
-
270
- st.subheader(body= "Materials")
271
- material = st.pills(
272
- label= "Materials",
273
- options= ['Glass', 'Stone', "Metal", "Steel", "Wood", "Brick", "Plastic", "Gypsum",
274
- "Concrete", "Polished Concrete", "Paint", "Stucco", "Marble", "Terracotta"],
275
- selection_mode= 'multi',
276
- label_visibility= 'collapsed'
277
- )
278
- material = [i.lower() for i in material]
279
-
280
- st.subheader(body= "Landscape")
281
- landscape = st.pills(
282
- label= "Landscape",
283
- options= ['Cityscape', 'Countryside', "Forest", "Desert", "Mountain", "Coastal",
284
- "Tropical", "Grassland", "Tundra", "Wetland"],
285
- selection_mode= 'multi',
286
- label_visibility= 'collapsed'
287
- )
288
- landscape = [i.lower() for i in landscape]
289
-
290
- st.subheader(body= "Weather")
291
- weather = st.pills(
292
- label= "Weather",
293
- options= ['Sunny', 'Night', "Rainy", "Snowy", "Cloudy Sky", "Foggy",
294
- "Dusk", "Sunset", "Sunrise"],
295
- selection_mode= 'multi',
296
- label_visibility= 'collapsed'
297
- )
298
- weather = [i.lower() for i in weather]
299
-
300
- st.subheader(body= "Lighting")
301
- lighting = st.pills(
302
- label= "lighting",
303
- options= ['Soft Lights', 'Golden Hour', "Morning Lights", "Sunbeams", "High Contrast"],
304
- selection_mode= 'multi',
305
- label_visibility= 'collapsed'
306
- )
307
- lighting = [i.lower() for i in lighting]
308
-
309
- if st.button(label= "# **Add Keywords**", type= "primary"):
310
- combined = views + spaces + design + material + landscape + weather + lighting
311
-
312
- if not combined:
313
- st.error(":red[**You haven't selected any keywords**]", icon="🚨")
314
- else:
315
- st.session_state['add_kw'] = f"{prompt} {", ".join(combined)}"
316
- st.rerun()
317
-
318
-
319
- if st.button("**+ Add Keywords**",
320
- type= 'secondary',
321
- disabled= st.session_state['lock_settings']):
322
- add_keywords()
323
-
324
- if "add_kw" not in st.session_state:
325
- st.session_state['add_kw'] = str("")
326
-
327
-
328
- prompt = st.text_area(
329
- label= "# **Prompt**",
330
- placeholder= "Describe your image",
331
- value = st.session_state['add_kw'],
332
- max_chars= 600,
333
- disabled= st.session_state['lock_settings']
334
- )
335
-
336
- neg_prompt= st.text_area(
337
- label= "# **Negative prompt (optinal)**",
338
- placeholder= "Remove unwanted element",
339
- value= '',
340
- max_chars= 200,
341
- disabled= st.session_state['lock_settings'],
342
- )
343
-
344
- #___________________________________Creative mode________________________________________________________________________________________________________________________________________
345
-
346
- if 'guidance' not in st.session_state:
347
- st.session_state['guidance'] = 7.50
348
-
349
-
350
- with st.container(border= True):
351
-
352
- st.header(body= "Creative")
353
-
354
- # Process the classifier free guidance
355
- def process_guidance(guidance, max_value):
356
- try:
357
- return float(max_value) - float(guidance)
358
- except Exception as e:
359
- return f"Invalid data type: {e}"
360
-
361
- # Function to update guidance value
362
- def change_guidance():
363
- if st.session_state['guidance'] != st.session_state['guidance_numeric']:
364
- st.session_state['guidance'] = float(st.session_state['guidance_numeric'])
365
-
366
- elif st.session_state['guidance'] != st.session_state['guidance_slider']:
367
- st.session_state['guidance'] = float(st.session_state['guidance_slider'])
368
-
369
- num_col, slider_col = st.columns([1, 3])
370
- # Number input synced with slider input
371
- with num_col:
372
- guidance_numeric = st.number_input("Guidance Scale", min_value=1.0, max_value=15.0,
373
- value=float(st.session_state['guidance']),
374
- placeholder="Input guidance scale",
375
- key="guidance_numeric",
376
- on_change=change_guidance,
377
- label_visibility='collapsed',
378
- disabled= st.session_state['lock_settings']
379
- )
380
- with slider_col:
381
- # Slider input synced with number input
382
- guidance_slider = st.slider("Guidance Scale", min_value=1.0, max_value=15.0,
383
- value=st.session_state['guidance'],
384
- step=0.1,
385
- key= 'guidance_slider',
386
- on_change= change_guidance,
387
- label_visibility='collapsed',
388
- disabled= st.session_state['lock_settings']
389
- )
390
- with st.expander("How it works?", expanded= True):
391
- st.write("""
392
- - Less guidance from the prompt. Flexible with the prompt. Great for redesign.
393
- - Follow extracly with the prompt, minor change to the prompt.
394
- """)
395
-
396
- #___________________________________________Geometry mode________________________________________________________________________________________________________________________________________
397
-
398
- if 'geometry_scale' not in st.session_state:
399
- st.session_state['geometry_scale'] = 0.5
400
-
401
- with st.container(border= True):
402
- st.header(body= "Image Strength")
403
-
404
- def change_geometry():
405
-
406
- if st.session_state['geometry_scale'] != st.session_state['geo_col1']:
407
- st.session_state['geometry_scale'] = float(st.session_state['geo_col1'])
408
-
409
- elif st.session_state['geometry_scale'] != st.session_state['geo_col2']:
410
- st.session_state['geometry_scale'] = float(st.session_state['geo_col2'])
411
-
412
- # Slider with dynamic value display to the left
413
- col1, col2 = st.columns([1, 3], vertical_alignment= 'top')
414
- with col1:
415
- value = st.number_input("Strength", 0.0, 1.0,
416
- value= float(st.session_state['geometry_scale']),
417
- label_visibility="hidden",
418
- key= "geo_col1",
419
- on_change= change_geometry,
420
- disabled = st.session_state['lock_settings']
421
- )
422
-
423
- with col2:
424
- value = st.slider("Strength", 0.0, 1.0,
425
- value= float(st.session_state['geometry_scale']),
426
- label_visibility="hidden",
427
- key= "geo_col2",
428
- on_change= change_geometry,
429
- disabled= st.session_state['lock_settings'])
430
-
431
-
432
- # Clickable link with detailed description
433
- with st.expander("How it works?", expanded= True):
434
- st.write("""
435
- - **Flexible:** Less guidance from input image. Great for redesign.
436
- - **Balanced:** Mix of creativity and precision.
437
- - **Precise:** Accurate, minor change to original input geometry. Good for rendering.
438
- """)
439
-
440
- #____________________________________________________Render mode________________________________________________________________________________________________________________________________________
441
-
442
- if "render_mode" not in st.session_state:
443
- st.session_state["render_mode"] = 30
444
-
445
- # Function to switch mode
446
- def set_render_mode():
447
- mode_mapping = {"⚡**Fast Render**": 30,
448
- "🌟 **Best Render**": 50}
449
- st.session_state["render_mode"] = mode_mapping[st.session_state['render_value']]
450
-
451
- with st.container(border= True):
452
- st.subheader("**Render Speed**")
453
- # Two buttons side by side
454
- render_mode = st.radio("Render Mode",
455
- options= ["⚡**Fast Render**", "🌟 **Best Render**"],
456
- label_visibility= 'collapsed',
457
- captions= ["**Fast Render:** Quicker, Lower quality",
458
- "**Best Render:** Slower, Best quality"],
459
- on_change= set_render_mode,
460
- disabled= st.session_state['lock_settings'],
461
- key= 'render_value'
462
- )
463
- st.write(st.session_state["render_mode"])
464
-
465
-
466
- #_______________________________________________________________________________________________________________________________________________________________________
467
- if 'lock_settings' not in st.session_state:
468
- st.session_state['lock_settings'] = False
469
-
470
- if 'start_generate' not in st.session_state:
471
- st.session_state['start_generate'] = 'secondary'
472
-
473
-
474
- def store_config():
475
- config = {}
476
-
477
- config['style_names'] = styles
478
- config['functional_names'] = functional
479
-
480
-
481
- config['posprompt_1'] = prompt
482
- config['negprompt_1'] = neg_prompt
483
-
484
- config['season'] = st.session_state['season']
485
- config['landscape'] = st.session_state['landscape']
486
- config['weather'] = st.session_state['weather']
487
- config['time_of_day'] = st.session_state['day']
488
-
489
- config['guidance'] = process_guidance(st.session_state['guidance'], 15.0)
490
- config['condition_scale'] = st.session_state['geometry_scale']
491
- config['render_speed'] = st.session_state["render_mode"]
492
-
493
- config['image'] = pil_img
494
-
495
- return config
496
-
497
- def lock_and_unlock():
498
-
499
- if not st.session_state['lock_settings']:
500
- st.session_state['lock_settings'] = True
501
-
502
- elif st.session_state['lock_settings']:
503
- st.session_state['lock_settings'] = False
504
-
505
- if 'lock_generate_bttn' not in st.session_state:
506
- st.session_state['lock_generate_bttn'] = False
507
-
508
- def reset_generation():
509
- st.session_state['generating_process'] = False
510
- st.session_state['generation_complete'] = False
511
- st.session_state['generated_image'] = None
512
-
513
- def download_image(generated_img):
514
- buffer = BytesIO()
515
-
516
- generated_img.save(buffer, format="PNG")
517
-
518
- img_bytes = buffer.getvalue()
519
-
520
- st.download_button(
521
- label= "DOWNLOAD",
522
- data= img_bytes,
523
- file_name= "archintelligent_generated.png",
524
- mime= "image/png",
525
- type= "primary",
526
- use_container_width= True,
527
- on_click= 'ignore'
528
- )
529
-
530
-
531
- def generate_image():
532
- with st.spinner("Generating your image...", show_time= True):
533
- config = store_config()
534
- pipeline.process_config(config)
535
- image = pipeline.generate()
536
-
537
- # Compare the input image and the result image
538
- st.session_state['generated_image'] = image
539
-
540
- st.session_state['generation_complete'] = True
541
- st.session_state['generating_process'] = False
542
-
543
-
544
- # download_image(image)
545
- if st.button("**Go back**"):
546
- st.session_state['generating_process'] = False
547
- st.rerun()
548
-
549
- lock_toggle = "**LOCK SETTINGS**" if not st.session_state['lock_settings'] else "**UNLOCK SETTINGS**"
550
- c1, c2 = st.columns([0.5, 1.6], gap= 'small')
551
-
552
- with c1:
553
- if st.button(
554
- label= lock_toggle,
555
- use_container_width= False,
556
- on_click= lock_and_unlock,
557
- disabled=st.session_state['generating_process'] or \
558
- st.session_state['generation_complete']):
559
-
560
- st.session_state['lock_settings'] = True
561
-
562
- with c2:
563
- generate_bttn= st.button(
564
- label= "# **GENERATE**",
565
- use_container_width= True,
566
- type= 'primary',
567
- disabled=st.session_state['generating_process'] or \
568
- st.session_state['generation_complete']
569
- )
570
-
571
- if generate_bttn and st.session_state['lock_settings']:
572
- if not uploaded_image:
573
- st.error("Please upload an image before proceeding!", icon= "❌")
574
- else:
575
- st.session_state['generating_process'] = True
576
- st.rerun()
577
-
578
- elif generate_bttn and not st.session_state['lock_settings']:
579
- st.error("Lock settings before generate image", icon="🚨")
580
-
581
- with st.container(border=True):
582
-
583
-
584
- if st.session_state['generating_process'] and not st.session_state['generation_complete']:
585
- generate_image()
586
- st.rerun() # Rerun to show the results after generation
587
-
588
- elif st.session_state['generation_complete']:
589
-
590
- st.title("Result")
591
-
592
- # Display the stored image
593
- if st.session_state['generated_image']:
594
- st.image(st.session_state['generated_image'], caption= "Generated building", use_container_width= True)
595
-
596
- left, right = st.columns([0.125, 0.8])
597
- with right:
598
- download_image(st.session_state['generated_image'])
599
- with left:
600
- # Go back button outside the generate_image function
601
- if st.button("**Go back**", on_click= reset_generation):
602
- pass # The on_click handler will reset the states
603
- else:
604
- pass
 
1
+ import os
2
+ import subprocess
3
+ import time
4
+
5
+ from PIL import Image
6
+ from io import BytesIO
7
+
8
+ import pandas as pd
9
+ import numpy as np
10
+
11
+ from streamlit_image_select import image_select
12
+ from streamlit_image_comparison import image_comparison
13
+ import streamlit as st
14
+
15
+
16
+ #______________________________Add image________________________________________________________________________________________________________________________________________
17
+ def app(pipeline):
18
+
19
+ # Initialize session states if they don't exist
20
+ if 'lock_settings' not in st.session_state:
21
+ st.session_state['lock_settings'] = False
22
+ if 'generating_process' not in st.session_state:
23
+ st.session_state['generating_process'] = False
24
+ if 'generation_complete' not in st.session_state:
25
+ st.session_state['generation_complete'] = False
26
+ if 'generated_image' not in st.session_state:
27
+ st.session_state['generated_image'] = None
28
+
29
+
30
+
31
+ with st.container(border= True):
32
+ st.header("1. Upload your image", )
33
+ uploaded_image = st.file_uploader(
34
+ label= "# **Upload you image**",
35
+ type= ['png', 'jpg', 'jpeg'],
36
+ disabled= st.session_state['lock_settings'],
37
+ label_visibility = 'collapsed',
38
+ )
39
+ if uploaded_image:
40
+ st.image(uploaded_image)
41
+ pil_img = Image.open(uploaded_image).convert("RGB")
42
+
43
+
44
+
45
+
46
+ #_____________________________Add Design Style and Building Type________________________________________________________________________________________________________________________________________
47
+
48
+
49
+ style_choices = ["Modern", "Minimalism","Art Deco",
50
+ "Art Nouveau","Baroque", "Brutalist", "Classical", "Neo-Classical",
51
+ "Cyberpunk", "Deconstructivism", "Futurism", "Sustainable",
52
+ "Gothic", "Neo-Futurism", "Victorian"
53
+ ]
54
+
55
+ functionality_choices = [
56
+ "Residential", "Villa", "Office", "Skyscraper",
57
+ "Hotel", "School Campus", "Farmhouse", "Playground", "Park", "Apartment",
58
+ "Hospital", "Kindergarten", "Church", "Container", "Bridge",
59
+ "Resort", "Airport", "Factory", "Stadium", "Temple", "Tree House"
60
+ ]
61
+
62
+ with st.container(border= True):
63
+ st.header("Choose style and functionality", divider= 'blue')
64
+ style_col, function_col = st.columns([0.91, 1], border= False)
65
+ with style_col:
66
+ st.write("**Design Style**")
67
+ styles= st.selectbox(label='Style choice',
68
+ options= style_choices,
69
+ placeholder= "Design style",
70
+ label_visibility= 'collapsed',
71
+ disabled= st.session_state['lock_settings']
72
+ )
73
+ with function_col:
74
+ st.write("**Functionality**")
75
+ functional= st.selectbox(
76
+ label='Functionality choice',
77
+ options= functionality_choices,
78
+ placeholder= "Functionality",
79
+ label_visibility= 'collapsed',
80
+ disabled= st.session_state['lock_settings']
81
+ )
82
+
83
+
84
+ #______________________________________Add Detail________________________________________________________________________________________________________________________________________
85
+
86
+ def idx2cls(mode:list):
87
+ return {i: j for i, j in enumerate(mode)}
88
+
89
+ if "season" not in st.session_state:
90
+ st.session_state['season'] = ""
91
+ if "weather" not in st.session_state:
92
+ st.session_state['weather'] = ""
93
+ if "day" not in st.session_state:
94
+ st.session_state['day'] = ""
95
+ if "landscape" not in st.session_state:
96
+ st.session_state['landscape'] = ""
97
+
98
+ with st.container(border= True):
99
+
100
+ st.header("Add Details")
101
+ @st.dialog("Choose Season")
102
+ def add_season():
103
+ season_photos = [r".\app\asset\images\season\Spring.jpg",
104
+ r".\app\asset\images\season\Summer.jpg",
105
+ r".\app\asset\images\season\Autumn.jpg",
106
+ r".\app\asset\images\season\Winter.jpg"]
107
+
108
+ season_caps = ["Spring", "Summer", "Autumn", "Winter"]
109
+
110
+ season_selection = image_select(label= "",
111
+ images = season_photos,
112
+ captions= season_caps, return_value= 'index',
113
+ )
114
+
115
+ season_button = st.button("**Select**",
116
+ use_container_width= True,
117
+ type='primary')
118
+
119
+ idx2class = idx2cls(season_caps)
120
+
121
+ if season_button:
122
+ st.session_state['season'] = idx2class[season_selection]
123
+ st.rerun()
124
+
125
+
126
+ @st.dialog("Choose Weather")
127
+ def add_weather():
128
+ weather_photos = [r".\app\asset\images\weather\Sunny.jpg", r".\app\asset\images\weather\Rainy.jpg",
129
+ r".\app\asset\images\weather\Cloudy.jpg", r"E:.\app\asset\images\weather\Foggy.jpg",
130
+ r".\app\asset\images\weather\Snowy.jpg", r"E:.\app\asset\images\weather\Storm.jpg"]
131
+ weather_caps = ['Sunny', "Rainy", "Cloudy", "Foggy", "Snowy", "Storm"]
132
+ weather_selection = image_select(label='',
133
+ images= weather_photos,
134
+ captions= weather_caps,
135
+ return_value= 'index')
136
+ weather_button = st.button("**Select**",
137
+ use_container_width= True,
138
+ type='primary')
139
+
140
+ idx2class = idx2cls(weather_caps)
141
+ if weather_button:
142
+ st.session_state['weather'] = idx2class[weather_selection]
143
+ st.rerun()
144
+
145
+ @st.dialog("Time of Day")
146
+ def add_day():
147
+ day_photos = [
148
+ r".\app\asset\images\time of day\sunrise.jpg",
149
+ r".\app\asset\images\time of day\mid_day.jpg",
150
+ r".\app\asset\images\time of day\sunset.jpg",
151
+ r".\app\asset\images\time of day\night.jpg"
152
+ ]
153
+
154
+ day_caps = ["Sunrise", "Mid day", "Sunset", "Night"]
155
+ day_selection = image_select(label='',
156
+ images= day_photos,
157
+ captions= day_caps,
158
+ return_value= 'index')
159
+ day_button = st.button("**Select**",
160
+ use_container_width= True,
161
+ type='primary')
162
+
163
+ idx2class = idx2cls(day_caps)
164
+ if day_button:
165
+ st.session_state['day'] = idx2class[day_selection]
166
+ st.rerun()
167
+
168
+
169
+ @st.dialog("Landscape")
170
+ def add_landscape():
171
+ landscape_photos = [r".\app\asset\images\landscape\urban.jpg", r".\app\asset\images\landscape\surburban.jpg",
172
+ r".\app\asset\images\landscape\coastal.jpg", r".\app\asset\images\landscape\grassland.jpg",
173
+ r".\app\asset\images\landscape\forest.jpg", r".\app\asset\images\landscape\tropical.jpg",
174
+ r".\app\asset\images\landscape\desert.jpg", r".\app\asset\images\landscape\mountain.jpg",
175
+ r".\app\asset\images\landscape\swamp.jpg", r".\app\asset\images\landscape\polar.jpg"]
176
+
177
+ landscape_caps = ["Urban", "Suburban", "Coastal", "Grassland", 'Forest',
178
+ 'Tropical', "Desert", "Mountain", "Swamp", "Polar"]
179
+
180
+ landscape_selection = image_select(label='',
181
+ images= landscape_photos,
182
+ captions= landscape_caps,
183
+ return_value= 'index')
184
+ landscape_button = st.button("**Select**",
185
+ use_container_width= True,
186
+ type='primary')
187
+
188
+ idx2class = idx2cls(landscape_caps)
189
+ if landscape_button:
190
+ st.session_state['landscape'] = idx2class[landscape_selection]
191
+ st.rerun()
192
+
193
+
194
+ with st.popover(label= "Add Detail",
195
+ use_container_width= True,
196
+ disabled= st.session_state['lock_settings']):
197
+
198
+ first_col, second_col = st.columns([0.5, 0.5], vertical_alignment='center')
199
+ with first_col:
200
+ if st.button("**Season**", use_container_width= True):
201
+ add_season()
202
+ if st.button("**Weather**", use_container_width= True):
203
+ add_weather()
204
+ with second_col:
205
+ if st.button("**Time**", use_container_width= True):
206
+ add_day()
207
+ if st.button("**Landscape**", use_container_width= True):
208
+ add_landscape()
209
+
210
+ col1, col2 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
211
+ col3, col4 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
212
+ col5, col6 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
213
+ col7, col8 = st.columns([0.5, 0.8], vertical_alignment= "bottom")
214
+
215
+ col1.markdown('<p style="font-size:18px; font-weight:bold;">Season:</p>', unsafe_allow_html=True)
216
+ col2.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["season"]}</p>', unsafe_allow_html=True)
217
+
218
+ col3.markdown('<p style="font-size:18px; font-weight:bold;">Time:</p>', unsafe_allow_html=True)
219
+ col4.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["day"]}</p>', unsafe_allow_html=True)
220
+
221
+ col5.markdown('<p style="font-size:18px; font-weight:bold;">Weather:</p>', unsafe_allow_html=True)
222
+ col6.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["weather"]}</p>', unsafe_allow_html=True)
223
+
224
+ col7.markdown('<p style="font-size:18px; font-weight:bold;">Landscape:</p>', unsafe_allow_html=True)
225
+ col8.markdown(f'<p style="font-size:16px; font-weight:normal;">{st.session_state["landscape"]}</p>', unsafe_allow_html=True)
226
+
227
+
228
+ #________________________________Add Prompt and Negative Prompt________________________________________________________________________________________________________________________________________
229
+
230
+
231
+ with st.container(border=True):
232
+ st.header("Add Prompts")
233
+ @st.dialog("Keywords")
234
+ def add_keywords():
235
+
236
+ with st.container(border= True, height= 270):
237
+ st.subheader(body= "View Direction")
238
+ views = st.pills(
239
+ label= "Choose view",
240
+ options= ['Elevation Frontal View', 'Aerial View', 'Close-Up Shot',
241
+ 'Street-level View', 'Wide Shot', 'Cropped View'],
242
+ selection_mode= 'multi',
243
+ label_visibility= 'collapsed'
244
+ )
245
+ views = [i.lower() for i in views]
246
+
247
+ st.subheader(body= "Space Type")
248
+ spaces = st.pills(
249
+ label= "Choose spaces",
250
+ options= ['Residential building', 'Countryside villa', "Office building",
251
+ "Office Tower", "Skyscraper", "Stadium Building", "School Building",
252
+ "Hotel Building", "Factory Building", "Commercial Building"],
253
+ selection_mode= 'multi',
254
+ label_visibility= 'collapsed'
255
+ )
256
+ spaces = [i.lower() for i in spaces]
257
+
258
+ st.subheader(body= "Design style")
259
+ design = st.pills(
260
+ label= "Design style",
261
+ options= ["Modern", "Minimalism","Art Deco",
262
+ "Art Nouveau","Baroque", "Brutalist", "Classical", "Neo-Classical",
263
+ "Cyberpunk", "Deconstructivism", "Futurism",
264
+ "Gothic", "Neo-Futurism", "Victorian"],
265
+ selection_mode= 'multi',
266
+ label_visibility= 'collapsed'
267
+ )
268
+ design = [i.lower() for i in design]
269
+
270
+ st.subheader(body= "Materials")
271
+ material = st.pills(
272
+ label= "Materials",
273
+ options= ['Glass', 'Stone', "Metal", "Steel", "Wood", "Brick", "Plastic", "Gypsum",
274
+ "Concrete", "Polished Concrete", "Paint", "Stucco", "Marble", "Terracotta"],
275
+ selection_mode= 'multi',
276
+ label_visibility= 'collapsed'
277
+ )
278
+ material = [i.lower() for i in material]
279
+
280
+ st.subheader(body= "Landscape")
281
+ landscape = st.pills(
282
+ label= "Landscape",
283
+ options= ['Cityscape', 'Countryside', "Forest", "Desert", "Mountain", "Coastal",
284
+ "Tropical", "Grassland", "Tundra", "Wetland"],
285
+ selection_mode= 'multi',
286
+ label_visibility= 'collapsed'
287
+ )
288
+ landscape = [i.lower() for i in landscape]
289
+
290
+ st.subheader(body= "Weather")
291
+ weather = st.pills(
292
+ label= "Weather",
293
+ options= ['Sunny', 'Night', "Rainy", "Snowy", "Cloudy Sky", "Foggy",
294
+ "Dusk", "Sunset", "Sunrise"],
295
+ selection_mode= 'multi',
296
+ label_visibility= 'collapsed'
297
+ )
298
+ weather = [i.lower() for i in weather]
299
+
300
+ st.subheader(body= "Lighting")
301
+ lighting = st.pills(
302
+ label= "lighting",
303
+ options= ['Soft Lights', 'Golden Hour', "Morning Lights", "Sunbeams", "High Contrast"],
304
+ selection_mode= 'multi',
305
+ label_visibility= 'collapsed'
306
+ )
307
+ lighting = [i.lower() for i in lighting]
308
+
309
+ if st.button(label= "# **Add Keywords**", type= "primary"):
310
+ combined = views + spaces + design + material + landscape + weather + lighting
311
+
312
+ if not combined:
313
+ st.error(":red[**You haven't selected any keywords**]", icon="🚨")
314
+ else:
315
+ st.session_state['add_kw'] = f"{prompt} {', '.join(combined)}"
316
+ st.rerun()
317
+
318
+
319
+ if st.button("**+ Add Keywords**",
320
+ type= 'secondary',
321
+ disabled= st.session_state['lock_settings']):
322
+ add_keywords()
323
+
324
+ if "add_kw" not in st.session_state:
325
+ st.session_state['add_kw'] = str("")
326
+
327
+
328
+ prompt = st.text_area(
329
+ label= "# **Prompt**",
330
+ placeholder= "Describe your image",
331
+ value = st.session_state['add_kw'],
332
+ max_chars= 600,
333
+ disabled= st.session_state['lock_settings']
334
+ )
335
+
336
+ neg_prompt= st.text_area(
337
+ label= "# **Negative prompt (optinal)**",
338
+ placeholder= "Remove unwanted element",
339
+ value= '',
340
+ max_chars= 200,
341
+ disabled= st.session_state['lock_settings'],
342
+ )
343
+
344
+ #___________________________________Creative mode________________________________________________________________________________________________________________________________________
345
+
346
+ if 'guidance' not in st.session_state:
347
+ st.session_state['guidance'] = 7.50
348
+
349
+
350
+ with st.container(border= True):
351
+
352
+ st.header(body= "Creative")
353
+
354
+ # Process the classifier free guidance
355
+ def process_guidance(guidance, max_value):
356
+ try:
357
+ return float(max_value) - float(guidance)
358
+ except Exception as e:
359
+ return f"Invalid data type: {e}"
360
+
361
+ # Function to update guidance value
362
+ def change_guidance():
363
+ if st.session_state['guidance'] != st.session_state['guidance_numeric']:
364
+ st.session_state['guidance'] = float(st.session_state['guidance_numeric'])
365
+
366
+ elif st.session_state['guidance'] != st.session_state['guidance_slider']:
367
+ st.session_state['guidance'] = float(st.session_state['guidance_slider'])
368
+
369
+ num_col, slider_col = st.columns([1, 3])
370
+ # Number input synced with slider input
371
+ with num_col:
372
+ guidance_numeric = st.number_input("Guidance Scale", min_value=1.0, max_value=15.0,
373
+ value=float(st.session_state['guidance']),
374
+ placeholder="Input guidance scale",
375
+ key="guidance_numeric",
376
+ on_change=change_guidance,
377
+ label_visibility='collapsed',
378
+ disabled= st.session_state['lock_settings']
379
+ )
380
+ with slider_col:
381
+ # Slider input synced with number input
382
+ guidance_slider = st.slider("Guidance Scale", min_value=1.0, max_value=15.0,
383
+ value=st.session_state['guidance'],
384
+ step=0.1,
385
+ key= 'guidance_slider',
386
+ on_change= change_guidance,
387
+ label_visibility='collapsed',
388
+ disabled= st.session_state['lock_settings']
389
+ )
390
+ with st.expander("How it works?", expanded= True):
391
+ st.write("""
392
+ - Less guidance from the prompt. Flexible with the prompt. Great for redesign.
393
+ - Follow extracly with the prompt, minor change to the prompt.
394
+ """)
395
+
396
+ #___________________________________________Geometry mode________________________________________________________________________________________________________________________________________
397
+
398
+ if 'geometry_scale' not in st.session_state:
399
+ st.session_state['geometry_scale'] = 0.5
400
+
401
+ with st.container(border= True):
402
+ st.header(body= "Image Strength")
403
+
404
+ def change_geometry():
405
+
406
+ if st.session_state['geometry_scale'] != st.session_state['geo_col1']:
407
+ st.session_state['geometry_scale'] = float(st.session_state['geo_col1'])
408
+
409
+ elif st.session_state['geometry_scale'] != st.session_state['geo_col2']:
410
+ st.session_state['geometry_scale'] = float(st.session_state['geo_col2'])
411
+
412
+ # Slider with dynamic value display to the left
413
+ col1, col2 = st.columns([1, 3], vertical_alignment= 'top')
414
+ with col1:
415
+ value = st.number_input("Strength", 0.0, 1.0,
416
+ value= float(st.session_state['geometry_scale']),
417
+ label_visibility="hidden",
418
+ key= "geo_col1",
419
+ on_change= change_geometry,
420
+ disabled = st.session_state['lock_settings']
421
+ )
422
+
423
+ with col2:
424
+ value = st.slider("Strength", 0.0, 1.0,
425
+ value= float(st.session_state['geometry_scale']),
426
+ label_visibility="hidden",
427
+ key= "geo_col2",
428
+ on_change= change_geometry,
429
+ disabled= st.session_state['lock_settings'])
430
+
431
+
432
+ # Clickable link with detailed description
433
+ with st.expander("How it works?", expanded= True):
434
+ st.write("""
435
+ - **Flexible:** Less guidance from input image. Great for redesign.
436
+ - **Balanced:** Mix of creativity and precision.
437
+ - **Precise:** Accurate, minor change to original input geometry. Good for rendering.
438
+ """)
439
+
440
+ #____________________________________________________Render mode________________________________________________________________________________________________________________________________________
441
+
442
+ if "render_mode" not in st.session_state:
443
+ st.session_state["render_mode"] = 30
444
+
445
+ # Function to switch mode
446
+ def set_render_mode():
447
+ mode_mapping = {"⚡**Fast Render**": 30,
448
+ "🌟 **Best Render**": 50}
449
+ st.session_state["render_mode"] = mode_mapping[st.session_state['render_value']]
450
+
451
+ with st.container(border= True):
452
+ st.subheader("**Render Speed**")
453
+ # Two buttons side by side
454
+ render_mode = st.radio("Render Mode",
455
+ options= ["⚡**Fast Render**", "🌟 **Best Render**"],
456
+ label_visibility= 'collapsed',
457
+ captions= ["**Fast Render:** Quicker, Lower quality",
458
+ "**Best Render:** Slower, Best quality"],
459
+ on_change= set_render_mode,
460
+ disabled= st.session_state['lock_settings'],
461
+ key= 'render_value'
462
+ )
463
+ st.write(st.session_state["render_mode"])
464
+
465
+
466
+ #_______________________________________________________________________________________________________________________________________________________________________
467
+ if 'lock_settings' not in st.session_state:
468
+ st.session_state['lock_settings'] = False
469
+
470
+ if 'start_generate' not in st.session_state:
471
+ st.session_state['start_generate'] = 'secondary'
472
+
473
+
474
+ def store_config():
475
+ config = {}
476
+
477
+ config['style_names'] = styles
478
+ config['functional_names'] = functional
479
+
480
+
481
+ config['posprompt_1'] = prompt
482
+ config['negprompt_1'] = neg_prompt
483
+
484
+ config['season'] = st.session_state['season']
485
+ config['landscape'] = st.session_state['landscape']
486
+ config['weather'] = st.session_state['weather']
487
+ config['time_of_day'] = st.session_state['day']
488
+
489
+ config['guidance'] = process_guidance(st.session_state['guidance'], 15.0)
490
+ config['condition_scale'] = st.session_state['geometry_scale']
491
+ config['render_speed'] = st.session_state["render_mode"]
492
+
493
+ config['image'] = pil_img
494
+
495
+ return config
496
+
497
+ def lock_and_unlock():
498
+
499
+ if not st.session_state['lock_settings']:
500
+ st.session_state['lock_settings'] = True
501
+
502
+ elif st.session_state['lock_settings']:
503
+ st.session_state['lock_settings'] = False
504
+
505
+ if 'lock_generate_bttn' not in st.session_state:
506
+ st.session_state['lock_generate_bttn'] = False
507
+
508
+ def reset_generation():
509
+ st.session_state['generating_process'] = False
510
+ st.session_state['generation_complete'] = False
511
+ st.session_state['generated_image'] = None
512
+
513
+ def download_image(generated_img):
514
+ buffer = BytesIO()
515
+
516
+ generated_img.save(buffer, format="PNG")
517
+
518
+ img_bytes = buffer.getvalue()
519
+
520
+ st.download_button(
521
+ label= "DOWNLOAD",
522
+ data= img_bytes,
523
+ file_name= "archintelligent_generated.png",
524
+ mime= "image/png",
525
+ type= "primary",
526
+ use_container_width= True,
527
+ on_click= 'ignore'
528
+ )
529
+
530
+
531
+ def generate_image():
532
+ with st.spinner("Generating your image...", show_time= True):
533
+ config = store_config()
534
+ pipeline.process_config(config)
535
+ image = pipeline.generate()
536
+
537
+ # Compare the input image and the result image
538
+ st.session_state['generated_image'] = image
539
+
540
+ st.session_state['generation_complete'] = True
541
+ st.session_state['generating_process'] = False
542
+
543
+
544
+ # download_image(image)
545
+ if st.button("**Go back**"):
546
+ st.session_state['generating_process'] = False
547
+ st.rerun()
548
+
549
+ lock_toggle = "**LOCK SETTINGS**" if not st.session_state['lock_settings'] else "**UNLOCK SETTINGS**"
550
+ c1, c2 = st.columns([0.5, 1.6], gap= 'small')
551
+
552
+ with c1:
553
+ if st.button(
554
+ label= lock_toggle,
555
+ use_container_width= False,
556
+ on_click= lock_and_unlock,
557
+ disabled=st.session_state['generating_process'] or \
558
+ st.session_state['generation_complete']):
559
+
560
+ st.session_state['lock_settings'] = True
561
+
562
+ with c2:
563
+ generate_bttn= st.button(
564
+ label= "# **GENERATE**",
565
+ use_container_width= True,
566
+ type= 'primary',
567
+ disabled=st.session_state['generating_process'] or \
568
+ st.session_state['generation_complete']
569
+ )
570
+
571
+ if generate_bttn and st.session_state['lock_settings']:
572
+ if not uploaded_image:
573
+ st.error("Please upload an image before proceeding!", icon= "❌")
574
+ else:
575
+ st.session_state['generating_process'] = True
576
+ st.rerun()
577
+
578
+ elif generate_bttn and not st.session_state['lock_settings']:
579
+ st.error("Lock settings before generate image", icon="🚨")
580
+
581
+ with st.container(border=True):
582
+
583
+
584
+ if st.session_state['generating_process'] and not st.session_state['generation_complete']:
585
+ generate_image()
586
+ st.rerun() # Rerun to show the results after generation
587
+
588
+ elif st.session_state['generation_complete']:
589
+
590
+ st.title("Result")
591
+
592
+ # Display the stored image
593
+ if st.session_state['generated_image']:
594
+ st.image(st.session_state['generated_image'], caption= "Generated building", use_container_width= True)
595
+
596
+ left, right = st.columns([0.125, 0.8])
597
+ with right:
598
+ download_image(st.session_state['generated_image'])
599
+ with left:
600
+ # Go back button outside the generate_image function
601
+ if st.button("**Go back**", on_click= reset_generation):
602
+ pass # The on_click handler will reset the states
603
+ else:
604
+ pass