# -*- coding: utf-8 -*-
"""
10by15 House -> Revit helper (build_10by15_revit.py)
====================================================

    UNTESTED helper -- run on an empty project created from your template;
    review every element; the website and schedules are the reference.

Project : 10by15 House  (data v0.2, generated 2026-10-18)
Source  : https://10by15.com  (all data below is generated from the website)

What it does (each step can be switched off in SETTINGS):
  1. Levels       storey levels (e.g. "GF +-0.000 ...") and the REF datums
                  (sidewalk, yard / ground beams, parapet tops) as reference
                  levels without views (Building Story off)
  2. Grids        every grid at its exact position, same extents as /revit
  3. Plan views   one floor plan per storey level (scale 1:100)
  4. Types        wall and floor types by name (duplicates a Basic Wall /
                  floor type and sets its layers + thickness when missing);
                  0 mm layers are Membrane Layers, the RC layer is the core
  5. Walls        on their levels: centreline, base offset ON THE STRUCTURE
                  (the top of the beam under the wall, else the RC top of
                  the slab), top constraint (up to the level above minus the
                  slab) or unconnected height, exterior face flipped
                  outwards; parapet walls are the brick only, up to the
                  underside of their RC coping
  6. Floors       every slab as a STRUCTURAL floor of its own type: main
                  slabs with notched outlines, lowered / sunken / level-access
                  sub-slabs at their own height offset, stair well and
                  skylight holes, and the access openings over the buried
                  tanks (septic tank, water tank covers)
  7. Shafts       one Shaft Opening per service shaft (hop gen) through the
                  floors above its base, up to its vent upstand; the pipes
                  in it go into its Comments
  8. Doors and windows, when "Family : Type" from the schedules is loaded
                  (otherwise a rectangular wall opening + "missing families"):
                  sill heights (incl. the 100 mm terrace-door kerbs), marks,
                  swing side and hinge jamb (see DOOR_* settings)
  9. Room separation lines, rooms (number, name, Vietnamese name) and tags
 10. Structural columns (each on the beam top it stands on) and beams (top
     = RC top of the slab they carry), the RC copings on the parapets and
     the parapet stub columns, if a rectangular concrete family is loaded
 11. Links the DXF plans (10by15-GF.dxf ...) into each plan view
     (Current view only, Origin to Origin, millimetres) if found
NOT created (build them by hand from /revit): stairs (numbers printed at the
end), railings and the RC upstands under the loggia guards, canopies, shaft
boxing walls, paving, gates, steps, buried pipes and the other services.

How to run
  pyRevit:  put this file in a folder and run it with pyRevit > "Run Script"
            (or make it a pushbutton script). Works with IronPython or
            CPython engines.
  RevitPythonShell: open the file in the editor and press Run (F5).
  First run with DRY_RUN = True: everything is built inside a transaction,
  the report is printed, then the transaction is ROLLED BACK. Read the
  report, load the missing families, then set DRY_RUN = False and run again.

Units: millimetres in the data, converted to feet for the API.
Origin: data (0,0) = front-left lot corner = Revit internal origin.
"""
from __future__ import print_function, division

# ---------------------------------------------------------------------------
# SETTINGS
# ---------------------------------------------------------------------------
DRY_RUN = True                    # True = build, report, then roll back
CREATE_LEVELS = True
CREATE_REF_LEVELS = True          # sidewalk / yard / parapet datums (no views)
CREATE_GRIDS = True
CREATE_PLAN_VIEWS = True
CREATE_TYPES = True
CREATE_WALLS = True
CREATE_FLOORS = True
CREATE_SHAFTS = True              # Shaft Openings; False = sketch the shaft holes
PLACE_OPENINGS = True             # doors / windows from loaded families
WALL_OPENING_IF_MISSING = True    # cut a plain wall opening if no family
ORIENT_DOORS = True               # flip doors to the swing side / hinge jamb
# Door family convention (Autodesk metric families). After the first run look
# at one swing door in plan: if every leaf opens to the wrong side, toggle
# DOOR_OPENS_TO_FACING; if every hinge is on the wrong jamb, toggle
# DOOR_HINGE_ON_HAND_SIDE - then run again.
DOOR_OPENS_TO_FACING = False      # leaf opens away from FacingOrientation
DOOR_HINGE_ON_HAND_SIDE = False   # hinge jamb is opposite HandOrientation
CREATE_ROOM_SEPARATIONS = True
CREATE_ROOMS = True
TAG_ROOMS = True
PLACE_COLUMNS = True              # needs a rectangular concrete column family
COLUMNS_TO_BEAM_TOP = False       # True = carry columns up to the beam tops
PLACE_BEAMS = True                # needs a rectangular concrete beam family
PLACE_COPINGS = True              # RC copings on the parapets (beam family)
PLACE_PARAPET_POSTS = True        # parapet stub columns (column family)
LINK_CAD = True                   # link 10by15-<level>.dxf into each plan view
CAD_FOLDER = ""                   # folder with the DXFs; "" = next to this script
SET_TRUE_NORTH = False            # see note in set_true_north()

# Families tried (in order) for structural columns / beams. Type sizes are
# duplicated from the first type and set through the "b" and "h" parameters.
COLUMN_FAMILIES = ["M_Concrete-Rectangular-Column", "Concrete-Rectangular-Column"]
BEAM_FAMILIES = ["M_Concrete-Rectangular Beam", "Concrete-Rectangular Beam"]

MM_PER_FOOT = 304.8

import json
import os
import traceback

import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import (  # noqa: E402
    BuiltInParameter,
    CompoundStructure,
    CompoundStructureLayer,
    CurveArray,
    CurveLoop,
    DWGImportOptions,
    Element,
    ElementId,
    FailureProcessingResult,
    FailureSeverity,
    FamilySymbol,
    FilteredElementCollector,
    Floor,
    FloorType,
    Grid,
    IFailuresPreprocessor,
    ImportColorMode,
    ImportPlacement,
    ImportUnit,
    Level,
    Line,
    LinkElementId,
    Material,
    MaterialFunctionAssignment,
    ShellLayerType,
    SketchPlane,
    Transaction,
    UV,
    ViewFamily,
    ViewFamilyType,
    ViewPlan,
    ViewType,
    Wall,
    WallKind,
    WallType,
    XYZ,
)
from Autodesk.Revit.DB.Structure import StructuralType  # noqa: E402
from System.Collections.Generic import List  # noqa: E402

try:
    doc = __revit__.ActiveUIDocument.Document  # noqa: F821 (pyRevit, RevitPythonShell)
except Exception:
    doc = None

# The house, generated by 10by15.com (mm). Do not edit by hand: download a new
# copy of this script from the website when the design changes.
DATA = json.loads(r'''
{
 "format": "10by15-revit",
 "project": {
  "name": "10by15 House",
  "nameVi": "Nh\u00e0 ph\u1ed1 10\u00d715",
  "code": "10B15",
  "version": "0.2",
  "date": "2026-10-18",
  "status": "Concept design \u2014 for family review and Revit modelling. Not for construction."
 },
 "generated": "2026-10-18",
 "units": "mm",
 "trueNorthAngle": 45,
 "names": {
  "roomNameVi": "T\u00ean ph\u00f2ng"
 },
 "levels": [
  {
   "id": "GF",
   "name": "Ground floor",
   "nameVi": "T\u1ea7ng tr\u1ec7t",
   "revitName": "GF \u00b10.000 T\u1ea7ng tr\u1ec7t",
   "elevation": 0,
   "cadFile": "10by15-GF.dxf"
  },
  {
   "id": "L1",
   "name": "First floor",
   "nameVi": "L\u1ea7u 1",
   "revitName": "L1 +4.100 L\u1ea7u 1",
   "elevation": 4100,
   "cadFile": "10by15-L1.dxf"
  },
  {
   "id": "RF",
   "name": "Roof terrace",
   "nameVi": "S\u00e2n th\u01b0\u1ee3ng & tum",
   "revitName": "RF +7.500 S\u00e2n th\u01b0\u1ee3ng & tum",
   "elevation": 7500,
   "cadFile": "10by15-RF.dxf"
  },
  {
   "id": "TR",
   "name": "Penthouse roof",
   "nameVi": "M\u00e1i tum",
   "revitName": "TR +10.700 M\u00e1i tum",
   "elevation": 10700,
   "cadFile": "10by15-TR.dxf"
  }
 ],
 "refLevels": [
  {
   "id": "REF-300",
   "revitName": "REF Sidewalk \u22120.300 V\u1ec9a h\u00e8",
   "elevation": -300,
   "note": "Datum for the legal building height and the neighbour heights"
  },
  {
   "id": "REF-150",
   "revitName": "REF Yard / Top of ground beams \u22120.150 S\u00e2n / \u0110\u1ec9nh d\u1ea7m m\u00f3ng",
   "elevation": -150,
   "note": "Paving: Front yard (SE-yard-front), Rear yard (SE-yard-rear) and the top of the driveway ramp (SE-drive); Ground beams (gi\u1eb1ng m\u00f3ng); base of the ground-floor walls and columns standing on them (GB-1/A-B \u22120.200 lower, under a lowered sub-slab)"
  },
  {
   "id": "REF8600",
   "revitName": "REF Top of parapet RF +8.600 \u0110\u1ec9nh t\u01b0\u1eddng ch\u1eafn m\u00e1i",
   "elevation": 8600,
   "note": "Parapets on the roof terrace (5 walls)"
  },
  {
   "id": "REF11000",
   "revitName": "REF Top of parapet TR +11.000 \u0110\u1ec9nh t\u01b0\u1eddng ch\u1eafn m\u00e1i",
   "elevation": 11000,
   "note": "Parapets on the penthouse roof (4 walls)"
  }
 ],
 "grids": [
  {
   "id": "A",
   "axis": "x",
   "position": 110,
   "start": [
    110,
    -1000
   ],
   "end": [
    110,
    16000
   ]
  },
  {
   "id": "B",
   "axis": "x",
   "position": 3755,
   "start": [
    3755,
    -1000
   ],
   "end": [
    3755,
    16000
   ]
  },
  {
   "id": "C",
   "axis": "x",
   "position": 6355,
   "start": [
    6355,
    -1000
   ],
   "end": [
    6355,
    16000
   ]
  },
  {
   "id": "D",
   "axis": "x",
   "position": 9890,
   "start": [
    9890,
    -1000
   ],
   "end": [
    9890,
    16000
   ]
  },
  {
   "id": "1",
   "axis": "y",
   "position": 1260,
   "start": [
    -1000,
    1260
   ],
   "end": [
    11000,
    1260
   ]
  },
  {
   "id": "1a",
   "axis": "y",
   "position": 4400,
   "start": [
    -1000,
    4400
   ],
   "end": [
    11000,
    4400
   ]
  },
  {
   "id": "2",
   "axis": "y",
   "position": 6780,
   "start": [
    -1000,
    6780
   ],
   "end": [
    11000,
    6780
   ]
  },
  {
   "id": "3",
   "axis": "y",
   "position": 9100,
   "start": [
    -1000,
    9100
   ],
   "end": [
    11000,
    9100
   ]
  },
  {
   "id": "4",
   "axis": "y",
   "position": 12890,
   "start": [
    -1000,
    12890
   ],
   "end": [
    11000,
    12890
   ]
  }
 ],
 "wallTypes": [
  {
   "id": "EXT-220",
   "revitName": "VN-EXT-220 Brick 180 + Plaster 20/20",
   "thickness": 220,
   "function": "exterior",
   "coreIndex": 1,
   "exteriorShell": 1,
   "interiorShell": 1,
   "layers": [
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75), exterior, painted",
     "materialVi": "V\u1eefa tr\u00e1t xi m\u0103ng c\u00e1t M7,5 (m\u00e1c 75), s\u01a1n ngo\u1ea1i th\u1ea5t",
     "thickness": 20,
     "function": "Finish1"
    },
    {
     "material": "10B15 Hollow clay brick 80\u00d780\u00d7180 laid as headers (180 across the wall)",
     "materialVi": "G\u1ea1ch \u1ed1ng 4 l\u1ed7 80\u00d780\u00d7180 x\u00e2y quay ngang (t\u01b0\u1eddng 20)",
     "thickness": 180,
     "function": "Structure"
    },
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75), interior, putty + paint",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75), b\u1ea3 matit, s\u01a1n n\u1ed9i th\u1ea5t",
     "thickness": 20,
     "function": "Finish2"
    }
   ]
  },
  {
   "id": "INT-220",
   "revitName": "VN-INT-220 Brick 180 + Plaster 20/20",
   "thickness": 220,
   "function": "interior",
   "coreIndex": 1,
   "exteriorShell": 1,
   "interiorShell": 1,
   "layers": [
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75), putty + paint",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75), b\u1ea3 matit, s\u01a1n",
     "thickness": 20,
     "function": "Finish1"
    },
    {
     "material": "10B15 Hollow clay brick 80\u00d780\u00d7180 laid as headers (180 across the wall)",
     "materialVi": "G\u1ea1ch \u1ed1ng 80\u00d780\u00d7180 x\u00e2y quay ngang",
     "thickness": 180,
     "function": "Structure"
    },
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75), putty + paint",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75), b\u1ea3 matit, s\u01a1n",
     "thickness": 20,
     "function": "Finish2"
    }
   ]
  },
  {
   "id": "INT-110",
   "revitName": "VN-INT-110 Brick 80 + Plaster 15/15",
   "thickness": 110,
   "function": "interior",
   "coreIndex": 1,
   "exteriorShell": 1,
   "interiorShell": 1,
   "layers": [
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75)- tiles in wet rooms",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75) (\u1ed1p g\u1ea1ch khu v\u1ec7 sinh)",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Hollow clay brick 80\u00d780\u00d7180 laid as stretchers (80 across the wall)",
     "materialVi": "G\u1ea1ch \u1ed1ng 80\u00d780\u00d7180 x\u00e2y d\u1ecdc (t\u01b0\u1eddng 10)",
     "thickness": 80,
     "function": "Structure"
    },
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75)- tiles in wet rooms",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75) (\u1ed1p g\u1ea1ch khu v\u1ec7 sinh)",
     "thickness": 15,
     "function": "Finish2"
    }
   ]
  },
  {
   "id": "PAR-220",
   "revitName": "VN-PAR-220 Solid Brick 180 + Plaster 20/20",
   "thickness": 220,
   "function": "parapet",
   "coreIndex": 1,
   "exteriorShell": 1,
   "interiorShell": 1,
   "layers": [
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75), exterior paint",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75), s\u01a1n ngo\u1ea1i th\u1ea5t",
     "thickness": 20,
     "function": "Finish1"
    },
    {
     "material": "10B15 SOLID clay brick (g\u1ea1ch th\u1ebb / g\u1ea1ch \u0111inh 40\u00d780\u00d7180) in M7.5 mortar, RC coping beam 100 with 2\u00d810",
     "materialVi": "G\u1ea1ch \u0111\u1eb7c (g\u1ea1ch th\u1ebb / g\u1ea1ch \u0111inh 40\u00d780\u00d7180) v\u1eefa M7,5, gi\u1eb1ng \u0111\u1ec9nh t\u01b0\u1eddng BTCT d\u00e0y 100, 2\u00d810",
     "thickness": 180,
     "function": "Structure"
    },
    {
     "material": "10B15 Cement-sand plaster M7.5 (m\u00e1c 75) + waterproof upturn 300",
     "materialVi": "V\u1eefa tr\u00e1t M7,5 (m\u00e1c 75) + ch\u1ed1ng th\u1ea5m ch\u00e2n t\u01b0\u1eddng 300",
     "thickness": 20,
     "function": "Finish2"
    }
   ]
  }
 ],
 "slabTypes": [
  {
   "id": "FL-GF",
   "revitName": "VN-FL-GF 150",
   "thickness": 150,
   "coreIndex": 2,
   "exteriorShell": 2,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Porcelain tile 600\u00d7600 + adhesive",
     "materialVi": "G\u1ea1ch granite nh\u00e2n t\u1ea1o 600\u00d7600 + keo d\u00e1n",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Cement-sand screed M7.5 (m\u00e1c 75)",
     "materialVi": "V\u1eefa l\u00f3t M7,5 (m\u00e1c 75)",
     "thickness": 35,
     "function": "Substrate"
    },
    {
     "material": "10B15 RC slab B20 (M250), mesh \u00d88 a200",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250), l\u01b0\u1edbi th\u00e9p \u00d88 a200",
     "thickness": 100,
     "function": "Structure"
    }
   ]
  },
  {
   "id": "FL-GF-WC",
   "revitName": "VN-FL-GF-WC 200",
   "thickness": 200,
   "coreIndex": 3,
   "exteriorShell": 3,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Anti-slip porcelain 300\u00d7300 (R11)",
     "materialVi": "G\u1ea1ch ch\u1ed1ng tr\u01a1n 300\u00d7300 (R11)",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Screed to falls \u2265 2 % to a linear drain (avg 85)",
     "materialVi": "V\u1eefa t\u1ea1o d\u1ed1c \u2265 2 % v\u1ec1 r\u00e3nh thu (TB 85)",
     "thickness": 85,
     "function": "Substrate"
    },
    {
     "material": "10B15 Waterproofing membrane, 2 coats, turned up 300 (1 800 at the shower)",
     "materialVi": "Ch\u1ed1ng th\u1ea5m 2 l\u1edbp, v\u00e9n t\u01b0\u1eddng 300 (khu t\u1eafm 1 800)",
     "thickness": 0,
     "function": "Membrane"
    },
    {
     "material": "10B15 RC slab B20 (M250), locally lowered 50",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250), h\u1ea1 c\u1ed1t 50",
     "thickness": 100,
     "function": "Structure"
    }
   ]
  },
  {
   "id": "FL-170",
   "revitName": "VN-FL-170 RC120 + Finish50",
   "thickness": 170,
   "coreIndex": 2,
   "exteriorShell": 2,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Floor finish (tile / engineered wood)",
     "materialVi": "L\u1edbp ho\u00e0n thi\u1ec7n (g\u1ea1ch / s\u00e0n g\u1ed7)",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Cement-sand screed M7.5 (m\u00e1c 75)",
     "materialVi": "V\u1eefa l\u00f3t M7,5 (m\u00e1c 75)",
     "thickness": 35,
     "function": "Substrate"
    },
    {
     "material": "10B15 RC slab B20 (M250)",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250)",
     "thickness": 120,
     "function": "Structure"
    }
   ]
  },
  {
   "id": "FL-WC-450",
   "revitName": "VN-FL-WC-450 RC120 sunk 300",
   "thickness": 450,
   "coreIndex": 4,
   "exteriorShell": 4,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Anti-slip porcelain 300\u00d7300 (R11)",
     "materialVi": "G\u1ea1ch ch\u1ed1ng tr\u01a1n 300\u00d7300 (R11)",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Screed to falls \u2265 2 % + second waterproofing layer",
     "materialVi": "V\u1eefa t\u1ea1o d\u1ed1c \u2265 2 % + l\u1edbp ch\u1ed1ng th\u1ea5m th\u1ee9 hai",
     "thickness": 35,
     "function": "Substrate"
    },
    {
     "material": "10B15 Lightweight fill (foamed concrete / brick rubble in mortar) around the drains",
     "materialVi": "L\u1edbp \u0111\u1ec7m nh\u1eb9 (b\u00ea t\u00f4ng b\u1ecdt / x\u00e0 b\u1ea7n tr\u1ed9n v\u1eefa) quanh \u1ed1ng tho\u00e1t",
     "thickness": 280,
     "function": "Substrate"
    },
    {
     "material": "10B15 Waterproofing membrane on the RC, turned up 300 (1 800 at showers)",
     "materialVi": "M\u00e0ng ch\u1ed1ng th\u1ea5m tr\u00ean s\u00e0n BTCT, v\u00e9n t\u01b0\u1eddng 300 (khu t\u1eafm 1 800)",
     "thickness": 0,
     "function": "Membrane"
    },
    {
     "material": "10B15 RC slab B20 (M250), sunk 300",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250), h\u1ea1 c\u1ed1t 300",
     "thickness": 120,
     "function": "Structure"
    }
   ]
  },
  {
   "id": "FL-OUT-170",
   "revitName": "VN-FL-OUT-170 RC120 lowered 50",
   "thickness": 170,
   "coreIndex": 3,
   "exteriorShell": 3,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Anti-slip outdoor porcelain 300\u00d7600",
     "materialVi": "G\u1ea1ch ngo\u00e0i tr\u1eddi ch\u1ed1ng tr\u01a1n 300\u00d7600",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Screed to falls \u2265 1 % to the drain",
     "materialVi": "V\u1eefa t\u1ea1o d\u1ed1c \u2265 1 % v\u1ec1 ph\u1ec5u thu",
     "thickness": 35,
     "function": "Substrate"
    },
    {
     "material": "10B15 Waterproofing membrane, turned up 200 behind the door sills",
     "materialVi": "Ch\u1ed1ng th\u1ea5m, v\u00e9n 200 d\u01b0\u1edbi ng\u1ea1ch c\u1eeda",
     "thickness": 0,
     "function": "Membrane"
    },
    {
     "material": "10B15 RC slab B20 (M250), lowered 50",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250), h\u1ea1 c\u1ed1t 50",
     "thickness": 120,
     "function": "Structure"
    }
   ]
  },
  {
   "id": "RF-250",
   "revitName": "VN-RF-250 RC120 + Falls + WP + XPS",
   "thickness": 250,
   "coreIndex": 6,
   "exteriorShell": 6,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Anti-slip terracotta tile (g\u1ea1ch \u0111\u1ecf ch\u1ed1ng tr\u01a1n) / porcelain",
     "materialVi": "G\u1ea1ch \u0111\u1ecf ch\u1ed1ng tr\u01a1n / g\u1ea1ch men ch\u1ed1ng tr\u01a1n",
     "thickness": 15,
     "function": "Finish1"
    },
    {
     "material": "10B15 Protection screed / tile bed",
     "materialVi": "V\u1eefa b\u1ea3o v\u1ec7 / v\u1eefa l\u00f3t g\u1ea1ch",
     "thickness": 30,
     "function": "Substrate"
    },
    {
     "material": "10B15 Separating sheet (geotextile / PE) over the insulation",
     "materialVi": "L\u1edbp ng\u0103n c\u00e1ch (v\u1ea3i \u0111\u1ecba k\u1ef9 thu\u1eadt / nilon) tr\u00ean l\u1edbp c\u00e1ch nhi\u1ec7t",
     "thickness": 0,
     "function": "Membrane"
    },
    {
     "material": "10B15 XPS insulation board 40 (inverted roof)",
     "materialVi": "T\u1ea5m c\u00e1ch nhi\u1ec7t XPS 40 (m\u00e1i ng\u01b0\u1ee3c)",
     "thickness": 40,
     "function": "Insulation"
    },
    {
     "material": "10B15 Waterproofing membrane, 2 layers, turned up 300 at parapets and kerbs",
     "materialVi": "M\u00e0ng ch\u1ed1ng th\u1ea5m 2 l\u1edbp, v\u00e9n 300 ch\u00e2n t\u01b0\u1eddng v\u00e0 g\u1edd",
     "thickness": 0,
     "function": "Membrane"
    },
    {
     "material": "10B15 Screed to falls \u2265 1 % (avg 45)",
     "materialVi": "V\u1eefa t\u1ea1o d\u1ed1c \u2265 1 % (TB 45)",
     "thickness": 45,
     "function": "Substrate"
    },
    {
     "material": "10B15 RC slab B20 (M250)",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250)",
     "thickness": 120,
     "function": "Structure"
    }
   ]
  },
  {
   "id": "TR-290",
   "revitName": "VN-TR-290 RC120 + Falls + WP + Insulating tiles",
   "thickness": 290,
   "coreIndex": 4,
   "exteriorShell": 4,
   "interiorShell": 0,
   "layers": [
    {
     "material": "10B15 Heat-insulating 4-hole clay tiles 220\u00d7220\u00d7105 (g\u1ea1ch ch\u1ed1ng n\u00f3ng 4 l\u1ed7)",
     "materialVi": "G\u1ea1ch ch\u1ed1ng n\u00f3ng 4 l\u1ed7 220\u00d7220\u00d7105",
     "thickness": 105,
     "function": "Finish1"
    },
    {
     "material": "10B15 Mortar bed",
     "materialVi": "V\u1eefa l\u00f3t",
     "thickness": 15,
     "function": "Substrate"
    },
    {
     "material": "10B15 Waterproofing membrane, 2 layers, turned up 300",
     "materialVi": "M\u00e0ng ch\u1ed1ng th\u1ea5m 2 l\u1edbp, v\u00e9n 300",
     "thickness": 0,
     "function": "Membrane"
    },
    {
     "material": "10B15 Screed to falls \u2265 1 % (avg 50, 6 m to the outlets)",
     "materialVi": "V\u1eefa t\u1ea1o d\u1ed1c \u2265 1 % (TB 50)",
     "thickness": 50,
     "function": "Substrate"
    },
    {
     "material": "10B15 RC slab B20 (M250)",
     "materialVi": "S\u00e0n BTCT B20 (m\u00e1c 250)",
     "thickness": 120,
     "function": "Structure"
    }
   ]
  }
 ],
 "walls": [
  {
   "id": "GF-FRONT-AB",
   "level": "GF",
   "type": "EXT-220",
   "start": [
    110,
    1260
   ],
   "end": [
    3755,
    1260
   ],
   "baseOffset": -200,
   "height": 4130,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-FRONT-BD",
   "level": "GF",
   "type": "EXT-220",
   "start": [
    3755,
    1260
   ],
   "end": [
    9890,
    1260
   ],
   "baseOffset": -150,
   "height": 4030,
   "topLevel": "L1",
   "topOffset": -220,
   "coping": 0,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-LEFT",
   "level": "GF",
   "type": "EXT-220",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    12890
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": [
    -1,
    0
   ],
   "boundary": "left",
   "notes": ""
  },
  {
   "id": "GF-RIGHT",
   "level": "GF",
   "type": "EXT-220",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    12890
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": [
    1,
    0
   ],
   "boundary": "right",
   "notes": ""
  },
  {
   "id": "GF-REAR",
   "level": "GF",
   "type": "EXT-220",
   "start": [
    110,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": [
    0,
    1
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-B-FRONT",
   "level": "GF",
   "type": "INT-220",
   "start": [
    3755,
    1260
   ],
   "end": [
    3755,
    6780
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-B-REAR",
   "level": "GF",
   "type": "INT-220",
   "start": [
    3755,
    9100
   ],
   "end": [
    3755,
    12890
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-C-MID",
   "level": "GF",
   "type": "INT-220",
   "start": [
    6355,
    6780
   ],
   "end": [
    6355,
    9100
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-2-AB",
   "level": "GF",
   "type": "INT-220",
   "start": [
    110,
    6780
   ],
   "end": [
    3755,
    6780
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-2-BC",
   "level": "GF",
   "type": "INT-220",
   "start": [
    3755,
    6780
   ],
   "end": [
    6355,
    6780
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-2-CD",
   "level": "GF",
   "type": "INT-220",
   "start": [
    6355,
    6780
   ],
   "end": [
    9890,
    6780
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-3-AB",
   "level": "GF",
   "type": "INT-220",
   "start": [
    110,
    9100
   ],
   "end": [
    3755,
    9100
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-3-CD",
   "level": "GF",
   "type": "INT-220",
   "start": [
    6355,
    9100
   ],
   "end": [
    9890,
    9100
   ],
   "baseOffset": -150,
   "height": 4080,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "GF-P-WC",
   "level": "GF",
   "type": "INT-110",
   "start": [
    8155,
    6780
   ],
   "end": [
    8155,
    9100
   ],
   "baseOffset": -50,
   "height": 3980,
   "topLevel": "L1",
   "topOffset": -170,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-FRONT-AB",
   "level": "L1",
   "type": "EXT-220",
   "start": [
    110,
    1260
   ],
   "end": [
    3755,
    1260
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-LEFT",
   "level": "L1",
   "type": "EXT-220",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    12890
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": [
    -1,
    0
   ],
   "boundary": "left",
   "notes": ""
  },
  {
   "id": "L1-RIGHT",
   "level": "L1",
   "type": "EXT-220",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    12890
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": [
    1,
    0
   ],
   "boundary": "right",
   "notes": ""
  },
  {
   "id": "L1-REAR",
   "level": "L1",
   "type": "EXT-220",
   "start": [
    110,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": [
    0,
    1
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-FRONT-LOGGIA",
   "level": "L1",
   "type": "EXT-220",
   "start": [
    3755,
    2680
   ],
   "end": [
    9890,
    2680
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": "Recessed front wall behind the loggia; sits on secondary beam BS-L1-01"
  },
  {
   "id": "L1-B-FRONT",
   "level": "L1",
   "type": "INT-220",
   "start": [
    3755,
    1260
   ],
   "end": [
    3755,
    6780
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-B-REAR",
   "level": "L1",
   "type": "INT-220",
   "start": [
    3755,
    9100
   ],
   "end": [
    3755,
    12890
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-C-FRONT",
   "level": "L1",
   "type": "INT-220",
   "start": [
    6355,
    2680
   ],
   "end": [
    6355,
    6780
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-C-MID",
   "level": "L1",
   "type": "INT-220",
   "start": [
    6355,
    6780
   ],
   "end": [
    6355,
    9100
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-C-REAR",
   "level": "L1",
   "type": "INT-220",
   "start": [
    6355,
    9100
   ],
   "end": [
    6355,
    12890
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-2-AB",
   "level": "L1",
   "type": "INT-220",
   "start": [
    110,
    6780
   ],
   "end": [
    3755,
    6780
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-2-CD",
   "level": "L1",
   "type": "INT-220",
   "start": [
    6355,
    6780
   ],
   "end": [
    9890,
    6780
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-3-AB",
   "level": "L1",
   "type": "INT-220",
   "start": [
    110,
    9100
   ],
   "end": [
    3755,
    9100
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-3-CD",
   "level": "L1",
   "type": "INT-220",
   "start": [
    6355,
    9100
   ],
   "end": [
    9890,
    9100
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-P-BATH",
   "level": "L1",
   "type": "INT-110",
   "start": [
    8155,
    6780
   ],
   "end": [
    8155,
    9100
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "L1-P-SHBATH",
   "level": "L1",
   "type": "INT-110",
   "start": [
    3755,
    10365
   ],
   "end": [
    6355,
    10365
   ],
   "baseOffset": -50,
   "height": 3200,
   "topLevel": "RF",
   "topOffset": -250,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": "Sits on secondary beam BS-L1-03"
  },
  {
   "id": "RF-T-LEFT",
   "level": "RF",
   "type": "EXT-220",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    9100
   ],
   "baseOffset": -130,
   "height": 3040,
   "topLevel": "TR",
   "topOffset": -290,
   "coping": 0,
   "exteriorNormal": [
    -1,
    0
   ],
   "boundary": "left",
   "notes": ""
  },
  {
   "id": "RF-T-FRONT",
   "level": "RF",
   "type": "EXT-220",
   "start": [
    110,
    4400
   ],
   "end": [
    6355,
    4400
   ],
   "baseOffset": -130,
   "height": 3040,
   "topLevel": "TR",
   "topOffset": -290,
   "coping": 0,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": "Sits on secondary beam BS-RF-01"
  },
  {
   "id": "RF-T-RIGHT",
   "level": "RF",
   "type": "EXT-220",
   "start": [
    6355,
    4400
   ],
   "end": [
    6355,
    9100
   ],
   "baseOffset": -130,
   "height": 3040,
   "topLevel": "TR",
   "topOffset": -290,
   "coping": 0,
   "exteriorNormal": [
    1,
    0
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "RF-T-REAR",
   "level": "RF",
   "type": "EXT-220",
   "start": [
    110,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "baseOffset": -130,
   "height": 3040,
   "topLevel": "TR",
   "topOffset": -290,
   "coping": 0,
   "exteriorNormal": [
    0,
    1
   ],
   "boundary": null,
   "notes": ""
  },
  {
   "id": "RF-T-2",
   "level": "RF",
   "type": "INT-220",
   "start": [
    110,
    6780
   ],
   "end": [
    6355,
    6780
   ],
   "baseOffset": -130,
   "height": 3040,
   "topLevel": "TR",
   "topOffset": -290,
   "coping": 0,
   "exteriorNormal": null,
   "boundary": null,
   "notes": ""
  },
  {
   "id": "RF-P-FRONT",
   "level": "RF",
   "type": "PAR-220",
   "start": [
    110,
    1260
   ],
   "end": [
    9890,
    1260
   ],
   "baseOffset": -130,
   "height": 1130,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": "Brick to +8.500; RC coping 220 x 100 on top to +8.600"
  },
  {
   "id": "RF-P-LEFT-F",
   "level": "RF",
   "type": "PAR-220",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    4400
   ],
   "baseOffset": -130,
   "height": 1130,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    -1,
    0
   ],
   "boundary": "left",
   "notes": "Brick to +8.500; RC coping 220 x 100 on top to +8.600"
  },
  {
   "id": "RF-P-LEFT-R",
   "level": "RF",
   "type": "PAR-220",
   "start": [
    110,
    9100
   ],
   "end": [
    110,
    12890
   ],
   "baseOffset": -130,
   "height": 1130,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    -1,
    0
   ],
   "boundary": "left",
   "notes": "Brick to +8.500; RC coping 220 x 100 on top to +8.600"
  },
  {
   "id": "RF-P-RIGHT",
   "level": "RF",
   "type": "PAR-220",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    12890
   ],
   "baseOffset": -130,
   "height": 1130,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    1,
    0
   ],
   "boundary": "right",
   "notes": "Brick to +8.500; RC coping 220 x 100 on top to +8.600"
  },
  {
   "id": "RF-P-REAR",
   "level": "RF",
   "type": "PAR-220",
   "start": [
    110,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "baseOffset": -130,
   "height": 1130,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    0,
    1
   ],
   "boundary": null,
   "notes": "Brick to +8.500; RC coping 220 x 100 on top to +8.600"
  },
  {
   "id": "TR-P-FRONT",
   "level": "TR",
   "type": "PAR-220",
   "start": [
    110,
    4400
   ],
   "end": [
    6355,
    4400
   ],
   "baseOffset": -170,
   "height": 370,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    0,
    -1
   ],
   "boundary": null,
   "notes": "Brick to +10.900; RC coping 220 x 100 on top to +11.000"
  },
  {
   "id": "TR-P-RIGHT",
   "level": "TR",
   "type": "PAR-220",
   "start": [
    6355,
    4400
   ],
   "end": [
    6355,
    9100
   ],
   "baseOffset": -170,
   "height": 370,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    1,
    0
   ],
   "boundary": null,
   "notes": "Brick to +10.900; RC coping 220 x 100 on top to +11.000"
  },
  {
   "id": "TR-P-REAR",
   "level": "TR",
   "type": "PAR-220",
   "start": [
    110,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "baseOffset": -170,
   "height": 370,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    0,
    1
   ],
   "boundary": null,
   "notes": "Brick to +10.900; RC coping 220 x 100 on top to +11.000"
  },
  {
   "id": "TR-P-LEFT",
   "level": "TR",
   "type": "PAR-220",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    9100
   ],
   "baseOffset": -170,
   "height": 370,
   "topLevel": null,
   "topOffset": null,
   "coping": 100,
   "exteriorNormal": [
    -1,
    0
   ],
   "boundary": "left",
   "notes": "Brick to +10.900; RC coping 220 x 100 on top to +11.000"
  }
 ],
 "slabs": [
  {
   "id": "S-GF",
   "level": "GF",
   "type": "FL-GF",
   "thickness": 150,
   "outline": [
    [
     0,
     1150
    ],
    [
     220,
     1150
    ],
    [
     220,
     6670
    ],
    [
     3645,
     6670
    ],
    [
     3645,
     1150
    ],
    [
     10000,
     1150
    ],
    [
     10000,
     13000
    ],
    [
     0,
     13000
    ]
   ],
   "holes": [
    [
     [
      6465,
      8990
     ],
     [
      7800,
      8990
     ],
     [
      7800,
      8540
     ],
     [
      8100,
      8540
     ],
     [
      8100,
      6890
     ],
     [
      6465,
      6890
     ]
    ],
    [
     [
      8450,
      3000
     ],
     [
      9050,
      3000
     ],
     [
      9050,
      2400
     ],
     [
      8450,
      2400
     ]
    ]
   ],
   "shaftHoles": [],
   "allHoles": [
    [
     [
      6465,
      8990
     ],
     [
      7800,
      8990
     ],
     [
      7800,
      8540
     ],
     [
      8100,
      8540
     ],
     [
      8100,
      6890
     ],
     [
      6465,
      6890
     ]
    ],
    [
     [
      8450,
      3000
     ],
     [
      9050,
      3000
     ],
     [
      9050,
      2400
     ],
     [
      8450,
      2400
     ]
    ]
   ],
   "accessOpenings": [
    {
     "service": "SV-water-ug",
     "rect": [
      [
       8450,
       2400
      ],
      [
       9050,
       3000
      ]
     ]
    }
   ],
   "topOffset": 0,
   "rcTop": -50,
   "main": true,
   "notes": "RC top \u22120.050, finished top \u00b10.000"
  },
  {
   "id": "S-GF-GARAGE",
   "level": "GF",
   "type": "FL-GF",
   "thickness": 150,
   "outline": [
    [
     220,
     1150
    ],
    [
     3645,
     1150
    ],
    [
     3645,
     6670
    ],
    [
     220,
     6670
    ]
   ],
   "holes": [
    [
     [
      1570,
      3550
     ],
     [
      2070,
      3550
     ],
     [
      2070,
      3050
     ],
     [
      1570,
      3050
     ]
    ],
    [
     [
      1570,
      4150
     ],
     [
      2070,
      4150
     ],
     [
      2070,
      3650
     ],
     [
      1570,
      3650
     ]
    ]
   ],
   "shaftHoles": [],
   "allHoles": [
    [
     [
      1570,
      3550
     ],
     [
      2070,
      3550
     ],
     [
      2070,
      3050
     ],
     [
      1570,
      3050
     ]
    ],
    [
     [
      1570,
      4150
     ],
     [
      2070,
      4150
     ],
     [
      2070,
      3650
     ],
     [
      1570,
      3650
     ]
    ]
   ],
   "accessOpenings": [
    {
     "service": "SV-septic",
     "rect": [
      [
       1570,
       3050
      ],
      [
       2070,
       3550
      ]
     ]
    },
    {
     "service": "SV-septic",
     "rect": [
      [
       1570,
       3650
      ],
      [
       2070,
       4150
      ]
     ]
    }
   ],
   "topOffset": -150,
   "rcTop": -200,
   "main": false,
   "notes": "Garage floor \u22120.150, falls 1 % to the gate; runs under the garage door to the fa\u00e7ade. The ground beams under it drop to \u22120.200 so the build-up passes over them. Septic tank below. RC top \u22120.200, finished top \u22120.150"
  },
  {
   "id": "S-GF-WC",
   "level": "GF",
   "type": "FL-GF-WC",
   "thickness": 200,
   "outline": [
    [
     6465,
     6890
    ],
    [
     8100,
     6890
    ],
    [
     8100,
     8540
    ],
    [
     7800,
     8540
    ],
    [
     7800,
     8990
    ],
    [
     6465,
     8990
    ]
   ],
   "holes": [],
   "shaftHoles": [],
   "allHoles": [],
   "accessOpenings": [],
   "topOffset": 0,
   "rcTop": -100,
   "main": false,
   "notes": "Level-access WC: finished floor \u00b10.000, RC lowered to \u22120.100 for falls to the shower drain. RC top \u22120.100, finished top \u00b10.000"
  },
  {
   "id": "S-L1",
   "level": "L1",
   "type": "FL-170",
   "thickness": 170,
   "outline": [
    [
     0,
     1150
    ],
    [
     3865,
     1150
    ],
    [
     3865,
     2570
    ],
    [
     9780,
     2570
    ],
    [
     9780,
     1150
    ],
    [
     10000,
     1150
    ],
    [
     10000,
     13000
    ],
    [
     0,
     13000
    ]
   ],
   "holes": [
    [
     [
      220,
      8990
     ],
     [
      4300,
      8990
     ],
     [
      4300,
      6890
     ],
     [
      220,
      6890
     ]
    ],
    [
     [
      6465,
      8990
     ],
     [
      8100,
      8990
     ],
     [
      8100,
      6890
     ],
     [
      6465,
      6890
     ]
    ],
    [
     [
      3865,
      12780
     ],
     [
      6245,
      12780
     ],
     [
      6245,
      10420
     ],
     [
      3865,
      10420
     ]
    ]
   ],
   "shaftHoles": [
    "SH-3"
   ],
   "allHoles": [
    [
     [
      220,
      8990
     ],
     [
      4300,
      8990
     ],
     [
      4300,
      6890
     ],
     [
      220,
      6890
     ]
    ],
    [
     [
      6465,
      8990
     ],
     [
      8100,
      8990
     ],
     [
      8100,
      6890
     ],
     [
      6465,
      6890
     ]
    ],
    [
     [
      3865,
      12780
     ],
     [
      6245,
      12780
     ],
     [
      6245,
      10420
     ],
     [
      3865,
      10420
     ]
    ],
    [
     [
      9480,
      9510
     ],
     [
      9780,
      9510
     ],
     [
      9780,
      9210
     ],
     [
      9480,
      9210
     ]
    ]
   ],
   "accessOpenings": [],
   "topOffset": 0,
   "rcTop": 4050,
   "main": true,
   "notes": "RC top +4.050, finished top +4.100"
  },
  {
   "id": "S-L1-LOGGIA",
   "level": "L1",
   "type": "FL-OUT-170",
   "thickness": 170,
   "outline": [
    [
     3865,
     1150
    ],
    [
     9780,
     1150
    ],
    [
     9780,
     2570
    ],
    [
     3865,
     2570
    ]
   ],
   "holes": [],
   "shaftHoles": [],
   "allHoles": [],
   "accessOpenings": [],
   "topOffset": -50,
   "rcTop": 4000,
   "main": false,
   "notes": "Loggia: finished \u22120.050, RC top \u22120.100; falls to the drain at the right-hand end. RC top +4.000, finished top +4.050"
  },
  {
   "id": "S-L1-WC-1",
   "level": "L1",
   "type": "FL-WC-450",
   "thickness": 450,
   "outline": [
    [
     6465,
     6890
    ],
    [
     8100,
     6890
    ],
    [
     8100,
     8540
    ],
    [
     7800,
     8540
    ],
    [
     7800,
     8990
    ],
    [
     6465,
     8990
    ]
   ],
   "holes": [],
   "shaftHoles": [],
   "allHoles": [],
   "accessOpenings": [],
   "topOffset": -20,
   "rcTop": 3750,
   "main": false,
   "notes": "Master bathroom: sunken structural slab (RC top \u22120.350). RC top +3.750, finished top +4.080"
  },
  {
   "id": "S-L1-WC-2",
   "level": "L1",
   "type": "FL-WC-450",
   "thickness": 450,
   "outline": [
    [
     3865,
     10420
    ],
    [
     6245,
     10420
    ],
    [
     6245,
     12780
    ],
    [
     4165,
     12780
    ],
    [
     4165,
     12330
    ],
    [
     3865,
     12330
    ]
   ],
   "holes": [],
   "shaftHoles": [],
   "allHoles": [],
   "accessOpenings": [],
   "topOffset": -20,
   "rcTop": 3750,
   "main": false,
   "notes": "Shared bathroom: sunken structural slab (RC top \u22120.350). RC top +3.750, finished top +4.080"
  },
  {
   "id": "S-RF",
   "level": "RF",
   "type": "RF-250",
   "thickness": 250,
   "outline": [
    [
     0,
     1150
    ],
    [
     10000,
     1150
    ],
    [
     10000,
     13000
    ],
    [
     0,
     13000
    ]
   ],
   "holes": [
    [
     [
      220,
      8990
     ],
     [
      4300,
      8990
     ],
     [
      4300,
      6890
     ],
     [
      220,
      6890
     ]
    ]
   ],
   "shaftHoles": [
    "SH-1",
    "SH-2",
    "SH-3"
   ],
   "allHoles": [
    [
     [
      220,
      8990
     ],
     [
      4300,
      8990
     ],
     [
      4300,
      6890
     ],
     [
      220,
      6890
     ]
    ],
    [
     [
      7800,
      8990
     ],
     [
      8100,
      8990
     ],
     [
      8100,
      8540
     ],
     [
      7800,
      8540
     ]
    ],
    [
     [
      3865,
      12780
     ],
     [
      4165,
      12780
     ],
     [
      4165,
      12330
     ],
     [
      3865,
      12330
     ]
    ],
    [
     [
      9480,
      9510
     ],
     [
      9780,
      9510
     ],
     [
      9780,
      9210
     ],
     [
      9480,
      9210
     ]
    ]
   ],
   "accessOpenings": [],
   "topOffset": 0,
   "rcTop": 7370,
   "main": true,
   "notes": "Shaft openings for the vent stacks and the kitchen-hood duct, which terminate above the terrace. RC top +7.370, finished top +7.500"
  },
  {
   "id": "S-TR",
   "level": "TR",
   "type": "TR-290",
   "thickness": 290,
   "outline": [
    [
     0,
     4290
    ],
    [
     6465,
     4290
    ],
    [
     6465,
     9210
    ],
    [
     0,
     9210
    ]
   ],
   "holes": [
    [
     [
      1320,
      8840
     ],
     [
      3720,
      8840
     ],
     [
      3720,
      7040
     ],
     [
      1320,
      7040
     ]
    ]
   ],
   "shaftHoles": [],
   "allHoles": [
    [
     [
      1320,
      8840
     ],
     [
      3720,
      8840
     ],
     [
      3720,
      7040
     ],
     [
      1320,
      7040
     ]
    ]
   ],
   "accessOpenings": [],
   "topOffset": 0,
   "rcTop": 10530,
   "main": true,
   "notes": "Skylight over the stair core (2.4 \u00d7 1.8 m) on a 300 mm upstand. RC top +10.530, finished top +10.700"
  }
 ],
 "shafts": [
  {
   "id": "SH-1",
   "profile": [
    [
     7800,
     8540
    ],
    [
     8100,
     8540
    ],
    [
     8100,
     8990
    ],
    [
     7800,
     8990
    ]
   ],
   "bottomLevel": "L1",
   "baseOffset": -470,
   "topLevel": "RF",
   "topOffset": 1000,
   "enclosed": [
    "GF",
    "L1"
   ],
   "contents": "Soil stack \u00d8110 (GF WC and master-bathroom pans \u2192 septic tank) + grey-water stack \u00d875 (master-bathroom floor drain \u2192 front pit) + vent \u00d875; exhaust duct \u00d8100 from both bathroom fans (\u2265 50 m\u00b3/h each) to a cowl above the side terrace",
   "stacks": [
    {
     "kind": "soil",
     "dia": 110,
     "connectsTo": "SV-septic",
     "text": "Soil stack \u00d8110 \u2192 SV-septic Septic tank"
    },
    {
     "kind": "grey",
     "dia": 75,
     "connectsTo": "SV-mh-2",
     "text": "Grey-water stack \u00d875 \u2192 SV-mh-2 Front inspection pit"
    },
    {
     "kind": "vent",
     "dia": 75,
     "connectsTo": "roof",
     "text": "Vent stack \u00d875 \u2192 roof (vent cowl above the terrace)"
    },
    {
     "kind": "exhaust",
     "dia": 100,
     "connectsTo": "roof",
     "text": "Exhaust duct \u00d8100 \u2192 roof (vent cowl above the terrace)"
    }
   ],
   "boxing": [
    {
     "level": "GF",
     "a": [
      7800,
      8540
     ],
     "b": [
      8100,
      8540
     ]
    },
    {
     "level": "GF",
     "a": [
      7800,
      8990
     ],
     "b": [
      7800,
      8540
     ]
    },
    {
     "level": "L1",
     "a": [
      7800,
      8540
     ],
     "b": [
      8100,
      8540
     ]
    },
    {
     "level": "L1",
     "a": [
      7800,
      8990
     ],
     "b": [
      7800,
      8540
     ]
    }
   ]
  },
  {
   "id": "SH-2",
   "profile": [
    [
     3865,
     12330
    ],
    [
     4165,
     12330
    ],
    [
     4165,
     12780
    ],
    [
     3865,
     12780
    ]
   ],
   "bottomLevel": "L1",
   "baseOffset": -470,
   "topLevel": "RF",
   "topOffset": 1000,
   "enclosed": [
    "GF",
    "L1"
   ],
   "contents": "Soil stack \u00d8110 from the shared bathroom (\u2192 septic tank under the GF slab) + grey-water stack \u00d875 (floor drain \u2192 rear pit) + vent \u00d875; exhaust duct \u00d8100 to a cowl above the rear terrace",
   "stacks": [
    {
     "kind": "soil",
     "dia": 110,
     "connectsTo": "SV-septic",
     "text": "Soil stack \u00d8110 \u2192 SV-septic Septic tank"
    },
    {
     "kind": "grey",
     "dia": 75,
     "connectsTo": "SV-mh-1",
     "text": "Grey-water stack \u00d875 \u2192 SV-mh-1 Rear inspection pit"
    },
    {
     "kind": "vent",
     "dia": 75,
     "connectsTo": "roof",
     "text": "Vent stack \u00d875 \u2192 roof (vent cowl above the terrace)"
    },
    {
     "kind": "exhaust",
     "dia": 100,
     "connectsTo": "roof",
     "text": "Exhaust duct \u00d8100 \u2192 roof (vent cowl above the terrace)"
    }
   ],
   "boxing": [
    {
     "level": "GF",
     "a": [
      3865,
      12330
     ],
     "b": [
      4165,
      12330
     ]
    },
    {
     "level": "GF",
     "a": [
      4165,
      12330
     ],
     "b": [
      4165,
      12780
     ]
    },
    {
     "level": "L1",
     "a": [
      3865,
      12330
     ],
     "b": [
      4165,
      12330
     ]
    },
    {
     "level": "L1",
     "a": [
      4165,
      12330
     ],
     "b": [
      4165,
      12780
     ]
    }
   ]
  },
  {
   "id": "SH-3",
   "profile": [
    [
     9480,
     9210
    ],
    [
     9780,
     9210
    ],
    [
     9780,
     9510
    ],
    [
     9480,
     9510
    ]
   ],
   "bottomLevel": "L1",
   "baseOffset": -170,
   "topLevel": "RF",
   "topOffset": 1200,
   "enclosed": [
    "GF",
    "L1"
   ],
   "contents": "Kitchen-hood duct \u00d8150 (\u2265 100 m\u00b3/h) rising to a cowl \u2265 1 m above the rear terrace, discharging upwards \u2014 never towards the street or a neighbour",
   "stacks": [
    {
     "kind": "exhaust",
     "dia": 150,
     "connectsTo": "roof",
     "text": "Exhaust duct \u00d8150 \u2192 roof (vent cowl above the terrace)"
    }
   ],
   "boxing": [
    {
     "level": "GF",
     "a": [
      9780,
      9510
     ],
     "b": [
      9480,
      9510
     ]
    },
    {
     "level": "GF",
     "a": [
      9480,
      9510
     ],
     "b": [
      9480,
      9210
     ]
    },
    {
     "level": "L1",
     "a": [
      9780,
      9510
     ],
     "b": [
      9480,
      9510
     ]
    },
    {
     "level": "L1",
     "a": [
      9480,
      9510
     ],
     "b": [
      9480,
      9210
     ]
    }
   ]
  }
 ],
 "openings": [
  {
   "id": "D-01",
   "kind": "door",
   "type": "D6",
   "family": "Door-Overhead-Rolling : 3200 x 2600",
   "wall": "GF-FRONT-AB",
   "level": "GF",
   "center": [
    1932,
    1260
   ],
   "p0": [
    332,
    1260
   ],
   "p1": [
    3532,
    1260
   ],
   "width": 3200,
   "height": 2600,
   "frameWidth": 3180,
   "frameHeight": 2590,
   "sill": -150,
   "head": 2450,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-02",
   "kind": "door",
   "type": "D1",
   "family": "Door-Double-Bifold 4-Leaf : 2000 x 2700",
   "wall": "GF-FRONT-BD",
   "level": "GF",
   "center": [
    5055,
    1260
   ],
   "p0": [
    4055,
    1260
   ],
   "p1": [
    6055,
    1260
   ],
   "width": 2000,
   "height": 2700,
   "frameWidth": 1980,
   "frameHeight": 2690,
   "sill": 0,
   "head": 2700,
   "swing": {
    "towards": [
     0,
     1
    ],
    "hinge": null,
    "bothJambs": true
   },
   "notes": ""
  },
  {
   "id": "W-01",
   "kind": "window",
   "type": "W3",
   "family": "Window-Fixed-Sliding : 2400 x 2200",
   "wall": "GF-FRONT-BD",
   "level": "GF",
   "center": [
    8120,
    1260
   ],
   "p0": [
    6920,
    1260
   ],
   "p1": [
    9320,
    1260
   ],
   "width": 2400,
   "height": 2200,
   "frameWidth": 2380,
   "frameHeight": 2180,
   "sill": 500,
   "head": 2700,
   "swing": null,
   "notes": ""
  },
  {
   "id": "W-02",
   "kind": "window",
   "type": "W1",
   "family": "Window-Casement-Double : 1400 x 1400",
   "wall": "GF-REAR",
   "level": "GF",
   "center": [
    1932,
    12890
   ],
   "p0": [
    1232,
    12890
   ],
   "p1": [
    2632,
    12890
   ],
   "width": 1400,
   "height": 1400,
   "frameWidth": 1380,
   "frameHeight": 1380,
   "sill": 900,
   "head": 2300,
   "swing": null,
   "notes": ""
  },
  {
   "id": "W-03",
   "kind": "window",
   "type": "W6",
   "family": "Window-Sliding-Double : 1600 x 1600",
   "wall": "GF-REAR",
   "level": "GF",
   "center": [
    5055,
    12890
   ],
   "p0": [
    4255,
    12890
   ],
   "p1": [
    5855,
    12890
   ],
   "width": 1600,
   "height": 1600,
   "frameWidth": 1580,
   "frameHeight": 1580,
   "sill": 800,
   "head": 2400,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-03",
   "kind": "door",
   "type": "D8",
   "family": "Door-Single-Glass : 900 x 2200",
   "wall": "GF-REAR",
   "level": "GF",
   "center": [
    7115,
    12890
   ],
   "p0": [
    6665,
    12890
   ],
   "p1": [
    7565,
    12890
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     0,
     -1
    ],
    "hinge": [
     6665,
     12890
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "W-04",
   "kind": "window",
   "type": "W4",
   "family": "Window-Sliding-Double : 1400 x 1100",
   "wall": "GF-REAR",
   "level": "GF",
   "center": [
    8600,
    12890
   ],
   "p0": [
    7900,
    12890
   ],
   "p1": [
    9300,
    12890
   ],
   "width": 1400,
   "height": 1100,
   "frameWidth": 1380,
   "frameHeight": 1080,
   "sill": 1100,
   "head": 2200,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-04",
   "kind": "door",
   "type": "D7",
   "family": "Door-Single-Panel-Fire : 900 x 2200",
   "wall": "GF-B-FRONT",
   "level": "GF",
   "center": [
    3755,
    6000
   ],
   "p0": [
    3755,
    5550
   ],
   "p1": [
    3755,
    6450
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     1,
     0
    ],
    "hinge": [
     3755,
     6450
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-05",
   "kind": "door",
   "type": "D2",
   "family": "Door-Single-Panel : 900 x 2200",
   "wall": "GF-B-REAR",
   "level": "GF",
   "center": [
    3755,
    9760
   ],
   "p0": [
    3755,
    9310
   ],
   "p1": [
    3755,
    10210
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     -1,
     0
    ],
    "hinge": [
     3755,
     9310
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-06",
   "kind": "door",
   "type": "D12",
   "family": "Door-Single-Panel : 900 x 2100",
   "wall": "GF-C-MID",
   "level": "GF",
   "center": [
    6355,
    7630
   ],
   "p0": [
    6355,
    7180
   ],
   "p1": [
    6355,
    8080
   ],
   "width": 900,
   "height": 2100,
   "frameWidth": 880,
   "frameHeight": 2090,
   "sill": 0,
   "head": 2100,
   "swing": {
    "towards": [
     -1,
     0
    ],
    "hinge": [
     6355,
     7180
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "OP-01",
   "kind": "opening",
   "type": "OP1",
   "family": "Opening-Cased : 2000 x 2400",
   "wall": "GF-2-BC",
   "level": "GF",
   "center": [
    5055,
    6780
   ],
   "p0": [
    4055,
    6780
   ],
   "p1": [
    6055,
    6780
   ],
   "width": 2000,
   "height": 2400,
   "frameWidth": 2000,
   "frameHeight": 2400,
   "sill": 0,
   "head": 2400,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-07",
   "kind": "door",
   "type": "D9",
   "family": "Door-Single-Panel : 700 x 2100",
   "wall": "GF-3-CD",
   "level": "GF",
   "center": [
    8660,
    9100
   ],
   "p0": [
    8310,
    9100
   ],
   "p1": [
    9010,
    9100
   ],
   "width": 700,
   "height": 2100,
   "frameWidth": 680,
   "frameHeight": 2090,
   "sill": 0,
   "head": 2100,
   "swing": {
    "towards": [
     0,
     -1
    ],
    "hinge": [
     9010,
     9100
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "W-11",
   "kind": "window",
   "type": "W2",
   "family": "Window-Casement-Triple : 1800 x 1500",
   "wall": "L1-FRONT-AB",
   "level": "L1",
   "center": [
    1932,
    1260
   ],
   "p0": [
    1032,
    1260
   ],
   "p1": [
    2832,
    1260
   ],
   "width": 1800,
   "height": 1500,
   "frameWidth": 1780,
   "frameHeight": 1480,
   "sill": 900,
   "head": 2400,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-11",
   "kind": "door",
   "type": "D4",
   "family": "Door-Sliding-2 Panel : 2000 x 2400",
   "wall": "L1-FRONT-LOGGIA",
   "level": "L1",
   "center": [
    5055,
    2680
   ],
   "p0": [
    4055,
    2680
   ],
   "p1": [
    6055,
    2680
   ],
   "width": 2000,
   "height": 2400,
   "frameWidth": 1980,
   "frameHeight": 2390,
   "sill": 0,
   "head": 2400,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-12",
   "kind": "door",
   "type": "D5",
   "family": "Door-Sliding-2 Panel : 2400 x 2400",
   "wall": "L1-FRONT-LOGGIA",
   "level": "L1",
   "center": [
    8120,
    2680
   ],
   "p0": [
    6920,
    2680
   ],
   "p1": [
    9320,
    2680
   ],
   "width": 2400,
   "height": 2400,
   "frameWidth": 2380,
   "frameHeight": 2390,
   "sill": 0,
   "head": 2400,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-13",
   "kind": "door",
   "type": "D2",
   "family": "Door-Single-Panel : 900 x 2200",
   "wall": "L1-B-FRONT",
   "level": "L1",
   "center": [
    3755,
    6000
   ],
   "p0": [
    3755,
    5550
   ],
   "p1": [
    3755,
    6450
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     -1,
     0
    ],
    "hinge": [
     3755,
     6450
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-14",
   "kind": "door",
   "type": "D2",
   "family": "Door-Single-Panel : 900 x 2200",
   "wall": "L1-C-FRONT",
   "level": "L1",
   "center": [
    6355,
    6000
   ],
   "p0": [
    6355,
    5550
   ],
   "p1": [
    6355,
    6450
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     1,
     0
    ],
    "hinge": [
     6355,
     6450
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "OP-11",
   "kind": "opening",
   "type": "OP2",
   "family": "Opening-Cased : 800 x 2200",
   "wall": "L1-2-CD",
   "level": "L1",
   "center": [
    8710,
    6780
   ],
   "p0": [
    8310,
    6780
   ],
   "p1": [
    9110,
    6780
   ],
   "width": 800,
   "height": 2200,
   "frameWidth": 800,
   "frameHeight": 2200,
   "sill": 0,
   "head": 2200,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-15",
   "kind": "door",
   "type": "D3",
   "family": "Door-Single-Panel : 750 x 2100",
   "wall": "L1-P-BATH",
   "level": "L1",
   "center": [
    8155,
    7555
   ],
   "p0": [
    8155,
    7180
   ],
   "p1": [
    8155,
    7930
   ],
   "width": 750,
   "height": 2100,
   "frameWidth": 730,
   "frameHeight": 2090,
   "sill": 0,
   "head": 2100,
   "swing": {
    "towards": [
     -1,
     0
    ],
    "hinge": [
     8155,
     7180
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-16",
   "kind": "door",
   "type": "D2",
   "family": "Door-Single-Panel : 900 x 2200",
   "wall": "L1-B-REAR",
   "level": "L1",
   "center": [
    3755,
    9760
   ],
   "p0": [
    3755,
    9310
   ],
   "p1": [
    3755,
    10210
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     -1,
     0
    ],
    "hinge": [
     3755,
     9310
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-17",
   "kind": "door",
   "type": "D2",
   "family": "Door-Single-Panel : 900 x 2200",
   "wall": "L1-C-REAR",
   "level": "L1",
   "center": [
    6355,
    9760
   ],
   "p0": [
    6355,
    9310
   ],
   "p1": [
    6355,
    10210
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     1,
     0
    ],
    "hinge": [
     6355,
     9310
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-18",
   "kind": "door",
   "type": "D3",
   "family": "Door-Single-Panel : 750 x 2100",
   "wall": "L1-P-SHBATH",
   "level": "L1",
   "center": [
    5055,
    10365
   ],
   "p0": [
    4680,
    10365
   ],
   "p1": [
    5430,
    10365
   ],
   "width": 750,
   "height": 2100,
   "frameWidth": 730,
   "frameHeight": 2090,
   "sill": 0,
   "head": 2100,
   "swing": {
    "towards": [
     0,
     1
    ],
    "hinge": [
     4680,
     10365
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "W-12",
   "kind": "window",
   "type": "W1",
   "family": "Window-Casement-Double : 1400 x 1400",
   "wall": "L1-REAR",
   "level": "L1",
   "center": [
    1932,
    12890
   ],
   "p0": [
    1232,
    12890
   ],
   "p1": [
    2632,
    12890
   ],
   "width": 1400,
   "height": 1400,
   "frameWidth": 1380,
   "frameHeight": 1380,
   "sill": 900,
   "head": 2300,
   "swing": null,
   "notes": ""
  },
  {
   "id": "W-13",
   "kind": "window",
   "type": "W5",
   "family": "Window-Awning : 900 x 700",
   "wall": "L1-REAR",
   "level": "L1",
   "center": [
    5695,
    12890
   ],
   "p0": [
    5245,
    12890
   ],
   "p1": [
    6145,
    12890
   ],
   "width": 900,
   "height": 700,
   "frameWidth": 880,
   "frameHeight": 680,
   "sill": 1500,
   "head": 2200,
   "swing": null,
   "notes": ""
  },
  {
   "id": "W-14",
   "kind": "window",
   "type": "W1",
   "family": "Window-Casement-Double : 1400 x 1400",
   "wall": "L1-REAR",
   "level": "L1",
   "center": [
    8122,
    12890
   ],
   "p0": [
    7422,
    12890
   ],
   "p1": [
    8822,
    12890
   ],
   "width": 1400,
   "height": 1400,
   "frameWidth": 1380,
   "frameHeight": 1380,
   "sill": 900,
   "head": 2300,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-21",
   "kind": "door",
   "type": "D10",
   "family": "Door-Double-Glass : 1400 x 2400",
   "wall": "RF-T-FRONT",
   "level": "RF",
   "center": [
    1932,
    4400
   ],
   "p0": [
    1232,
    4400
   ],
   "p1": [
    2632,
    4400
   ],
   "width": 1400,
   "height": 2400,
   "frameWidth": 1380,
   "frameHeight": 2390,
   "sill": 100,
   "head": 2500,
   "swing": {
    "towards": [
     0,
     1
    ],
    "hinge": null,
    "bothJambs": true
   },
   "notes": "Over a 100 mm waterproofed kerb (g\u1edd ch\u1eb7n n\u01b0\u1edbc) \u2014 the terrace is outside"
  },
  {
   "id": "W-21",
   "kind": "window",
   "type": "W1",
   "family": "Window-Casement-Double : 1400 x 1400",
   "wall": "RF-T-FRONT",
   "level": "RF",
   "center": [
    5000,
    4400
   ],
   "p0": [
    4300,
    4400
   ],
   "p1": [
    5700,
    4400
   ],
   "width": 1400,
   "height": 1400,
   "frameWidth": 1380,
   "frameHeight": 1380,
   "sill": 900,
   "head": 2300,
   "swing": null,
   "notes": ""
  },
  {
   "id": "D-22",
   "kind": "door",
   "type": "D2",
   "family": "Door-Single-Panel : 900 x 2200",
   "wall": "RF-T-2",
   "level": "RF",
   "center": [
    5055,
    6780
   ],
   "p0": [
    4605,
    6780
   ],
   "p1": [
    5505,
    6780
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 0,
   "head": 2200,
   "swing": {
    "towards": [
     0,
     -1
    ],
    "hinge": [
     4605,
     6780
    ],
    "bothJambs": false
   },
   "notes": ""
  },
  {
   "id": "D-23",
   "kind": "door",
   "type": "D11",
   "family": "Door-Single-Glass : 900 x 2200",
   "wall": "RF-T-REAR",
   "level": "RF",
   "center": [
    5055,
    9100
   ],
   "p0": [
    4605,
    9100
   ],
   "p1": [
    5505,
    9100
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 100,
   "head": 2300,
   "swing": {
    "towards": [
     0,
     -1
    ],
    "hinge": [
     5505,
     9100
    ],
    "bothJambs": false
   },
   "notes": "Over a 100 mm waterproofed kerb"
  },
  {
   "id": "D-24",
   "kind": "door",
   "type": "D11",
   "family": "Door-Single-Glass : 900 x 2200",
   "wall": "RF-T-RIGHT",
   "level": "RF",
   "center": [
    6355,
    7940
   ],
   "p0": [
    6355,
    7490
   ],
   "p1": [
    6355,
    8390
   ],
   "width": 900,
   "height": 2200,
   "frameWidth": 880,
   "frameHeight": 2190,
   "sill": 100,
   "head": 2300,
   "swing": {
    "towards": [
     -1,
     0
    ],
    "hinge": [
     6355,
     7490
    ],
    "bothJambs": false
   },
   "notes": "Stair hall \u2192 side terrace, so the front garden is reached without passing through the altar room"
  }
 ],
 "rooms": [
  {
   "id": "0.01",
   "level": "GF",
   "name": "Garage",
   "nameVi": "Gara \u00f4 t\u00f4",
   "point": [
    1932.5,
    4020
   ],
   "area": 18.15,
   "floorOffset": -150
  },
  {
   "id": "0.02",
   "level": "GF",
   "name": "Living room",
   "nameVi": "Ph\u00f2ng kh\u00e1ch",
   "point": [
    6822.5,
    4020
   ],
   "area": 31.35,
   "floorOffset": 0
  },
  {
   "id": "0.03",
   "level": "GF",
   "name": "Stair",
   "nameVi": "C\u1ea7u thang",
   "point": [
    2260,
    7940
   ],
   "area": 8.57,
   "floorOffset": 0
  },
  {
   "id": "0.04",
   "level": "GF",
   "name": "Hall",
   "nameVi": "S\u1ea3nh c\u1ea7u thang",
   "point": [
    5272.5,
    7940
   ],
   "area": 4.08,
   "floorOffset": 0
  },
  {
   "id": "0.05",
   "level": "GF",
   "name": "WC / shower",
   "nameVi": "V\u1ec7 sinh t\u1ea7ng tr\u1ec7t",
   "point": [
    7255.18,
    7906.23
   ],
   "area": 3.3,
   "floorOffset": 0
  },
  {
   "id": "0.06",
   "level": "GF",
   "name": "Pantry / store",
   "nameVi": "Kho",
   "point": [
    8995,
    7940
   ],
   "area": 3.3,
   "floorOffset": 0
  },
  {
   "id": "0.07",
   "level": "GF",
   "name": "Dining",
   "nameVi": "Ph\u00f2ng \u0103n",
   "point": [
    5126.89,
    10970.94
   ],
   "area": 8.75,
   "floorOffset": 0
  },
  {
   "id": "0.08",
   "level": "GF",
   "name": "Kitchen",
   "nameVi": "B\u1ebfp",
   "point": [
    8055.91,
    11007.12
   ],
   "area": 12.14,
   "floorOffset": 0
  },
  {
   "id": "0.09",
   "level": "GF",
   "name": "Bedroom 1 (grandparents)",
   "nameVi": "Ph\u00f2ng ng\u1ee7 1 (\u00f4ng b\u00e0)",
   "point": [
    1932.5,
    10995
   ],
   "area": 12.23,
   "floorOffset": 0
  },
  {
   "id": "1.01",
   "level": "L1",
   "name": "Bedroom 2",
   "nameVi": "Ph\u00f2ng ng\u1ee7 2",
   "point": [
    1932.5,
    4020
   ],
   "area": 18.15,
   "floorOffset": 0
  },
  {
   "id": "1.02",
   "level": "L1",
   "name": "Family lounge",
   "nameVi": "Ph\u00f2ng sinh ho\u1ea1t chung",
   "point": [
    5055,
    4730
   ],
   "area": 9.23,
   "floorOffset": 0
  },
  {
   "id": "1.03",
   "level": "L1",
   "name": "Loggia",
   "nameVi": "L\u00f4 gia",
   "point": [
    6822.5,
    1970
   ],
   "area": 7.1,
   "floorOffset": -50
  },
  {
   "id": "1.04",
   "level": "L1",
   "name": "Master bedroom",
   "nameVi": "Ph\u00f2ng ng\u1ee7 ch\u00ednh",
   "point": [
    8122.5,
    4730
   ],
   "area": 12.86,
   "floorOffset": 0
  },
  {
   "id": "1.05",
   "level": "L1",
   "name": "Walk-in closet",
   "nameVi": "Ph\u00f2ng thay \u0111\u1ed3",
   "point": [
    8995,
    7940
   ],
   "area": 3.3,
   "floorOffset": 0
  },
  {
   "id": "1.06",
   "level": "L1",
   "name": "Master bathroom",
   "nameVi": "V\u1ec7 sinh ph\u00f2ng ng\u1ee7 ch\u00ednh",
   "point": [
    7255.18,
    7906.23
   ],
   "area": 3.3,
   "floorOffset": -20
  },
  {
   "id": "1.07",
   "level": "L1",
   "name": "Stair",
   "nameVi": "C\u1ea7u thang",
   "point": [
    2260,
    7940
   ],
   "area": 8.57,
   "floorOffset": 0
  },
  {
   "id": "1.08",
   "level": "L1",
   "name": "Hall",
   "nameVi": "S\u1ea3nh l\u1ea7u 1",
   "point": [
    5272.5,
    7940
   ],
   "area": 4.08,
   "floorOffset": 0
  },
  {
   "id": "1.09",
   "level": "L1",
   "name": "Passage",
   "nameVi": "H\u00e0nh lang",
   "point": [
    5055,
    9760
   ],
   "area": 2.62,
   "floorOffset": 0
  },
  {
   "id": "1.10",
   "level": "L1",
   "name": "Shared bathroom",
   "nameVi": "V\u1ec7 sinh chung",
   "point": [
    5080.61,
    11576.48
   ],
   "area": 5.48,
   "floorOffset": -20
  },
  {
   "id": "1.11",
   "level": "L1",
   "name": "Bedroom 3",
   "nameVi": "Ph\u00f2ng ng\u1ee7 3",
   "point": [
    1932.5,
    10995
   ],
   "area": 12.23,
   "floorOffset": 0
  },
  {
   "id": "1.12",
   "level": "L1",
   "name": "Bedroom 4 / study",
   "nameVi": "Ph\u00f2ng ng\u1ee7 4 / ph\u00f2ng l\u00e0m vi\u1ec7c",
   "point": [
    8110.95,
    11007.53
   ],
   "area": 11.74,
   "floorOffset": 0
  },
  {
   "id": "2.01",
   "level": "RF",
   "name": "Altar room",
   "nameVi": "Ph\u00f2ng th\u1edd",
   "point": [
    3232.5,
    5590
   ],
   "area": 13.01,
   "floorOffset": 0
  },
  {
   "id": "2.02",
   "level": "RF",
   "name": "Stair",
   "nameVi": "C\u1ea7u thang",
   "point": [
    2260,
    7940
   ],
   "area": 8.57,
   "floorOffset": 0
  },
  {
   "id": "2.03",
   "level": "RF",
   "name": "Stair hall",
   "nameVi": "S\u1ea3nh tum",
   "point": [
    5272.5,
    7940
   ],
   "area": 4.08,
   "floorOffset": 0
  },
  {
   "id": "2.04",
   "level": "RF",
   "name": "Front terrace / garden",
   "nameVi": "S\u00e2n th\u01b0\u1ee3ng tr\u01b0\u1edbc",
   "point": [
    5000,
    2830
   ],
   "area": 27.92,
   "floorOffset": 0
  },
  {
   "id": "2.05",
   "level": "RF",
   "name": "Side terrace",
   "nameVi": "S\u00e2n th\u01b0\u1ee3ng b\u00ean",
   "point": [
    8122.5,
    6750
   ],
   "area": 16.31,
   "floorOffset": 0
  },
  {
   "id": "2.06",
   "level": "RF",
   "name": "Rear terrace / laundry",
   "nameVi": "S\u00e2n ph\u01a1i / gi\u1eb7t",
   "point": [
    5000,
    10995
   ],
   "area": 34.13,
   "floorOffset": 0
  }
 ],
 "separations": [
  {
   "level": "GF",
   "a": [
    4165,
    12330
   ],
   "b": [
    4165,
    12780
   ]
  },
  {
   "level": "GF",
   "a": [
    4300,
    6890
   ],
   "b": [
    4300,
    8990
   ]
  },
  {
   "level": "GF",
   "a": [
    6355,
    9210
   ],
   "b": [
    6355,
    12780
   ]
  },
  {
   "level": "GF",
   "a": [
    7800,
    8540
   ],
   "b": [
    7800,
    8990
   ]
  },
  {
   "level": "GF",
   "a": [
    9480,
    9210
   ],
   "b": [
    9480,
    9510
   ]
  },
  {
   "level": "GF",
   "a": [
    7800,
    8540
   ],
   "b": [
    8100,
    8540
   ]
  },
  {
   "level": "GF",
   "a": [
    3865,
    8990
   ],
   "b": [
    6245,
    8990
   ]
  },
  {
   "level": "GF",
   "a": [
    3865,
    9210
   ],
   "b": [
    6245,
    9210
   ]
  },
  {
   "level": "GF",
   "a": [
    9480,
    9510
   ],
   "b": [
    9780,
    9510
   ]
  },
  {
   "level": "GF",
   "a": [
    3865,
    12330
   ],
   "b": [
    4165,
    12330
   ]
  },
  {
   "level": "L1",
   "a": [
    4165,
    12330
   ],
   "b": [
    4165,
    12780
   ]
  },
  {
   "level": "L1",
   "a": [
    4300,
    6890
   ],
   "b": [
    4300,
    8990
   ]
  },
  {
   "level": "L1",
   "a": [
    7800,
    8540
   ],
   "b": [
    7800,
    8990
   ]
  },
  {
   "level": "L1",
   "a": [
    9480,
    9210
   ],
   "b": [
    9480,
    9510
   ]
  },
  {
   "level": "L1",
   "a": [
    3865,
    1370
   ],
   "b": [
    6245,
    1370
   ]
  },
  {
   "level": "L1",
   "a": [
    6465,
    1370
   ],
   "b": [
    9780,
    1370
   ]
  },
  {
   "level": "L1",
   "a": [
    3865,
    6670
   ],
   "b": [
    6245,
    6670
   ]
  },
  {
   "level": "L1",
   "a": [
    3865,
    6890
   ],
   "b": [
    6245,
    6890
   ]
  },
  {
   "level": "L1",
   "a": [
    7800,
    8540
   ],
   "b": [
    8100,
    8540
   ]
  },
  {
   "level": "L1",
   "a": [
    3865,
    8990
   ],
   "b": [
    6245,
    8990
   ]
  },
  {
   "level": "L1",
   "a": [
    3865,
    9210
   ],
   "b": [
    6245,
    9210
   ]
  },
  {
   "level": "L1",
   "a": [
    9480,
    9510
   ],
   "b": [
    9780,
    9510
   ]
  },
  {
   "level": "L1",
   "a": [
    3865,
    12330
   ],
   "b": [
    4165,
    12330
   ]
  },
  {
   "level": "RF",
   "a": [
    4300,
    6890
   ],
   "b": [
    4300,
    8990
   ]
  },
  {
   "level": "RF",
   "a": [
    6465,
    4290
   ],
   "b": [
    9780,
    4290
   ]
  },
  {
   "level": "RF",
   "a": [
    6465,
    9210
   ],
   "b": [
    9780,
    9210
   ]
  }
 ],
 "columns": [
  {
   "id": "A/1",
   "mark": "C-GF-A/1",
   "point": [
    110,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -200,
   "on": "GB-1/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "A/2",
   "mark": "C-GF-A/2",
   "point": [
    110,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-2/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "A/3",
   "mark": "C-GF-A/3",
   "point": [
    110,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-3/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "A/4",
   "mark": "C-GF-A/4",
   "point": [
    110,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-4/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "B/1",
   "mark": "C-GF-B/1",
   "point": [
    3755,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -200,
   "on": "GB-1/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -100
  },
  {
   "id": "B/2",
   "mark": "C-GF-B/2",
   "point": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-2/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "B/3",
   "mark": "C-GF-B/3",
   "point": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-3/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "B/4",
   "mark": "C-GF-B/4",
   "point": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-4/A-B",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "C/1",
   "mark": "C-GF-C/1",
   "point": [
    6355,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-1/B-C",
   "topLevel": "L1",
   "topOffset": -220,
   "beamTopOffset": -100
  },
  {
   "id": "C/2",
   "mark": "C-GF-C/2",
   "point": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-2/B-C",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "C/3",
   "mark": "C-GF-C/3",
   "point": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-3/B-C",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "C/4",
   "mark": "C-GF-C/4",
   "point": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-4/B-C",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "D/1",
   "mark": "C-GF-D/1",
   "point": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-1/C-D",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -100
  },
  {
   "id": "D/2",
   "mark": "C-GF-D/2",
   "point": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-2/C-D",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "D/3",
   "mark": "C-GF-D/3",
   "point": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-3/C-D",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "D/4",
   "mark": "C-GF-D/4",
   "point": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-4/C-D",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "A/1",
   "mark": "C-L1-A/1",
   "point": [
    110,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-1/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "A/2",
   "mark": "C-L1-A/2",
   "point": [
    110,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-2/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "A/3",
   "mark": "C-L1-A/3",
   "point": [
    110,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-3/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "A/4",
   "mark": "C-L1-A/4",
   "point": [
    110,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-4/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "B/1",
   "mark": "C-L1-B/1",
   "point": [
    3755,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -100,
   "on": "B-L1-1/B-C",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "B/2",
   "mark": "C-L1-B/2",
   "point": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-2/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "B/3",
   "mark": "C-L1-B/3",
   "point": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-3/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "B/4",
   "mark": "C-L1-B/4",
   "point": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-4/A-B",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "C/1",
   "mark": "C-L1-C/1",
   "point": [
    6355,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -100,
   "on": "B-L1-1/B-C",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "C/2",
   "mark": "C-L1-C/2",
   "point": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-2/B-C",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "C/3",
   "mark": "C-L1-C/3",
   "point": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-3/B-C",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "C/4",
   "mark": "C-L1-C/4",
   "point": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-4/B-C",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "D/1",
   "mark": "C-L1-D/1",
   "point": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -100,
   "on": "B-L1-1/C-D",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "D/2",
   "mark": "C-L1-D/2",
   "point": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-2/C-D",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "D/3",
   "mark": "C-L1-D/3",
   "point": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-3/C-D",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "D/4",
   "mark": "C-L1-D/4",
   "point": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-4/C-D",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "A/1a",
   "mark": "C-GF-A/1a",
   "point": [
    110,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-A/1-1a",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "B/1a",
   "mark": "C-GF-B/1a",
   "point": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "GF",
   "baseOffset": -150,
   "on": "GB-B/1-1a",
   "topLevel": "L1",
   "topOffset": -170,
   "beamTopOffset": -50
  },
  {
   "id": "A/1a",
   "mark": "C-L1-A/1a",
   "point": [
    110,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-A/1-1a",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "B/1a",
   "mark": "C-L1-B/1a",
   "point": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "L1",
   "baseOffset": -50,
   "on": "B-L1-B/1-1a",
   "topLevel": "RF",
   "topOffset": -250,
   "beamTopOffset": -130
  },
  {
   "id": "A/1a",
   "mark": "C-RF-A/1a",
   "point": [
    110,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-A/1-1a",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "B/1a",
   "mark": "C-RF-B/1a",
   "point": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-B/1-1a",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "C/1a",
   "mark": "C-RF-C/1a",
   "point": [
    6355,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-C/1-2",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "A/2",
   "mark": "C-RF-A/2",
   "point": [
    110,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-2/A-B",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "B/2",
   "mark": "C-RF-B/2",
   "point": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-2/A-B",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "C/2",
   "mark": "C-RF-C/2",
   "point": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-2/B-C",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "A/3",
   "mark": "C-RF-A/3",
   "point": [
    110,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-3/A-B",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "B/3",
   "mark": "C-RF-B/3",
   "point": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-3/A-B",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  },
  {
   "id": "C/3",
   "mark": "C-RF-C/3",
   "point": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "C1 220 x 220",
   "baseLevel": "RF",
   "baseOffset": -130,
   "on": "B-RF-3/B-C",
   "topLevel": "TR",
   "topOffset": -290,
   "beamTopOffset": -170
  }
 ],
 "beams": [
  {
   "id": "GB-1/A-B",
   "level": "GF",
   "start": [
    110,
    1260
   ],
   "end": [
    3755,
    1260
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -200,
   "notes": ""
  },
  {
   "id": "GB-1/B-C",
   "level": "GF",
   "start": [
    3755,
    1260
   ],
   "end": [
    6355,
    1260
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-1/C-D",
   "level": "GF",
   "start": [
    6355,
    1260
   ],
   "end": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-2/A-B",
   "level": "GF",
   "start": [
    110,
    6780
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-2/B-C",
   "level": "GF",
   "start": [
    3755,
    6780
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-2/C-D",
   "level": "GF",
   "start": [
    6355,
    6780
   ],
   "end": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-3/A-B",
   "level": "GF",
   "start": [
    110,
    9100
   ],
   "end": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-3/B-C",
   "level": "GF",
   "start": [
    3755,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-3/C-D",
   "level": "GF",
   "start": [
    6355,
    9100
   ],
   "end": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-4/A-B",
   "level": "GF",
   "start": [
    110,
    12890
   ],
   "end": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-4/B-C",
   "level": "GF",
   "start": [
    3755,
    12890
   ],
   "end": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-4/C-D",
   "level": "GF",
   "start": [
    6355,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-A/1-1a",
   "level": "GF",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    4400
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-A/1a-2",
   "level": "GF",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    6780
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-A/2-3",
   "level": "GF",
   "start": [
    110,
    6780
   ],
   "end": [
    110,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-A/3-4",
   "level": "GF",
   "start": [
    110,
    9100
   ],
   "end": [
    110,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-B/1-1a",
   "level": "GF",
   "start": [
    3755,
    1260
   ],
   "end": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-B/1a-2",
   "level": "GF",
   "start": [
    3755,
    4400
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-B/2-3",
   "level": "GF",
   "start": [
    3755,
    6780
   ],
   "end": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-B/3-4",
   "level": "GF",
   "start": [
    3755,
    9100
   ],
   "end": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-C/1-2",
   "level": "GF",
   "start": [
    6355,
    1260
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 600,
   "kind": "ground",
   "typeName": "220 x 600",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-C/2-3",
   "level": "GF",
   "start": [
    6355,
    6780
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-C/3-4",
   "level": "GF",
   "start": [
    6355,
    9100
   ],
   "end": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-D/1-2",
   "level": "GF",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 600,
   "kind": "ground",
   "typeName": "220 x 600",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-D/2-3",
   "level": "GF",
   "start": [
    9890,
    6780
   ],
   "end": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "GB-D/3-4",
   "level": "GF",
   "start": [
    9890,
    9100
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 400,
   "kind": "ground",
   "typeName": "220 x 400",
   "topOffset": -150,
   "notes": ""
  },
  {
   "id": "B-L1-1/A-B",
   "level": "L1",
   "start": [
    110,
    1260
   ],
   "end": [
    3755,
    1260
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-1/B-C",
   "level": "L1",
   "start": [
    3755,
    1260
   ],
   "end": [
    6355,
    1260
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -100,
   "notes": ""
  },
  {
   "id": "B-L1-1/C-D",
   "level": "L1",
   "start": [
    6355,
    1260
   ],
   "end": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -100,
   "notes": ""
  },
  {
   "id": "B-L1-2/A-B",
   "level": "L1",
   "start": [
    110,
    6780
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-2/B-C",
   "level": "L1",
   "start": [
    3755,
    6780
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-2/C-D",
   "level": "L1",
   "start": [
    6355,
    6780
   ],
   "end": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames a sunken bathroom slab (drop 300)"
  },
  {
   "id": "B-L1-3/A-B",
   "level": "L1",
   "start": [
    110,
    9100
   ],
   "end": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-3/B-C",
   "level": "L1",
   "start": [
    3755,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-3/C-D",
   "level": "L1",
   "start": [
    6355,
    9100
   ],
   "end": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames a sunken bathroom slab (drop 300)"
  },
  {
   "id": "B-L1-4/A-B",
   "level": "L1",
   "start": [
    110,
    12890
   ],
   "end": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-4/B-C",
   "level": "L1",
   "start": [
    3755,
    12890
   ],
   "end": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames a sunken bathroom slab (drop 300)"
  },
  {
   "id": "B-L1-4/C-D",
   "level": "L1",
   "start": [
    6355,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-A/1-1a",
   "level": "L1",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    4400
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-A/1a-2",
   "level": "L1",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-A/2-3",
   "level": "L1",
   "start": [
    110,
    6780
   ],
   "end": [
    110,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-A/3-4",
   "level": "L1",
   "start": [
    110,
    9100
   ],
   "end": [
    110,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-B/1-1a",
   "level": "L1",
   "start": [
    3755,
    1260
   ],
   "end": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-B/1a-2",
   "level": "L1",
   "start": [
    3755,
    4400
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-B/3-4",
   "level": "L1",
   "start": [
    3755,
    9100
   ],
   "end": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames a sunken bathroom slab (drop 300)"
  },
  {
   "id": "B-L1-C/1-2a",
   "level": "L1",
   "start": [
    6355,
    1260
   ],
   "end": [
    6355,
    2680
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -100,
   "notes": "Loggia part of the grid-C beam 1\u20132 (continuous with B-L1-C/1-2b); its top follows the lowered loggia slab"
  },
  {
   "id": "B-L1-C/1-2b",
   "level": "L1",
   "start": [
    6355,
    2680
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Continuous with B-L1-C/1-2a; carries secondary beam BS-L1-01 and wall L1-C-FRONT"
  },
  {
   "id": "B-L1-C/2-3",
   "level": "L1",
   "start": [
    6355,
    6780
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames a sunken bathroom slab (drop 300)"
  },
  {
   "id": "B-L1-C/3-4",
   "level": "L1",
   "start": [
    6355,
    9100
   ],
   "end": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames a sunken bathroom slab (drop 300)"
  },
  {
   "id": "B-L1-D/1-2",
   "level": "L1",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-D/2-3",
   "level": "L1",
   "start": [
    9890,
    6780
   ],
   "end": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-L1-D/3-4",
   "level": "L1",
   "start": [
    9890,
    9100
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": ""
  },
  {
   "id": "B-RF-1/A-B",
   "level": "RF",
   "start": [
    110,
    1260
   ],
   "end": [
    3755,
    1260
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-1/B-C",
   "level": "RF",
   "start": [
    3755,
    1260
   ],
   "end": [
    6355,
    1260
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-1/C-D",
   "level": "RF",
   "start": [
    6355,
    1260
   ],
   "end": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-2/A-B",
   "level": "RF",
   "start": [
    110,
    6780
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-2/B-C",
   "level": "RF",
   "start": [
    3755,
    6780
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-2/C-D",
   "level": "RF",
   "start": [
    6355,
    6780
   ],
   "end": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-3/A-B",
   "level": "RF",
   "start": [
    110,
    9100
   ],
   "end": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-3/B-C",
   "level": "RF",
   "start": [
    3755,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-3/C-D",
   "level": "RF",
   "start": [
    6355,
    9100
   ],
   "end": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-4/A-B",
   "level": "RF",
   "start": [
    110,
    12890
   ],
   "end": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-4/B-C",
   "level": "RF",
   "start": [
    3755,
    12890
   ],
   "end": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-4/C-D",
   "level": "RF",
   "start": [
    6355,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-A/1-1a",
   "level": "RF",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    4400
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-A/1a-2",
   "level": "RF",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-A/2-3",
   "level": "RF",
   "start": [
    110,
    6780
   ],
   "end": [
    110,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-A/3-4",
   "level": "RF",
   "start": [
    110,
    9100
   ],
   "end": [
    110,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-B/1-1a",
   "level": "RF",
   "start": [
    3755,
    1260
   ],
   "end": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-B/1a-2",
   "level": "RF",
   "start": [
    3755,
    4400
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-B/3-4",
   "level": "RF",
   "start": [
    3755,
    9100
   ],
   "end": [
    3755,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-C/1-2",
   "level": "RF",
   "start": [
    6355,
    1260
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 600,
   "kind": "main",
   "typeName": "220 x 600",
   "topOffset": -130,
   "notes": "Transfer beam: carries column C/1a mid-span"
  },
  {
   "id": "B-RF-C/2-3",
   "level": "RF",
   "start": [
    6355,
    6780
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-C/3-4",
   "level": "RF",
   "start": [
    6355,
    9100
   ],
   "end": [
    6355,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-D/1-2",
   "level": "RF",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    6780
   ],
   "width": 220,
   "depth": 500,
   "kind": "main",
   "typeName": "220 x 500",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-D/2-3",
   "level": "RF",
   "start": [
    9890,
    6780
   ],
   "end": [
    9890,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "B-RF-D/3-4",
   "level": "RF",
   "start": [
    9890,
    9100
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": ""
  },
  {
   "id": "BS-L1-04",
   "level": "L1",
   "start": [
    8210,
    6780
   ],
   "end": [
    8210,
    9100
   ],
   "width": 220,
   "depth": 500,
   "kind": "secondary",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Frames the sunken master-bathroom slab on its face (clear of SH-1) and carries the 110 partition"
  },
  {
   "id": "BS-L1-01",
   "level": "L1",
   "start": [
    3755,
    2680
   ],
   "end": [
    9890,
    2680
   ],
   "width": 220,
   "depth": 350,
   "kind": "secondary",
   "typeName": "220 x 350",
   "topOffset": -50,
   "notes": "Carries recessed L1 front wall behind loggia"
  },
  {
   "id": "BS-L1-02",
   "level": "L1",
   "start": [
    4410,
    6780
   ],
   "end": [
    4410,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "secondary",
   "typeName": "220 x 300",
   "topOffset": -50,
   "notes": "Stair opening edge beam"
  },
  {
   "id": "BS-L1-03",
   "level": "L1",
   "start": [
    3755,
    10310
   ],
   "end": [
    6355,
    10310
   ],
   "width": 220,
   "depth": 500,
   "kind": "secondary",
   "typeName": "220 x 500",
   "topOffset": -50,
   "notes": "Carries the 110 partition and frames the sunken shared-bathroom slab"
  },
  {
   "id": "BS-RF-01",
   "level": "RF",
   "start": [
    110,
    4400
   ],
   "end": [
    6355,
    4400
   ],
   "width": 220,
   "depth": 350,
   "kind": "secondary",
   "typeName": "220 x 350",
   "topOffset": -130,
   "notes": "Carries the tum front wall; columns A/1a and B/1a below, C/1a on transfer beam B-RF-C/1-2"
  },
  {
   "id": "BS-RF-02",
   "level": "RF",
   "start": [
    4410,
    6780
   ],
   "end": [
    4410,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "secondary",
   "typeName": "220 x 300",
   "topOffset": -130,
   "notes": "Stair opening edge beam"
  },
  {
   "id": "B-TR-1a/A-B",
   "level": "TR",
   "start": [
    110,
    4400
   ],
   "end": [
    3755,
    4400
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-1a/B-C",
   "level": "TR",
   "start": [
    3755,
    4400
   ],
   "end": [
    6355,
    4400
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-2/A-B",
   "level": "TR",
   "start": [
    110,
    6780
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-2/B-C",
   "level": "TR",
   "start": [
    3755,
    6780
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-3/A-B",
   "level": "TR",
   "start": [
    110,
    9100
   ],
   "end": [
    3755,
    9100
   ],
   "width": 220,
   "depth": 350,
   "kind": "main",
   "typeName": "220 x 350",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-3/B-C",
   "level": "TR",
   "start": [
    3755,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-A/1a-2",
   "level": "TR",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-A/2-3",
   "level": "TR",
   "start": [
    110,
    6780
   ],
   "end": [
    110,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-B/1a-2",
   "level": "TR",
   "start": [
    3755,
    4400
   ],
   "end": [
    3755,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-C/1a-2",
   "level": "TR",
   "start": [
    6355,
    4400
   ],
   "end": [
    6355,
    6780
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  },
  {
   "id": "B-TR-C/2-3",
   "level": "TR",
   "start": [
    6355,
    6780
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 300,
   "kind": "main",
   "typeName": "220 x 300",
   "topOffset": -170,
   "notes": ""
  }
 ],
 "copings": [
  {
   "id": "CP-RF-P-FRONT",
   "wall": "RF-P-FRONT",
   "level": "RF",
   "start": [
    110,
    1260
   ],
   "end": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 1100
  },
  {
   "id": "CP-RF-P-LEFT-F",
   "wall": "RF-P-LEFT-F",
   "level": "RF",
   "start": [
    110,
    1260
   ],
   "end": [
    110,
    4400
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 1100
  },
  {
   "id": "CP-RF-P-LEFT-R",
   "wall": "RF-P-LEFT-R",
   "level": "RF",
   "start": [
    110,
    9100
   ],
   "end": [
    110,
    12890
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 1100
  },
  {
   "id": "CP-RF-P-RIGHT",
   "wall": "RF-P-RIGHT",
   "level": "RF",
   "start": [
    9890,
    1260
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 1100
  },
  {
   "id": "CP-RF-P-REAR",
   "wall": "RF-P-REAR",
   "level": "RF",
   "start": [
    110,
    12890
   ],
   "end": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 1100
  },
  {
   "id": "CP-TR-P-FRONT",
   "wall": "TR-P-FRONT",
   "level": "TR",
   "start": [
    110,
    4400
   ],
   "end": [
    6355,
    4400
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 300
  },
  {
   "id": "CP-TR-P-RIGHT",
   "wall": "TR-P-RIGHT",
   "level": "TR",
   "start": [
    6355,
    4400
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 300
  },
  {
   "id": "CP-TR-P-REAR",
   "wall": "TR-P-REAR",
   "level": "TR",
   "start": [
    110,
    9100
   ],
   "end": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 300
  },
  {
   "id": "CP-TR-P-LEFT",
   "wall": "TR-P-LEFT",
   "level": "TR",
   "start": [
    110,
    4400
   ],
   "end": [
    110,
    9100
   ],
   "width": 220,
   "depth": 100,
   "typeName": "220 x 100",
   "topOffset": 300
  }
 ],
 "parapetPosts": [
  {
   "id": "PC-RF-1",
   "level": "RF",
   "point": [
    110,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-FRONT",
    "RF-P-LEFT-F"
   ]
  },
  {
   "id": "PC-RF-2",
   "level": "RF",
   "point": [
    2555,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-FRONT"
   ]
  },
  {
   "id": "PC-RF-3",
   "level": "RF",
   "point": [
    5000,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-FRONT"
   ]
  },
  {
   "id": "PC-RF-4",
   "level": "RF",
   "point": [
    7445,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-FRONT"
   ]
  },
  {
   "id": "PC-RF-5",
   "level": "RF",
   "point": [
    9890,
    1260
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-FRONT",
    "RF-P-RIGHT"
   ]
  },
  {
   "id": "PC-RF-6",
   "level": "RF",
   "point": [
    110,
    2830
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-LEFT-F"
   ]
  },
  {
   "id": "PC-RF-7",
   "level": "RF",
   "point": [
    110,
    10995
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-LEFT-R"
   ]
  },
  {
   "id": "PC-RF-8",
   "level": "RF",
   "point": [
    110,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-LEFT-R",
    "RF-P-REAR"
   ]
  },
  {
   "id": "PC-RF-9",
   "level": "RF",
   "point": [
    9890,
    4168
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-RIGHT"
   ]
  },
  {
   "id": "PC-RF-10",
   "level": "RF",
   "point": [
    9890,
    7075
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-RIGHT"
   ]
  },
  {
   "id": "PC-RF-11",
   "level": "RF",
   "point": [
    9890,
    9983
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-RIGHT"
   ]
  },
  {
   "id": "PC-RF-12",
   "level": "RF",
   "point": [
    9890,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-RIGHT",
    "RF-P-REAR"
   ]
  },
  {
   "id": "PC-RF-13",
   "level": "RF",
   "point": [
    2555,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-REAR"
   ]
  },
  {
   "id": "PC-RF-14",
   "level": "RF",
   "point": [
    5000,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-REAR"
   ]
  },
  {
   "id": "PC-RF-15",
   "level": "RF",
   "point": [
    7445,
    12890
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -130,
   "topOffset": 1000,
   "walls": [
    "RF-P-REAR"
   ]
  },
  {
   "id": "PC-TR-1",
   "level": "TR",
   "point": [
    110,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-FRONT",
    "TR-P-LEFT"
   ]
  },
  {
   "id": "PC-TR-2",
   "level": "TR",
   "point": [
    2192,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-FRONT"
   ]
  },
  {
   "id": "PC-TR-3",
   "level": "TR",
   "point": [
    4273,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-FRONT"
   ]
  },
  {
   "id": "PC-TR-4",
   "level": "TR",
   "point": [
    6355,
    4400
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-FRONT",
    "TR-P-RIGHT"
   ]
  },
  {
   "id": "PC-TR-5",
   "level": "TR",
   "point": [
    6355,
    6750
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-RIGHT"
   ]
  },
  {
   "id": "PC-TR-6",
   "level": "TR",
   "point": [
    6355,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-RIGHT",
    "TR-P-REAR"
   ]
  },
  {
   "id": "PC-TR-7",
   "level": "TR",
   "point": [
    110,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-REAR",
    "TR-P-LEFT"
   ]
  },
  {
   "id": "PC-TR-8",
   "level": "TR",
   "point": [
    2192,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-REAR"
   ]
  },
  {
   "id": "PC-TR-9",
   "level": "TR",
   "point": [
    4273,
    9100
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-REAR"
   ]
  },
  {
   "id": "PC-TR-10",
   "level": "TR",
   "point": [
    110,
    6750
   ],
   "width": 220,
   "depth": 220,
   "typeName": "PC 220 x 220",
   "baseOffset": -170,
   "topOffset": 200,
   "walls": [
    "TR-P-LEFT"
   ]
  }
 ],
 "stairs": [
  {
   "id": "ST-01",
   "baseLevel": "GF",
   "topLevel": "L1",
   "risers": 24,
   "riserHeight": 170.833,
   "tread": 280,
   "flightWidth": 1000,
   "core": {
    "x0": 220,
    "y0": 6890,
    "x1": 4300,
    "y1": 8990
   },
   "landingTop": 2050,
   "landing": {
    "x0": 220,
    "x1": 1220,
    "y0": 6890,
    "y1": 8990
   },
   "startX": 4300,
   "summary": "ST-01 GF->L1: U-shaped, 12 + 12 risers x 170.8 mm, tread 280 mm, flight width 1000 mm, half landing at +2.050, core x 220-4300, y 6890-8990, first riser at x = 4300"
  },
  {
   "id": "ST-02",
   "baseLevel": "L1",
   "topLevel": "RF",
   "risers": 20,
   "riserHeight": 170,
   "tread": 280,
   "flightWidth": 1000,
   "core": {
    "x0": 220,
    "y0": 6890,
    "x1": 4300,
    "y1": 8990
   },
   "landingTop": 5800,
   "landing": {
    "x0": 220,
    "x1": 1780,
    "y0": 6890,
    "y1": 8990
   },
   "startX": 4300,
   "summary": "ST-02 L1->RF: U-shaped, 10 + 10 risers x 170.0 mm, tread 280 mm, flight width 1000 mm, half landing at +5.800, core x 220-4300, y 6890-8990, first riser at x = 4300"
  }
 ]
}
''')

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
LOG = {"created": {}, "reused": [], "skipped": [], "missing": [], "errors": [],
       "warnings": [], "notes": []}


def created(kind, n=1):
    LOG["created"][kind] = LOG["created"].get(kind, 0) + n


def error(what, exc):
    LOG["errors"].append("%s: %s" % (what, exc))


def ft(mm):
    return float(mm) / MM_PER_FOOT


def xyz(p, z_ft=0.0):
    return XYZ(ft(p[0]), ft(p[1]), z_ft)


def key(element):
    return element.Id.ToString()


def ename(e):
    """Element name that also works for types in IronPython."""
    try:
        return e.Name
    except Exception:
        pass
    try:
        return Element.Name.__get__(e)
    except Exception:
        pass
    try:
        p = e.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM)
        if p is not None:
            return p.AsString()
    except Exception:
        pass
    return ""


def collect(cls):
    return list(FilteredElementCollector(doc).OfClass(cls).ToElements())


def set_param(e, bip, value):
    try:
        p = e.get_Parameter(bip)
        if p is None or p.IsReadOnly:
            return False
        p.Set(value)
        return True
    except Exception:
        return False


def set_named(e, name, value):
    try:
        p = e.LookupParameter(name)
        if p is None or p.IsReadOnly:
            return False
        p.Set(value)
        return True
    except Exception:
        return False


def by_id(items, attr="id"):
    out = {}
    for it in items:
        out[it[attr]] = it
    return out


LEVELS = {}       # data level id -> Level
REF_LEVELS = {}   # datum id -> Level (reference levels, no views)
VIEWS = {}        # data level id -> ViewPlan
WALL_TYPES = {}   # data wall type id -> WallType
FLOOR_TYPES = {}  # data slab type id -> FloorType
WALLS = {}        # data wall id -> Wall
MATERIALS = {}    # name -> ElementId


def z_of(level_id):
    return LEVELS[level_id].ProjectElevation


# ---------------------------------------------------------------------------
# Failure handling: swallow warnings (they are listed in the report)
# ---------------------------------------------------------------------------
def _preprocess(accessor):
    resolved = False
    try:
        for f in accessor.GetFailureMessages():
            text = f.GetDescriptionText()
            if f.GetSeverity() == FailureSeverity.Warning:
                LOG["warnings"].append(text)
                accessor.DeleteWarning(f)
            elif f.HasResolutions():
                LOG["warnings"].append("Resolved by Revit: " + text)
                accessor.ResolveFailure(f)
                resolved = True
            else:
                LOG["errors"].append("Revit: " + text)
    except Exception as exc:
        LOG["errors"].append("failure handler: %s" % exc)
    if resolved:
        return FailureProcessingResult.ProceedWithCommit
    return FailureProcessingResult.Continue


try:
    class TenByFifteenFailures(IFailuresPreprocessor):
        __namespace__ = "TenByFifteen"  # required by pythonnet, ignored by IronPython

        def PreprocessFailures(self, accessor):
            return _preprocess(accessor)
except Exception:
    TenByFifteenFailures = None


# ---------------------------------------------------------------------------
# 1. Levels
# ---------------------------------------------------------------------------
def build_levels():
    existing = collect(Level)
    names = {}
    for lvl in existing:
        names[ename(lvl)] = lvl
    claimed = set()
    wanted = [(L, True) for L in DATA["levels"]]
    if CREATE_REF_LEVELS:
        wanted += [(L, False) for L in DATA["refLevels"]]
    for L, storey in wanted:
        name = L["revitName"]
        elev = ft(L["elevation"])
        lvl = names.get(name)
        if lvl is None and storey:
            # reuse an unused template level at the same elevation ("Level 1")
            for cand in existing:
                if key(cand) not in claimed and abs(cand.Elevation - elev) < ft(1):
                    lvl = cand
                    break
        try:
            if lvl is None:
                lvl = Level.Create(doc, elev)
                created("levels" if storey else "reference levels")
            else:
                LOG["reused"].append("level %s (was '%s')" % (L["id"], ename(lvl)))
                if abs(lvl.Elevation - elev) > 1e-6:
                    lvl.Elevation = elev
            if ename(lvl) != name:
                lvl.Name = name
            claimed.add(key(lvl))
            if storey:
                LEVELS[L["id"]] = lvl
            else:
                set_param(lvl, BuiltInParameter.LEVEL_IS_BUILDING_STORY, 0)
                REF_LEVELS[L["id"]] = lvl
        except Exception as exc:
            error("level " + L["id"], exc)
    for lvl in existing:
        if key(lvl) not in claimed:
            LOG["notes"].append("Template level '%s' is not used by the house - delete it if empty." % ename(lvl))


def find_levels_only():
    names = {}
    for lvl in collect(Level):
        names[ename(lvl)] = lvl
    for L in DATA["levels"]:
        if L["revitName"] in names:
            LEVELS[L["id"]] = names[L["revitName"]]


# ---------------------------------------------------------------------------
# 2. Grids
# ---------------------------------------------------------------------------
def build_grids():
    existing = {}
    for g in collect(Grid):
        existing[ename(g)] = g
    for G in DATA["grids"]:
        if G["id"] in existing:
            LOG["skipped"].append("grid %s exists" % G["id"])
            continue
        try:
            g = Grid.Create(doc, Line.CreateBound(xyz(G["start"]), xyz(G["end"])))
            g.Name = G["id"]
            created("grids")
        except Exception as exc:
            error("grid " + G["id"], exc)


# ---------------------------------------------------------------------------
# 3. Plan views
# ---------------------------------------------------------------------------
def build_views():
    vft = None
    for t in collect(ViewFamilyType):
        if t.ViewFamily == ViewFamily.FloorPlan:
            vft = t
            break
    plans = [v for v in collect(ViewPlan) if not v.IsTemplate and v.ViewType == ViewType.FloorPlan]
    for L in DATA["levels"]:
        lvl = LEVELS.get(L["id"])
        if lvl is None:
            continue
        view = None
        for v in plans:
            if v.GenLevel is not None and key(v.GenLevel) == key(lvl):
                view = v
                break
        try:
            if view is None and CREATE_PLAN_VIEWS and vft is not None:
                view = ViewPlan.Create(doc, vft.Id, lvl.Id)
                created("plan views")
                try:
                    view.Name = L["revitName"]
                except Exception:
                    pass
                view.Scale = 100
            if view is not None:
                VIEWS[L["id"]] = view
        except Exception as exc:
            error("plan view " + L["id"], exc)


# ---------------------------------------------------------------------------
# 4. Wall and floor types
# ---------------------------------------------------------------------------
FUNCTIONS = {
    "Finish1": MaterialFunctionAssignment.Finish1,
    "Finish2": MaterialFunctionAssignment.Finish2,
    "Substrate": MaterialFunctionAssignment.Substrate,
    "Structure": MaterialFunctionAssignment.Structure,
    "Insulation": MaterialFunctionAssignment.Insulation,  # Thermal/Air Layer [3]
    "Membrane": MaterialFunctionAssignment.Membrane,      # must be 0 mm in Revit
}


def material(name):
    if name in MATERIALS:
        return MATERIALS[name]
    if not MATERIALS:
        for m in collect(Material):
            MATERIALS[ename(m)] = m.Id
        if name in MATERIALS:
            return MATERIALS[name]
    try:
        mid = Material.Create(doc, name)
        created("materials")
    except Exception as exc:
        error("material " + name, exc)
        mid = ElementId.InvalidElementId
    MATERIALS[name] = mid
    return mid


def layered_structure(T):
    layers = List[CompoundStructureLayer]()
    for ly in T["layers"]:
        layers.Add(CompoundStructureLayer(ft(ly["thickness"]), FUNCTIONS[ly["function"]], material(ly["material"])))
    cs = CompoundStructure.CreateSimpleCompoundStructure(layers)
    cs.SetNumberOfShellLayers(ShellLayerType.Exterior, T["exteriorShell"])
    cs.SetNumberOfShellLayers(ShellLayerType.Interior, T["interiorShell"])
    try:
        cs.StructuralMaterialIndex = T["coreIndex"]
    except Exception:
        pass
    return cs


def ensure_type(cls, T, base_ok):
    for t in collect(cls):
        if ename(t) == T["revitName"]:
            LOG["reused"].append("type " + T["revitName"])
            return t
    base = None
    for t in collect(cls):
        if base_ok(t):
            base = t
            break
    if base is None:
        LOG["errors"].append("no base type to duplicate for " + T["revitName"])
        return None
    new = base.Duplicate(T["revitName"])
    try:
        new.SetCompoundStructure(layered_structure(T))
    except Exception as exc:
        LOG["warnings"].append("layers of %s not set (%s) - using one %d mm layer" % (T["revitName"], exc, T["thickness"]))
        cs = CompoundStructure.CreateSingleLayerCompoundStructure(
            MaterialFunctionAssignment.Structure, ft(T["thickness"]), ElementId.InvalidElementId)
        new.SetCompoundStructure(cs)
    created("types")
    width = new.GetCompoundStructure().GetWidth() * MM_PER_FOOT
    if abs(width - T["thickness"]) > 0.5:
        LOG["errors"].append("type %s is %.1f mm thick, expected %d" % (T["revitName"], width, T["thickness"]))
    return new


def build_types():
    for T in DATA["wallTypes"]:
        try:
            t = ensure_type(WallType, T, lambda w: w.Kind == WallKind.Basic)
            if t is not None:
                WALL_TYPES[T["id"]] = t
                set_param(t, BuiltInParameter.FUNCTION_PARAM, 0 if T["function"] == "interior" else 1)
        except Exception as exc:
            error("wall type " + T["revitName"], exc)
    for T in DATA["slabTypes"]:
        try:
            t = ensure_type(FloorType, T, lambda f: not f.IsFoundationSlab)
            if t is not None:
                FLOOR_TYPES[T["id"]] = t
        except Exception as exc:
            error("floor type " + T["revitName"], exc)


# ---------------------------------------------------------------------------
# 5. Walls
# ---------------------------------------------------------------------------
def build_walls():
    for W in DATA["walls"]:
        lvl = LEVELS.get(W["level"])
        wt = WALL_TYPES.get(W["type"])
        if lvl is None or wt is None:
            LOG["skipped"].append("wall %s (level or type missing)" % W["id"])
            continue
        try:
            z = z_of(W["level"])
            line = Line.CreateBound(xyz(W["start"], z), xyz(W["end"], z))
            w = Wall.Create(doc, line, wt.Id, lvl.Id, ft(W["height"]), ft(W["baseOffset"]), False, False)
            if W["topLevel"] and W["topLevel"] in LEVELS:
                set_param(w, BuiltInParameter.WALL_HEIGHT_TYPE, LEVELS[W["topLevel"]].Id)
                set_param(w, BuiltInParameter.WALL_TOP_OFFSET, ft(W["topOffset"]))
            set_param(w, BuiltInParameter.ALL_MODEL_MARK, W["id"])
            if W["notes"]:
                set_param(w, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, W["notes"])
            n = W["exteriorNormal"]
            if n:
                o = w.Orientation
                if o.X * n[0] + o.Y * n[1] < 0:
                    w.Flip()
            WALLS[W["id"]] = w
            created("walls")
        except Exception as exc:
            error("wall " + W["id"], exc)


# ---------------------------------------------------------------------------
# 6. Floors
# ---------------------------------------------------------------------------
def curve_loop(points, z):
    loop = CurveLoop()
    n = len(points)
    for i in range(n):
        loop.Append(Line.CreateBound(xyz(points[i], z), xyz(points[(i + 1) % n], z)))
    return loop


def new_structural_floor(loops, ftype, lvl):
    """Floor.Create with the isStructural overload (Revit 2022+), else the
    plain overload and the Structural parameter."""
    try:
        return Floor.Create(doc, loops, ftype.Id, lvl.Id, True, None, 0.0)
    except TypeError:
        f = Floor.Create(doc, loops, ftype.Id, lvl.Id)
        set_param(f, BuiltInParameter.FLOOR_PARAM_IS_STRUCTURAL, 1)
        return f


def build_floors():
    for S in DATA["slabs"]:
        lvl = LEVELS.get(S["level"])
        ftype = FLOOR_TYPES.get(S["type"])
        if lvl is None or ftype is None:
            LOG["skipped"].append("floor %s (level or type missing)" % S["id"])
            continue
        try:
            z = z_of(S["level"])
            loops = List[CurveLoop]()
            loops.Add(curve_loop(S["outline"], z))
            for hole in (S["holes"] if CREATE_SHAFTS else S["allHoles"]):
                loops.Add(curve_loop(hole, z))
            f = new_structural_floor(loops, ftype, lvl)
            if S["topOffset"]:
                set_param(f, BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM, ft(S["topOffset"]))
            set_param(f, BuiltInParameter.ALL_MODEL_MARK, S["id"])
            if S["notes"]:
                set_param(f, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, S["notes"])
            created("floors")
            if S["accessOpenings"]:
                created("tank access openings", len(S["accessOpenings"]))
                LOG["notes"].append("Floor %s: %d access opening(s) cut for the covers of %s - place the covers (generic models) in them." % (
                    S["id"], len(S["accessOpenings"]), ", ".join(sorted(set(a["service"] for a in S["accessOpenings"])))))
        except Exception as exc:
            error("floor " + S["id"], exc)


# ---------------------------------------------------------------------------
# 7. Shaft openings (service shafts)
# ---------------------------------------------------------------------------
def build_shafts():
    for S in DATA["shafts"]:
        lo = LEVELS.get(S["bottomLevel"])
        hi = LEVELS.get(S["topLevel"])
        if lo is None or hi is None:
            LOG["skipped"].append("shaft %s (level missing)" % S["id"])
            continue
        try:
            z = z_of(S["bottomLevel"])
            pts = S["profile"]
            arr = CurveArray()
            for i in range(len(pts)):
                arr.Append(Line.CreateBound(xyz(pts[i], z), xyz(pts[(i + 1) % len(pts)], z)))
            op = doc.Create.NewOpening(lo, hi, arr)
            ok = set_param(op, BuiltInParameter.WALL_BASE_OFFSET, ft(S["baseOffset"]))
            ok = set_param(op, BuiltInParameter.WALL_TOP_OFFSET, ft(S["topOffset"])) and ok
            pipes = "; ".join(st["text"] for st in S["stacks"])
            set_param(op, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, S["id"] + ": " + (pipes or S["contents"]))
            if not ok:
                LOG["notes"].append("Shaft %s: set Base Offset %d mm and Top Offset %d mm by hand." % (
                    S["id"], S["baseOffset"], S["topOffset"]))
            created("shaft openings")
            sides = ["(%d, %d)-(%d, %d) on %s" % (b["a"][0], b["a"][1], b["b"][0], b["b"][1], b["level"])
                     for b in S["boxing"]]
            LOG["notes"].append("Shaft %s: box it in (hop gen) along its open sides %s; vent upstand %d mm above %s; pipes: %s." % (
                S["id"], ", ".join(sides) or "(none)", S["topOffset"], S["topLevel"], pipes or "-"))
        except Exception as exc:
            error("shaft " + S["id"], exc)


# ---------------------------------------------------------------------------
# 8. Doors and windows
# ---------------------------------------------------------------------------
def symbols_by_name():
    out = {}
    for s in collect(FamilySymbol):
        try:
            out[s.FamilyName + " : " + ename(s)] = s
        except Exception:
            pass
    return out


def dot2(v, d):
    return v.X * d[0] + v.Y * d[1]


def orient_door(inst, O):
    """Flips a door so its leaf opens towards the side given in the data and
    its hinge is on the data's hinge jamb (multi-leaf doors: both jambs)."""
    sw = O["swing"]
    if not ORIENT_DOORS or not sw:
        return
    try:
        want = 1 if DOOR_OPENS_TO_FACING else -1
        if dot2(inst.FacingOrientation, sw["towards"]) * want < 0:
            inst.flipFacing()
        if sw["hinge"] is not None:
            c = O["center"]
            d = [sw["hinge"][0] - c[0], sw["hinge"][1] - c[1]]
            want = 1 if DOOR_HINGE_ON_HAND_SIDE else -1
            if dot2(inst.HandOrientation, d) * want < 0:
                inst.flipHand()
        created("door swings set")
        where = "both jambs" if sw["bothJambs"] else "(%d, %d)" % (sw["hinge"][0], sw["hinge"][1])
        LOG["notes"].append("Check swing of %s: opens towards (%.0f, %.0f), hinge at %s." % (
            O["id"], sw["towards"][0], sw["towards"][1], where))
    except Exception as exc:
        LOG["notes"].append("Set the swing of %s by hand (%s)." % (O["id"], exc))


def build_openings():
    symbols = symbols_by_name()
    for O in DATA["openings"]:
        host = WALLS.get(O["wall"])
        if host is None:
            LOG["skipped"].append("opening %s (host wall %s missing)" % (O["id"], O["wall"]))
            continue
        z = z_of(O["level"])
        sym = symbols.get(O["family"]) if PLACE_OPENINGS else None
        try:
            if O["kind"] == "door" and O["sill"] > 0:
                LOG["notes"].append("%s sits on a %d mm waterproofed kerb: Sill Height %d, the wall stays solid below it." % (
                    O["id"], O["sill"], O["sill"]))
            if sym is not None:
                if not sym.IsActive:
                    sym.Activate()
                    doc.Regenerate()
                inst = doc.Create.NewFamilyInstance(
                    xyz(O["center"], z), sym, host, LEVELS[O["level"]], StructuralType.NonStructural)
                set_param(inst, BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM, ft(O["sill"]))
                set_param(inst, BuiltInParameter.ALL_MODEL_MARK, O["id"])
                created(O["kind"] + "s")
                orient_door(inst, O)
            else:
                LOG["missing"].append("%s  %s" % (O["id"], O["family"]))
                if WALL_OPENING_IF_MISSING:
                    doc.Create.NewOpening(host, xyz(O["p0"], z + ft(O["sill"])), xyz(O["p1"], z + ft(O["head"])))
                    created("wall openings (no family)")
        except Exception as exc:
            error("opening " + O["id"], exc)


# ---------------------------------------------------------------------------
# 9. Room separation lines, rooms, tags
# ---------------------------------------------------------------------------
def build_separations():
    for lid in LEVELS:
        lines = [s for s in DATA["separations"] if s["level"] == lid]
        view = VIEWS.get(lid)
        if not lines:
            continue
        if view is None:
            LOG["skipped"].append("room separation lines on %s (no plan view)" % lid)
            continue
        try:
            z = z_of(lid)
            plane = SketchPlane.Create(doc, LEVELS[lid].Id)
            arr = CurveArray()
            for s in lines:
                arr.Append(Line.CreateBound(xyz(s["a"], z), xyz(s["b"], z)))
            doc.Create.NewRoomBoundaryLines(plane, arr, view)
            created("room separation lines", len(lines))
        except Exception as exc:
            error("room separation lines " + lid, exc)


VI_PARAM_NOTED = []


def build_rooms():
    doc.Regenerate()
    for R in DATA["rooms"]:
        lvl = LEVELS.get(R["level"])
        if lvl is None:
            continue
        try:
            uv = UV(ft(R["point"][0]), ft(R["point"][1]))
            room = doc.Create.NewRoom(lvl, uv)
            set_param(room, BuiltInParameter.ROOM_NUMBER, R["id"])
            set_param(room, BuiltInParameter.ROOM_NAME, R["name"])
            if R["floorOffset"]:
                set_param(room, BuiltInParameter.ROOM_LOWER_OFFSET, ft(R["floorOffset"]))
            if not set_named(room, DATA["names"]["roomNameVi"], R["nameVi"]):
                set_param(room, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, R["nameVi"])
                if not VI_PARAM_NOTED:
                    VI_PARAM_NOTED.append(True)
                    LOG["notes"].append("No room parameter '%s' (Text, Rooms): the Vietnamese names went into Comments." % DATA["names"]["roomNameVi"])
            created("rooms")
            view = VIEWS.get(R["level"])
            if TAG_ROOMS and view is not None:
                doc.Create.NewRoomTag(LinkElementId(room.Id), uv, view.Id)
                created("room tags")
        except Exception as exc:
            error("room " + R["id"], exc)


# ---------------------------------------------------------------------------
# 10. Structural columns and beams
# ---------------------------------------------------------------------------
def family_symbols(families):
    for fam in families:
        found = [s for s in collect(FamilySymbol) if s.FamilyName == fam]
        if found:
            return found
    return []


def sized_symbol(candidates, name, b, h):
    for s in candidates:
        if ename(s) == name:
            return s
    new = candidates[0].Duplicate(name)
    set_named(new, "b", ft(b))
    set_named(new, "h", ft(h))
    candidates.append(new)
    created("structural types")
    return new


def build_columns():
    candidates = family_symbols(COLUMN_FAMILIES)
    if not candidates:
        LOG["missing"].append("columns: load one of %s" % ", ".join(COLUMN_FAMILIES))
        return
    for C in DATA["columns"]:
        try:
            sym = sized_symbol(candidates, C["typeName"], C["width"], C["depth"])
            if not sym.IsActive:
                sym.Activate()
                doc.Regenerate()
            base = LEVELS[C["baseLevel"]]
            inst = doc.Create.NewFamilyInstance(xyz(C["point"], base.ProjectElevation), sym, base, StructuralType.Column)
            set_param(inst, BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM, ft(C["baseOffset"]))
            set_param(inst, BuiltInParameter.FAMILY_TOP_LEVEL_PARAM, LEVELS[C["topLevel"]].Id)
            top = C["beamTopOffset"] if COLUMNS_TO_BEAM_TOP else C["topOffset"]
            set_param(inst, BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM, ft(top))
            set_param(inst, BuiltInParameter.ALL_MODEL_MARK, C["mark"])
            if C["on"]:
                set_param(inst, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, "On " + C["on"])
            created("columns")
        except Exception as exc:
            error("column " + C["mark"], exc)


def build_beams():
    candidates = family_symbols(BEAM_FAMILIES)
    if not candidates:
        LOG["missing"].append("beams: load one of %s" % ", ".join(BEAM_FAMILIES))
        return
    for B in DATA["beams"]:
        try:
            sym = sized_symbol(candidates, B["typeName"], B["width"], B["depth"])
            if not sym.IsActive:
                sym.Activate()
                doc.Regenerate()
            lvl = LEVELS[B["level"]]
            z = lvl.ProjectElevation + ft(B["topOffset"])
            line = Line.CreateBound(xyz(B["start"], z), xyz(B["end"], z))
            inst = doc.Create.NewFamilyInstance(line, sym, lvl, StructuralType.Beam)
            set_param(inst, BuiltInParameter.ALL_MODEL_MARK, B["id"])
            if B["notes"]:
                set_param(inst, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, B["notes"])
            created("beams")
        except Exception as exc:
            error("beam " + B["id"], exc)


def build_copings():
    """RC copings on the parapets: brick wall up to the coping underside,
    the coping on top (structural framing, top at the parapet datum)."""
    candidates = family_symbols(BEAM_FAMILIES)
    if not candidates:
        LOG["missing"].append("parapet copings: load one of %s" % ", ".join(BEAM_FAMILIES))
        return
    for B in DATA["copings"]:
        try:
            sym = sized_symbol(candidates, B["typeName"], B["width"], B["depth"])
            if not sym.IsActive:
                sym.Activate()
                doc.Regenerate()
            lvl = LEVELS[B["level"]]
            z = lvl.ProjectElevation + ft(B["topOffset"])
            line = Line.CreateBound(xyz(B["start"], z), xyz(B["end"], z))
            inst = doc.Create.NewFamilyInstance(line, sym, lvl, StructuralType.Beam)
            set_param(inst, BuiltInParameter.ALL_MODEL_MARK, B["id"])
            set_param(inst, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, "RC coping on " + B["wall"])
            created("parapet copings")
        except Exception as exc:
            error("coping " + B["id"], exc)


def build_parapet_posts():
    """Stub columns (cot bo tru) of the parapets: from the wall base to the
    underside of the coping (top level = base level + offset)."""
    candidates = family_symbols(COLUMN_FAMILIES)
    if not candidates:
        LOG["missing"].append("parapet stub columns: load one of %s" % ", ".join(COLUMN_FAMILIES))
        return
    for P in DATA["parapetPosts"]:
        try:
            sym = sized_symbol(candidates, P["typeName"], P["width"], P["depth"])
            if not sym.IsActive:
                sym.Activate()
                doc.Regenerate()
            base = LEVELS[P["level"]]
            inst = doc.Create.NewFamilyInstance(xyz(P["point"], base.ProjectElevation), sym, base, StructuralType.Column)
            set_param(inst, BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM, ft(P["baseOffset"]))
            set_param(inst, BuiltInParameter.FAMILY_TOP_LEVEL_PARAM, base.Id)
            set_param(inst, BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM, ft(P["topOffset"]))
            set_param(inst, BuiltInParameter.ALL_MODEL_MARK, P["id"])
            set_param(inst, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, "Parapet stub column in " + ", ".join(P["walls"]))
            created("parapet stub columns")
        except Exception as exc:
            error("parapet post " + P["id"], exc)


# ---------------------------------------------------------------------------
# 11. CAD links
# ---------------------------------------------------------------------------
def script_folder():
    try:
        return os.path.dirname(os.path.abspath(__file__))
    except Exception:
        return ""


def link_cad():
    folder = CAD_FOLDER or script_folder()
    for L in DATA["levels"]:
        view = VIEWS.get(L["id"])
        path = os.path.join(folder, L["cadFile"]) if folder else L["cadFile"]
        if view is None or not os.path.exists(path):
            LOG["notes"].append("Link %s yourself (Insert > Link CAD) - file not found next to the script." % L["cadFile"])
            continue
        try:
            opts = DWGImportOptions()
            opts.ThisViewOnly = True
            opts.Placement = ImportPlacement.Origin
            opts.Unit = ImportUnit.Millimeter
            opts.ColorMode = ImportColorMode.Preserved
            try:
                doc.Link(path, opts, view)  # IronPython: out parameter returned
            except TypeError:
                doc.Link(path, opts, view, ElementId.InvalidElementId)  # pythonnet
            created("CAD links")
        except Exception as exc:
            error("link " + L["cadFile"], exc)


# ---------------------------------------------------------------------------
# 12. True north (optional)
# ---------------------------------------------------------------------------
def set_true_north():
    """Rotates True North. The sign convention of ProjectPosition.Angle has
    not been verified here: after running, open a site plan with
    Orientation = True North and check the front facade faces the bearing in
    the README; if it is mirrored, use Manage > Position > Rotate True North
    with the angle and direction from the README instead."""
    import math
    from Autodesk.Revit.DB import ProjectPosition
    loc = doc.ActiveProjectLocation
    pos = loc.GetProjectPosition(XYZ.Zero)
    angle = math.radians(DATA["trueNorthAngle"])
    loc.SetProjectPosition(XYZ.Zero, ProjectPosition(pos.EastWest, pos.NorthSouth, pos.Elevation, angle))
    LOG["notes"].append("True North set to %s deg (verify, see set_true_north)." % DATA["trueNorthAngle"])


# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
def build():
    steps = [
        (CREATE_LEVELS, build_levels),
        (not CREATE_LEVELS, find_levels_only),
        (CREATE_GRIDS, build_grids),
        (True, build_views),
        (CREATE_TYPES, build_types),
        (CREATE_WALLS, build_walls),
        (CREATE_FLOORS, build_floors),
        (CREATE_SHAFTS, build_shafts),
        (PLACE_OPENINGS or WALL_OPENING_IF_MISSING, build_openings),
        (CREATE_ROOM_SEPARATIONS, build_separations),
        (CREATE_ROOMS, build_rooms),
        (PLACE_COLUMNS, build_columns),
        (PLACE_BEAMS, build_beams),
        (PLACE_COPINGS, build_copings),
        (PLACE_PARAPET_POSTS, build_parapet_posts),
        (LINK_CAD, link_cad),
        (SET_TRUE_NORTH, set_true_north),
    ]
    for enabled, step in steps:
        if not enabled:
            continue
        try:
            step()
        except Exception as exc:
            error("step " + step.__name__, exc)
            LOG["errors"].append(traceback.format_exc())


def report(outcome):
    line = "=" * 72
    print(line)
    print("10by15 -> Revit   data v%s, generated %s" % (DATA["project"]["version"], DATA["generated"]))
    print(outcome)
    print(line)
    for kind in sorted(LOG["created"]):
        print("  created %-28s %4d" % (kind, LOG["created"][kind]))
    sections = [
        ("Reused existing", LOG["reused"]),
        ("Skipped", LOG["skipped"]),
        ("MISSING FAMILIES - load these (Family : Type) and run again", LOG["missing"]),
        ("ERRORS", LOG["errors"]),
        ("Revit warnings", LOG["warnings"]),
        ("Notes", LOG["notes"]),
    ]
    for title, items in sections:
        if not items:
            continue
        print("")
        print("%s (%d):" % (title, len(items)))
        for it in items[:80]:
            print("  - " + it)
        if len(items) > 80:
            print("  ... and %d more" % (len(items) - 80))
    print("")
    print("Stairs - build these by hand (Architecture > Stair), data from the website:")
    for s in DATA["stairs"]:
        print("  - " + s["summary"])
    print("")
    print("Also by hand (see 10by15.com/revit): railings and the RC upstands under")
    print("the loggia guards, canopies, shaft boxing, the toposolid and the paving")
    print("surfaces (driveway ramp, level yard), gates, steps, buried pipes, services.")
    print("Check the model against the CSV schedules (rooms, doors, windows, walls).")
    print(line)


def main():
    if doc is None:
        print("No Revit document: run this inside pyRevit or RevitPythonShell with a project open.")
        return
    if doc.IsFamilyDocument:
        print("Open a PROJECT (not a family) created from your template, then run again.")
        return
    t = Transaction(doc, "10by15 house v" + DATA["project"]["version"])
    if TenByFifteenFailures is not None:
        try:
            opts = t.GetFailureHandlingOptions()
            opts.SetFailuresPreprocessor(TenByFifteenFailures())
            opts.SetClearAfterRollback(True)
            t.SetFailureHandlingOptions(opts)
        except Exception as exc:
            LOG["notes"].append("Revit warnings will show in dialogs (%s)" % exc)
    t.Start()
    try:
        build()
    except Exception as exc:
        error("FATAL", exc)
        t.RollBack()
        report("FAILED - transaction rolled back, nothing was changed.")
        return
    if DRY_RUN:
        t.RollBack()
        report("DRY RUN - everything above was rolled back. Set DRY_RUN = False to keep it.")
    else:
        status = t.Commit()
        report("Saved (transaction status: %s). Review every element against the website." % status)


if __name__ == "__main__" or doc is not None:
    main()
