File size: 5,225 Bytes
75cd7d1
 
 
006dc33
75cd7d1
 
006dc33
75cd7d1
 
 
 
 
 
 
 
 
006dc33
 
 
75cd7d1
006dc33
75cd7d1
006dc33
 
 
 
75cd7d1
006dc33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8ec5df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import streamlit as st
from openai import OpenAI

# Initialize OpenAI client using Hugging Face secrets
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])

# Sample architectural prompt
sample_prompt = (
    "A highly detailed, realistic architectural floor plan for a modern tiny home. "
    "The design features an open-concept layout with a multi-functional living space "
    "that combines a compact living area, dining space, and efficient kitchen with smart storage. "
    "A cozy loft bedroom is accessible via a sleek staircase or ladder. The minimalist bathroom "
    "includes a shower. Emphasize large windows with natural light, clean lines, and neutral tones "
    "with subtle accents. Annotate key dimensions and furniture placements. Professional architectural rendering style."
)

# Session state for user prompt
if "prompt" not in st.session_state:
    st.session_state.prompt = ""

st.title("🏠 OpenAI Image Generator: Tiny Home Floor Plan")

# Prompt input area
st.text_area("Enter your prompt:", key="prompt_input", value=st.session_state.prompt, height=200)

# Button to insert sample
if st.button("Insert Sample Prompt"):
    st.session_state.prompt = sample_prompt
    st.rerun()

# Sync prompt state
st.session_state.prompt = st.session_state.prompt_input

# Display the current prompt as read-only
st.text_area("Current prompt being used:", st.session_state.prompt, height=200, disabled=True)

# Generate image
if st.button("Generate Image"):
    if st.session_state.prompt.strip():
        with st.spinner("Generating image..."):
            try:
                response = client.images.generate(
                    model="dall-e-3",
                    prompt=st.session_state.prompt,
                    size="1024x1024",
                    quality="standard",
                    n=1
                )
                image_url = response.data[0].url
                st.image(image_url, caption="Generated Image", use_column_width=True)
                st.markdown(f"[Download Image]({image_url})", unsafe_allow_html=True)
            except Exception as e:
                st.error(f"Error: {e}")
    else:
        st.warning("Please enter a valid prompt.")
        # === Agent 3: Material Explorer ===
import json

st.header("Agent 3: Material Explorer")

# Optionally use DALL·E prompt if needed (or use layout summary from Agent 1/2)
your_dalle_prompt = st.session_state.get("requirements_summary", "")

if st.button("Get Suggested Materials"):
    with st.spinner("Using Gemini to extract materials..."):

        material_prompt = f"""
        From the following blueprint prompt and layout concept:

        Blueprint Prompt:
        \"\"\"{your_dalle_prompt}\"\"\"

        Return 5 key building materials implied by the layout, even if not explicitly listed.

        Respond ONLY with a raw JSON list like:
        ["Concrete slab foundation", "Metal roofing", "Plywood sheathing", "Double-pane windows", "Insulation"]
        """

        model = genai.GenerativeModel("gemini-1.5-pro")
        response = model.generate_content(material_prompt)
        raw = response.text.strip()

        import re
        cleaned = re.sub(r"```json|```", "", raw).strip()

        try:
            materials = json.loads(cleaned)
            st.session_state.materials = materials
            st.success("✅ Materials extracted.")
        except Exception as e:
            st.error("❌ Could not parse Gemini response.")
            st.code(raw)
            materials = []
# Hardcoded URL map
material_links = {
    "Engineered wood flooring": "https://www.homedepot.ca/product/home-decorators-collection-laminate-flooring-castle-oak/1001624267",
    "Laminate countertops": "https://www.homedepot.ca/product/hampton-bay-premium-laminate-countertop-butchers-block/1001185104",
    "Tile (bathroom)": "https://www.homedepot.ca/product/enigma-12-inch-x-24-inch-glazed-porcelain-tile-aria-grey/1001066513",
    "Painted drywall": "https://www.homedepot.ca/product/certainteed-1-2-inch-x-4-ft-x-8-ft-drywall/1000116648",
    "Wood framing (stud walls)": "https://www.homedepot.ca/product/2-inch-x-4-inch-x-8-ft-construction-grade-lumber/1000115194",
    "Spray foam insulation": "https://www.homedepot.ca/product/great-stuff-big-gap-filler-insulating-foam-sealant-12-oz/1000110899",
    "Triple-glazed windows": "https://www.homedepot.ca/product/american-craftsman-60-inch-x-60-inch-double-pane-double-hung-vinyl-window/1001202871",
    "Metal roofing": "https://www.homedepot.ca/product/ondura-36-inch-x-79-inch-black-roof-panel/1000167679",
    "Solar panel kit": "https://www.homedepot.ca/product/nature-power-110-watt-solar-panel-kit-with-inverter-and-charging-controller/1001037002",
    "Mini wood stove": "https://www.homedepot.ca/product/englander-1-200-sq-ft-wood-burning-stove/1000829230"
}

# Show material links
if "materials" in st.session_state:
    st.subheader("🔗 Explore Real-World Materials")

    for mat in st.session_state.materials:
        url = material_links.get(mat)
        if url:
            st.markdown(f"✅ **{mat}**: [View on Home Depot]({url})", unsafe_allow_html=True)
        else:
            st.markdown(f"🟡 **{mat}**: _(no link available)_")