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)