Skip to content

Zoning Envelope 3D

A Claude Code skill that generates interactive 3D zoning envelope viewers as self-contained HTML files — exact lot polygons from GIS data, extruded buildable volumes, setback zones, height caps, and orbit controls.

Zoning Envelope 3D — Sample Open fullscreen →

What it does

Run /zoning-envelope after a zoning analysis to generate an interactive 3D viewer of the buildable envelope. The output is a self-contained HTML file — no server, no dependencies, opens in any browser.

Demo above: 250 Hudson Street, Manhattan — M1-6 / HSQ (C6-4A equivalent). Base volume (0–85 ft) + tower volume (85–290 ft) on the exact tax lot polygon from NYC MapPLUTO.

Workflow

/zoning-analysis-nyc 250 Hudson St, New York NY   ← analysis (markdown report)
/zoning-envelope                                    ← 3D viewer (HTML file)

The analysis skill produces a structured report with an Envelope Data JSON block containing the lot polygon, setbacks, volumes, and parameters. The envelope skill reads that block and renders it in 3D.

Install

Claude Desktop:

  1. Open CustomizeBrowse plugins
  2. Click +Add marketplace from GitHub
  3. Enter AlpacaLabsLLC/skills-for-architects
  4. Install the Zoning Analysis plugin

Claude Code (terminal):

claude plugin marketplace add AlpacaLabsLLC/skills-for-architects
claude plugin install 02-zoning-analysis@skills-for-architects

Or symlink just this skill:

git clone https://github.com/AlpacaLabsLLC/skills-for-architects.git
ln -s $(pwd)/skills-for-architects/plugins/02-zoning-analysis/skills/zoning-envelope ~/.claude/skills/zoning-envelope

Usage

Point it at a zoning analysis report:

/zoning-envelope path/to/zoning-analysis-250-hudson-st.md

Search by keyword:

/zoning-envelope 250 hudson

Auto-detect the most recent report:

/zoning-envelope

What it renders

  • Exact lot polygon from GIS data — the real cadastral boundary, not a simplified rectangle
  • Setback zones as colored ground overlays with dashed inset lines
  • Buildable volumes — base, tower, galibo — extruded from the polygon at correct heights
  • Height cap at maximum building height
  • Edge-length labels on the lot boundary
  • Parameters panel — FAR, floor area, height limits, setbacks
  • Interactive controls — orbit, zoom, pan

How it handles different districts

District typeEnvelope shape
Height-factor (R7, C6-1)Base box + sky exposure plane wedge
Contextual (R7A, C6-4A)Streetwall base + setback tower
TONE (Uruguay)Full lot with setback zones + flat height cap
Multi-scenarioToggle buttons comparing individual, party-wall, and unified envelopes

Technical details

The viewer is a single HTML file (~300 lines) with:

  • Three.js 0.170 loaded from CDN via import map
  • OrbitControls for interactive navigation
  • Ear-clipping polygon triangulation for arbitrary lot shapes
  • Self-correcting polygon inset (handles both CW and CCW winding from different GIS sources)
  • Self-intersection clipping for concave lot shapes (L-shapes, T-shapes)
  • Polygon simplification to remove degenerate edges from inset offsets
  • Built-in watertightness validation overlay (green = pass, red = fail, dismissable)
  • Canvas-textured sprites for 3D labels
  • Responsive — works on desktop, tablet, and mobile

NYC examples

Interactive 3D envelopes generated from real NYC zoning analyses. Each viewer is a self-contained HTML file — drag to orbit, scroll to zoom, right-drag to pan.

Contextual districts (base + tower)

PropertyZoningLotEnvelope
250 Hudson StreetM1-6 / HSQ (C6-4A equiv.)21,862 SFBase 0–85 ft + Tower 85–290 ftView 3D →
195 BroadwayC5-536,775 SFBase 0–85 ft + Tower 85–400 ftView 3D →
161 Maiden LaneC5-34,836 SFBase 0–85 ft + Tower 85–400 ftView 3D →
233 BroadwayC5-329,411 SFBase 0–85 ft + Tower 85–450 ftView 3D →
100 Church StreetC5-353,354 SFBase 0–85 ft + Tower 85–400 ftView 3D →
29-37 41st Ave, QueensM1-6/R104,471 SFBase 0–65 ft + Tower 65–175 ftView 3D →

Single-volume districts

PropertyZoningLotMax Height
60 East 11th StreetC6-14,019 SF120 ftView 3D →
1 Wall StreetC5-542,178 SF500 ftView 3D →
120 BroadwayC5-549,614 SF500 ftView 3D →
2 Gold StreetC5-524,128 SF500 ftView 3D →
500 Waverly Ave, BrooklynR7A11,923 SF80 ftView 3D →

Testing and validation

The 3D geometry is validated with an automated test suite that checks every generated envelope for watertightness. The test fetches real lot polygons from NYC MapPLUTO, runs the geometry pipeline, and verifies each mesh.

What the test checks

For each extruded volume (base, tower, height cap):

  • Boundary edges — every edge must be shared by exactly 2 triangles (no holes)
  • Non-manifold edges — no edge shared by more than 2 triangles
  • Degenerate triangles — no zero-area faces from collapsed vertices
  • Self-intersecting inset polygons — the setback offset must not create bowtie crossings
  • Winding consistency — all face normals point outward

Test results

10 sites tested across Manhattan, Brooklyn, and Queens — diverse lot shapes (4 to 19 vertices), zoning districts (R7A to C5-5), and envelope types (single volume and base+tower). All 10 pass.

Known issues fixed (March 2026)

Three geometry bugs were identified and fixed through this testing process:

  1. Self-intersecting inset polygons on concave lots. On L-shaped and T-shaped lots, the vertex-offset inset algorithm produced bowtie self-intersections when the setback was large relative to narrow parts of the lot. Fixed by adding cleanInsetPolygon() — detects edge-edge crossings and clips the invalid loop — followed by simplifyPolygon() which removes micro-edges, near-collinear vertices, and tiny concave dents left by the offset.

  2. Ear-clipping triangulation stalling on near-collinear edges. The triangulator’s convexity check used <= 0, rejecting valid ears with near-zero cross products from simplified polygons. Changed to < -1e-6.

  3. Side face normals pointing inward. The side face index winding (i, j, j+n) produced inward-facing normals for CCW polygons. Fixed to (j, i, j+n) for correct outward normals.

Dependency

This skill requires a zoning analysis report as input. Run /zoning-analysis-nyc first — then /zoning-envelope reads the output.

Related skills

Explore