| 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() |
|
|