S3DIS
S3DIS indoor scene segmentation datasets with room loading, alignment, and tiling helpers.

Classes:
-
S3DISRoomData–Per-point arrays of one S3DIS room, as returned by
load_s3dis_room. -
S3DIS–The Stanford 3D Indoor Spaces Dataset (S3DIS) dataset, as described in the original paper
-
S3DISHdf5–Pre-processed HDF5 version of the S3DIS dataset used by multiple SOTA reference implementations.
Functions:
-
load_s3dis_room–Load the full S3DIS room from a given directory and (optionally) apply an alignment angle.
-
load_s3dis_alignment_angles–Load the alignment angles for a given area from a text file.
-
tile_s3dis_room–Split a single room dict into fixed-size spatial blocks.
S3DISRoomData
¶
Bases: TypedDict
Per-point arrays of one S3DIS room, as returned by load_s3dis_room.
S3DIS
¶
S3DIS(
root: PathLike,
*,
areas: Union[
ValueCollection[S3DISArea], Literal["all"]
] = "all",
classes: Union[
ValueCollection[S3DISClass], Literal["all"]
] = "all",
aligned: bool = True,
block_size: Optional[float] = None,
block_stride: float = 1.0,
num_nodes: int = 4096,
min_num_nodes: int = 100,
transform: Optional[Callable] = None,
download: bool = False,
force_download: bool = False,
force_process: bool = False,
show_progress: bool = True,
num_workers: Optional[int] = None,
)
Bases: PointCloudDataset
The Stanford 3D Indoor Spaces Dataset (S3DIS) dataset, as described in the original paper 3D Indoor Spaces Dataset: Collection, Annotations, and Methods.
You can download the raw dataset from https://cvg-data.inf.ethz.ch/s3dis/ official website.
The S3DIS dataset contains 6 diverse areas (one used for testing) covering a total of 6020 square meters. Each area contains multiple rooms (e.g. office, conference room, etc.), and each room contains multiple segment regions (e.g. wall, floor, ceiling, etc.) with instance-level annotations.
The dataset will be processed automatically and saved in the S3DIS/processed directory.
Each room is stored as its own folder:
<processed_dir>/<Area_i>/<room_name>/{coord,color,segment,instance}.npy. If the processed
data already exists, it will be loaded from the S3DIS/processed directory and processing
will be skipped.
Tip
If you change the preprocessing parameters, you can delete the processed data to reprocess the dataset
or use the force_process argument to force the processing of the raw data.
Parameters:
-
root(PathLike) –The root directory of the dataset, where the raw and processed data will be stored.
-
areas(Union[ValueCollection[S3DISArea], Literal['all']], default:'all') –The areas to load, either a list of area names or "all".
-
classes(Union[ValueCollection[S3DISClass], Literal['all']], default:'all') –The classes to load, either a list of class names or "all".
-
aligned(bool, default:True) –Whether to apply each room's global alignment rotation during processing. The raw
Stanford3dDataset_v1.2_Aligned_Versiondownload ships the same (non-aligned) coordinates as V1.2 plus per-roomArea_{i}_alignmentAngle.txtfiles. Whenaligned=True(default) the rotation is applied so the stored coordinates are globally aligned. WhenFalsethe original V1.2 coordinate frame is kept: this is required when benchmarking pretrained weights that were trained on non-aligned data (e.g. the DGCNN reference weights whose HDF5 blocks use non-aligned coordinates). Aligned and unaligned data are stored in separate processed directories so they can coexist. -
block_size(Optional[float], default:None) –If set, each room is split into ground-plane blocks of this size (meters) at load time. Changing this only affects loading, not on-disk processed data.
-
block_stride(float, default:1.0) –Stride between blocks when
block_sizeis set. -
num_nodes(int, default:4096) –Target number of points per block (or per room when not tiling).
-
min_num_nodes(int, default:100) –Skip blocks with fewer than this many points.
-
transform(Optional[Callable], default:None) –A callable that transforms the data when retrieved from the dataset.
-
download(bool, default:False) –Whether to download the raw data.
-
force_download(bool, default:False) –Whether to force the download of the raw data.
-
force_process(bool, default:False) –Whether to force the processing of the raw data.
-
show_progress(bool, default:True) –Whether to show a progress bar during processing.
-
num_workers(Optional[int], default:None) –Number of worker processes for parallel room processing. If
None, rooms are processed sequentially.
Example
Assuming you have downloaded the raw dataset from https://cvg-data.inf.ethz.ch/s3dis/,
and extracted it under data/S3DIS/raw, you can load the dataset as follows:
from torch_pointcloud.datasets import S3DIS
dataset = S3DIS(
root="data",
areas=["Area_1", "Area_2", "Area_3", "Area_4", "Area_6"],
)
To split rooms into 1m x 1m blocks (matching the DGCNN evaluation protocol):
Methods:
-
is_area_processed–Check whether an area is fully packed in the processed cache.
-
process–Process the raw dataset for easier loading.
-
load–Load the processed dataset into memory.
Attributes:
-
processed_dir(str) –Path to the processed cache directory, suffixed
_alignedwhen the rooms are axis-aligned. -
class_to_idx(dict[str, int]) –Mapping from class name to label index.
-
name(str) –Name of the dataset directory.
-
data_dir(str) –Path to the dataset directory
<root>/<name>. -
raw_dir(str) –Path to the raw download directory.
processed_dir
property
¶
Path to the processed cache directory, suffixed _aligned when the rooms are axis-aligned.
is_area_processed
¶
Check whether an area is fully packed in the processed cache.
Parameters:
-
area(str) –Name of the area (e.g.
Area_1).
Returns:
-
bool–True if every packed file of the area exists, False otherwise.
process
¶
process(
force: bool = False,
num_workers: Optional[int] = None,
show_progress: bool = True,
) -> None
Process the raw dataset for easier loading.
When aligned=True, applies the per-room alignment rotation so that
the stored coordinates are in the globally-aligned frame (the s3disfull
convention). When aligned=False, coordinates are kept in the raw
scan frame.
load
¶
load(
block_size: Optional[float] = None,
block_stride: float = 1.0,
num_nodes: int = 4096,
min_num_nodes: int = 100,
show_progress: bool = True,
) -> None
Load the processed dataset into memory.
If the provided block_size is not None and greater than 0, the rooms will be split into fixed-size
spatial blocks.
Parameters:
-
block_size(Optional[float], default:None) –Side length of each square block in meters.
-
block_stride(float, default:1.0) –Step size for the sliding window in meters. Must be \(\leq\)
block_size. -
num_nodes(int, default:4096) –Fixed number of nodes per block. Nodes are randomly subsampled (or duplicated if the block has fewer nodes).
-
min_num_nodes(int, default:100) –Minimum number of raw nodes for a block to be kept.
-
show_progress(bool, default:True) –Whether to show a progress bar during loading.
S3DISHdf5
¶
S3DISHdf5(
root: PathLike,
*,
areas: Union[
Sequence[S3DISArea], Literal["all"]
] = "all",
classes: Union[
ValueCollection[S3DISClass], Literal["all"]
] = "all",
transform: Optional[Callable] = None,
download: bool = False,
force_download: bool = False,
force_process: bool = False,
show_progress: bool = True,
)
Bases: PointCloudDataset
Pre-processed HDF5 version of the S3DIS dataset used by multiple SOTA reference implementations.
Unlike S3DIS, which loads from the raw annotated rooms, this class loads
the pre-tiled 4096-point blocks distributed as HDF5 files.
The blocks are already spatially tiled and fixed-size, so no additional tiling step is needed.
Each sample is a dict with the following keys:
| Key | Shape | Dtype | Description |
|---|---|---|---|
pos |
\((4096, 3)\) | float32 | XYZ coordinates |
color |
\((4096, 3)\) | float32 | RGB values |
norm_pos |
\((4096, 3)\) | float32 | Room-normalized XYZ coordinates (range \([0,1]\)) |
segment |
\((4096,)\) | int64 | Per-point semantic label (13 classes) |
Labels are emitted in S3DIS_CLASSES order (the archive itself stores them in S3DIS_HDF5_CLASSES order,
which swaps table / chair and sofa / bookcase).
Important
This dataset is already processed and the HDF5 files are used directly.
They are stored in the S3DIS/indoor3d_sem_seg_hdf5_data directory,
meaning that they are co-located with the S3DIS dataset.
Parameters:
-
root(PathLike) –Root directory where
S3DIS/indoor3d_sem_seg_hdf5_data/is stored. -
areas(Union[Sequence[S3DISArea], Literal['all']], default:'all') –Areas to load, either a sequence of area names or
"all". -
classes(Union[ValueCollection[S3DISClass], Literal['all']], default:'all') –Classes to load, either a sequence of class names or
"all". When a subset is selected, labels are remapped to contiguous indices in the given order; unselected classes fall back to the new index ofclutterwhen it is selected, else to the ignore index -1 (matchingS3DIS). -
transform(Optional[Callable], default:None) –Optional callable applied to each sample dict at
__getitem__time. -
download(bool, default:False) –Whether to download the HDF5 archive if not already present.
-
force_download(bool, default:False) –Whether to re-download even if the archive already exists.
-
force_process(bool, default:False) –Whether to force re-processing (no-op for this variant since the HDF5 files are used directly).
-
show_progress(bool, default:True) –Whether to show progress bars during download and loading.
Example
Assuming you have downloaded the HDF5 files from https://shapenet.cs.stanford.edu/media/,
and extracted it under data/S3DIS/indoor3d_sem_seg_hdf5_data, you can load the dataset as follows:
Attributes:
-
name(str) –Name of the dataset directory (shared with
S3DIS). -
class_to_idx(dict[str, int]) –Mapping from class name to label index.
-
raw_dir(str) –Path to the raw download directory.
-
processed_dir(str) –Path to the processed cache directory, which aliases
raw_dirsince the HDF5 blocks are read as-is. -
data_dir(str) –Path to the dataset directory
<root>/<name>.
processed_dir
property
¶
Path to the processed cache directory, which aliases raw_dir since the HDF5 blocks are read as-is.
load_s3dis_room
¶
load_s3dis_room(
room_dir: PathLike, alignment_angle: float | None = None
) -> S3DISRoomData
Load the full S3DIS room from a given directory and (optionally) apply an alignment angle.
Parameters:
-
room_dir(PathLike) –Path to the room directory.
-
alignment_angle(float | None, default:None) –Alignment angle to apply to the room. Defaults to None.
Returns:
-
S3DISRoomData–A dictionary containing the room data.
load_s3dis_alignment_angles
¶
Load the alignment angles for a given area from a text file. In S3DIS dataset, one file is provided for each area, containing the alignment angles for each room in the area. The file is a text file with the following format:
## Global alignment angle per disjoint space in Area_1 ##
## Disjoint Space Name Global Alignment Angle ##
conferenceRoom_1 0
conferenceRoom_2 180
Example
Assuming you have downloaded the raw dataset and extracted it under data/S3DIS/raw,
you can load the alignment angles for the Area_1 as follows:
tile_s3dis_room
¶
tile_s3dis_room(
room: dict[str, Any],
block_size: float = 1.0,
block_stride: float = 1.0,
num_nodes: int = 4096,
min_num_nodes: int = 100,
) -> list[dict[str, Any]]
Split a single room dict into fixed-size spatial blocks.
The algorithm shifts the room so that the minimum point is at the origin, then sweeps a \(\text{block\_size} \times \text{block\_size}\) window (full Z extent) over the room with the given stride. This matches the procedure in multiple SOTA reference implementations (KPFCNN, ...).
Parameters:
-
room(dict[str, Any]) –Dict with at least
DataKeys.POS(float32, \((N, 3)\)). All other tensors with a leading dimension of \(N\) are sliced in parallel. -
block_size(float, default:1.0) –Side length of each square block in meters.
-
block_stride(float, default:1.0) –Step size for the sliding window in meters. Must be \(\leq\)
block_size. -
num_nodes(int, default:4096) –Fixed number of nodes per block. Nodes are randomly subsampled (or duplicated if the block has fewer nodes).
-
min_num_nodes(int, default:100) –Minimum number of raw nodes for a block to be kept.
Returns:
-
list[dict[str, Any]]–List of dicts, one per retained block. Each block has exactly
-
list[dict[str, Any]]–num_nodesnodes (randomly subsampled or oversampled). -
list[dict[str, Any]]–Positions are origin-shifted (room minimum at origin).
Example
Assuming you have downloaded the raw dataset and extracted it under data/S3DIS/raw,
you can tile the room into 1m x 1m blocks as follows: