File size: 5,519 Bytes
dde6b93
d26d55f
dde6b93
d26d55f
dde6b93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d26d55f
dde6b93
 
 
 
 
 
 
 
 
 
 
 
d26d55f
 
 
dde6b93
 
d26d55f
dde6b93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d26d55f
 
dde6b93
d26d55f
 
dde6b93
 
 
 
d26d55f
dde6b93
 
 
 
d26d55f
dde6b93
 
 
d26d55f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dde6b93
 
 
 
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import gradio as gr
import json
from devcore.parser import parse_description
from devcore.builder import description_to_blueprint, blueprint_to_json

EXAMPLE_PROMPTS = [
    "2000 sq ft ranch house with 3 bedrooms and 2 baths",
    "modern 2-story house 30x40 with 4 bedrooms 3 bathrooms and a garage",
    "small cabin 800 sq ft with 1 bedroom and a loft",
    "victorian 3500 sq ft 5 bedroom 3 bath with office and library",
    "colonial with 4 bedrooms and 2.5 baths",
    "my house is 50 feet wide and 60 feet long with 3 bedrooms",
    "30 feet by 50 feet modern house with 4 bedrooms and a deck",
]


def build_blueprint(description):
    if not description or not description.strip():
        html = _render_empty("Enter a description of the building you want to visualize.")
        return html, "No description provided.", "", ""
    try:
        html = description_to_blueprint(description)
        data = parse_description(description)
        s = data["structure"]
        f = data["features"]
        summary = data["summary"]
        details = (
            f"🏠 **{s['style'].title()}** · {f['stories']} story · "
            f"{s['width']}ft × {s['depth']}ft · ~{s['sqft']} sqft\n"
            f"🛏️ {f['bedrooms']} bed · 🚿 {f['bathrooms']} bath · "
            f"{'🚗 Garage' if f['garage'] else 'No garage'}"
        )
        roof = s.get("roof_style", "gable")
        extras = f"🏗️ {roof} roof · 🖱️ Orbit/Pan/Tour modes · 📥 Export JSON"
        return html, summary, details, extras
    except Exception as e:
        html = _render_empty(f"Error: {e}")
        return html, f"Failed to build: {e}", "", ""


def _render_empty(message):
    return f"""<!DOCTYPE html><html><head><style>
* {{ margin:0; padding:0; box-sizing:border-box; }}
body {{ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  background:#0a0a1a; color:#888; display:flex; align-items:center;
  justify-content:center; height:100vh; }}
.msg {{ text-align:center; padding:40px; }}
.msg h2 {{ color:#6666aa; margin-bottom:12px; }}
.msg p {{ color:#666; font-size:14px; line-height:1.6; }}
</style></head><body>
<div class="msg"><h2>🏗️ 3D Blueprint Builder</h2>
<p>{message}</p>
<p style="margin-top:20px;font-size:12px;color:#444;">Type a description above and click Build</p></div>
</body></html>"""


with gr.Blocks(title="Vitalis DevCore — 3D Blueprint Builder", theme=gr.themes.Soft(primary_hue="purple", secondary_hue="indigo")) as demo:
    gr.HTML("""
    <div style="text-align:center;padding:20px;background:linear-gradient(135deg,#1a0a3e,#312e81);
      border-radius:12px;margin-bottom:12px;border:1px solid #7c3aed44;">
      <h1 style="color:#a78bfa;margin:0;font-size:1.8em;">Vitalis DevCore — 3D Blueprint Builder</h1>
      <p style="color:#c4b5fd;margin:4px 0 0;font-size:0.9em;">
        Describe a building in natural language — see it rendered as an interactive 3D model
      </p>
    </div>
    """)

    with gr.Row():
        with gr.Column(scale=3):
            prompt = gr.Textbox(
                label="Describe your building",
                placeholder="e.g., 2000 sq ft ranch house with 3 bedrooms and 2 baths",
                lines=2,
            )
        with gr.Column(scale=1):
            build_btn = gr.Button("🏗️ Build Blueprint", variant="primary", size="lg", scale=1)

    with gr.Row():
        summary_display = gr.Markdown(label="Summary", value="Enter a description and click Build.")

    with gr.Row():
        with gr.Column(scale=2):
            model_display = gr.HTML(label="3D Model")

    with gr.Accordion("Example prompts", open=True):
        example_btns = []
        for ex in EXAMPLE_PROMPTS:
            btn = gr.Button(ex, size="sm")
            btn.click(fn=lambda e=ex: e, outputs=prompt)
            example_btns.append(btn)

    with gr.Accordion("Blueprint Details", open=False):
        details_display = gr.Markdown(label="Details")

    extras_display = gr.Markdown(label="Features")

    def on_build(desc):
        html, summary, details, extras = build_blueprint(desc)
        return html, summary, details, extras

    build_btn.click(
        fn=on_build,
        inputs=[prompt],
        outputs=[model_display, summary_display, details_display, extras_display],
    )
    prompt.submit(
        fn=on_build,
        inputs=[prompt],
        outputs=[model_display, summary_display, details_display, extras_display],
    )

    gr.Markdown("---")
    with gr.Row():
        gr.Markdown("""
        ### View Controls
        - **Orbit** — Drag to rotate, scroll to zoom
        - **Pan** — Drag to move view
        - **Tour** — Auto- camera walkthrough of rooms
        - **Export** — Download blueprint as JSON

        *Style-specific roofs: gable, hip, flat, steep-gable · Measurements shown on each room · All rendering in-browser*
        """)
    with gr.Accordion("JSON Blueprint Data (read-only)", open=False):
        json_display = gr.Markdown("Build a blueprint first.")
        def show_json(desc):
            if not desc or not desc.strip():
                return "Enter a description."
            try:
                return "```json\n" + blueprint_to_json(desc) + "\n```"
            except:
                return "Invalid description."
        prompt.change(show_json, inputs=[prompt], outputs=json_display)

    gr.Markdown("*Vitalis DevCore — Natural Language → 3D Blueprint · Built with Three.js*")


if __name__ == "__main__":
    demo.launch()