Skip to main content

pysovist

Exact isovists and view volumes from floor plans, meshes and raw point clouds.

An isovist is the region visible from one point. pysovist computes it in two settings:

  • 2D, from wall segments. The visible polygon is computed exactly, with no ray count. Area, perimeter, occlusivity, radial statistics, drift and elongation follow in closed form, and so does convex deficiency without a range limit.
  • 3D, from a mesh or a point cloud. The view volume is the volume visible from an eye point. Point clouds are used as scanned: every point is a small ball, so furniture, equipment and people occlude as they did on the day of the scan.

Install

pip install pysovist                    # 2D isovists
pip install "pysovist[pointcloud]"      # point clouds (numba, laspy)
pip install "pysovist[mesh]"            # meshes (open3d)
pip install "pysovist[ifc]"             # BIM models in IFC files (ifcopenshell)
pip install "pysovist[all]"             # everything, including e57 files

Python 3.10 or newer. On a Linux machine without a desktop, open3d also needs the system libraries libegl1, libgl1 and libgomp1.

Quick start

import numpy as np
import pysovist

# A 10 m x 10 m room with a 2 m x 2 m pillar, as wall segments [[x0, y0], [x1, y1]].
def rect(x0, y0, x1, y1):
    v = np.array([(x0, y0), (x1, y0), (x1, y1), (x0, y1)], float)
    return np.stack([v, np.roll(v, -1, axis=0)], axis=1)

plan = pysovist.Plan(np.concatenate([rect(-5, -5, 5, 5), rect(-1, -1, 1, 1)]))
iso = pysovist.isovist(plan, (3.0, 0.0))
iso.area                       # 70.0, exact
iso.metrics["occlusivity"]     # 13.416..., the two edges of the pillar's shadow

# Many observers at once, one row each.
field = pysovist.isovist_field(plan, plan.grid(0.5), max_distance=40.0, n_jobs=-1)

View volumes from a point cloud:

cloud = pysovist.PointCloud.read("scan.las", radius=0.05)   # every point is a ball of radius 5 cm
vv = pysovist.view_volume(cloud, (3.0, 0.0, 1.7), n_rays=262_144)
vv.volume, vv.metrics["escape_fraction"]

Plans and meshes from a BIM model, read from an IFC file in any length unit:

plan = pysovist.Plan.from_ifc("model.ifc", 1.2, classes="furnished", storey="Level 1")
mesh = pysovist.Mesh.from_ifc("model.ifc", classes=("walls", "IfcSlab", "IfcCovering"))

Plan.from_ifc cuts the walls and, with "furnished", the furniture of one storey at 1.2 m above its floor.

Units are metres and radians. z points up.

What makes it exact

Seen from the observer, the angles of all wall endpoints, wall crossings and, under a range limit, crossings of walls with the range circle cut the full turn into wedges. Within one wedge the nearest wall never changes, so each wedge is a triangle or, under a range limit, a circular sector. Every metric is built from closed forms over these pieces.

Ray-sampling tools describe the same isovist by the polygon through N hit points. pysovist.sampled_metrics reproduces that description, so its error can be measured against the exact value. The area error falls as N^-2 in convex rooms and as N^-1 where the boundary has occluding edges.

Verification

  • 2D: closed-form scenes (square, hallway, regular polygons, L-shaped room, room with a pillar, open room with a range limit, fields of view) agree to a relative 1e-9 (absolute 1e-9 for values of zero). Random rooms agree with the visilibity library and with a polygon shadow construction to 1e-7, and the results are invariant under rigid motion and scaling.
  • 3D: closed-form volumes (cube, pyramid, sphere mesh, convex hulls, a cube clipped by a range sphere) agree to a relative 1e-4 at 65,536 directions (2e-4 for random hulls), and the error on the cube falls faster than N^-1/2. On an extruded floor plan the view volume equals the ceiling height times the exact 2D isovist area, to 1e-3 at 65,536 directions.
  • Point clouds: the ball ray caster agrees with a brute-force first hit to 1e-12.

How to cite

pysovist is free to use and modify under the MIT licence. If it helps your work, please cite the software and the methods paper. If you use the emergency-department results, please cite the behaviour paper. GitHub's "Cite this repository" button gives the software reference from CITATION.cff.

@software{pysovist,
  author  = {Aguilar, Leonel and Tuncay, Bartu},
  title   = {pysovist: exact isovists and view volumes from floor plans, meshes and point clouds},
  version = {0.1.2},
  year    = {2026},
  url     = {https://github.com/leaguilar/pysovist}
}

@unpublished{pysovist_methods,
  author = {Aguilar, Leonel and Baur, Rapha{\"e}l and Wheele, Theresa and Tuncay, Bartu and Ladouce, Simon and Li, Chenyang and Schmutz, Jan and Sailer, Kerstin and Gr{\"u}bel, Jascha and Slankamenac, Ksenija and Honegger, Patrik and Conroy-Dalton, Ruth and Sax, Hugo and H{\"o}lscher, Christoph and Gath-Morad, Michal},
  title  = {pysovist: reproducible visibility analysis across floor plans, furnished models and point clouds},
  note   = {In preparation},
  year   = {2026}
}

@unpublished{pysovist_ed_behaviour,
  author = {Aguilar, Leonel and Baur, Rapha{\"e}l and Wheele, Theresa and Ladouce, Simon and Li, Chenyang and Schmutz, Jan and Sailer, Kerstin and Gr{\"u}bel, Jascha and Slankamenac, Ksenija and Honegger, Patrik and Conroy-Dalton, Ruth and Sax, Hugo and H{\"o}lscher, Christoph and Gath-Morad, Michal},
  title  = {Beyond the wall plan: predicting staff occupancy from furnished layouts and point clouds},
  note   = {In preparation},
  year   = {2026}
}

Licence

MIT. Copyright (c) 2025-2026 Bartu Tuncay and Leonel Aguilar.

Metadata

Release files for pysovist 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pysovist 0.1.2
File Size Uploaded
pysovist-0.1.2.tar.gz 90.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pysovist 0.1.2
File Interpreter ABI Platform
pysovist-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 142.2 kB

Release files / pysovist-0.1.2.tar.gz

Download URL pysovist-0.1.2.tar.gz
Size 90.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e109cae456f89f0e67c326729c4a2aad1d6f9099b2e3b436896b82476a0054ef
BLAKE2b-256 checksum
How to use checksums
10aefa392f76eafcc7e3fcb0410215fae5193eaf6320f3aa219c1f09d5b19c82
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / pysovist-0.1.2-py3-none-any.whl

Download URL pysovist-0.1.2-py3-none-any.whl
Size 51.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1434a3f2f9161623357cea1d2900af063048750e5e538983d8ff33ff6a141858
BLAKE2b-256 checksum
How to use checksums
2366e2fc4c1db3b98bdb5a9c671cb5604d29b9d49fb2c7dd095d4a6a96e4913a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page