File size: 3,024 Bytes
d26d55f
dde6b93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d26d55f
 
 
 
dde6b93
 
 
 
d26d55f
dde6b93
 
 
 
 
 
 
 
 
 
 
 
d26d55f
dde6b93
 
 
 
d26d55f
dde6b93
d26d55f
 
 
 
 
 
 
 
 
 
dde6b93
 
 
 
d26d55f
 
dde6b93
 
 
d26d55f
 
 
 
 
 
dde6b93
 
 
 
d26d55f
 
 
dde6b93
 
 
d26d55f
dde6b93
d26d55f
dde6b93
 
 
 
d26d55f
dde6b93
 
 
 
 
 
d26d55f
dde6b93
 
d26d55f
 
 
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
import json, os
from devcore.parser import parse_description

TEMPLATE_PATH = os.path.join(os.path.dirname(__file__), "templates", "viewer.html")


def description_to_blueprint(text):
    data = parse_description(text)
    return _build_threejs_html(data)


def _build_threejs_html(data):
    scene = data["structure"]
    rooms = data["rooms"]
    w = scene["width"]
    d = scene["depth"]
    s = scene["stories"]
    roof_style = scene.get("roof_style", "gable")

    wall_height = 8 if s <= 1 else 9
    floor_height = 0.5

    room_meshes = []
    wall_meshes = []
    label_data = []
    measurements = []

    for room in rooms:
        rx, rz = room["x"], room["z"]
        rw, rd = room["w"], room["d"]
        floor_n = room.get("floor", 0)
        cy = floor_n * (wall_height + floor_height) + floor_height / 2
        exterior = room.get("exterior", False)
        color = room["color"]

        room_meshes.append({
            "x": rx, "z": rz, "w": rw, "d": rd,
            "y": cy, "h": floor_height,
            "color": color, "name": room["name"], "exterior": exterior,
        })

        lx = rx + rw / 2
        lz = rz + rd / 2
        label_data.append({"x": lx, "z": lz, "y": cy + 0.3, "text": room["name"]})

        measurements.append({
            "x": rx + rw / 2, "z": rz - 1, "y": 0.1,
            "text": f"{rw:.0f}'",
            "dim": "width",
        })
        measurements.append({
            "x": rx - 1, "z": rz + rd / 2, "y": 0.1,
            "text": f"{rd:.0f}'",
            "dim": "depth",
        })

        if not exterior:
            for side in ["north", "south", "east", "west"]:
                wall_meshes.append({
                    "side": side, "x": rx, "z": rz,
                    "w": rw, "d": rd, "h": wall_height,
                    "room_name": room["name"],
                })

    roof_h = 4 if roof_style == "flat" else 6
    roof_elev = s * (wall_height + floor_height)
    roof_info = {
        "w": w * 1.15, "d": d * 1.15, "y": roof_elev,
        "h": roof_h, "style": roof_style, "color": "#5a4a3a",
        "pitch": 0.5 if roof_style == "steep-gable" else (0.3 if roof_style == "low-gable" else 0.4),
    }

    blueprint = {
        "scene": {
            "width": w, "depth": d, "stories": s,
            "wall_height": wall_height, "floor_height": floor_height,
            "roof_style": roof_style, "style": scene.get("style", "modern"),
        },
        "floors": room_meshes,
        "walls": wall_meshes,
        "roof": roof_info,
        "labels": label_data,
        "measurements": measurements,
        "summary": data["summary"],
        "features": data["features"],
    }

    return _render_html(blueprint)


def _render_html(blueprint):
    bp_json = json.dumps(blueprint)
    with open(TEMPLATE_PATH, "r") as f:
        template = f.read()
    return template.replace("/* BLUEPRINT_DATA */", f"const BLUEPRINT = {bp_json};")


def blueprint_to_json(text):
    data = parse_description(text)
    return json.dumps(data, indent=2)