scenezoo 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. scenezoo/__init__.py +43 -0
  2. scenezoo/config.py +6 -0
  3. scenezoo/dataset/__init__.py +52 -0
  4. scenezoo/dataset/base.py +247 -0
  5. scenezoo/dataset/builtins.py +320 -0
  6. scenezoo/dataset/check.py +307 -0
  7. scenezoo/dataset/registry.py +297 -0
  8. scenezoo/dataset/scene/__init__.py +38 -0
  9. scenezoo/dataset/scene/_ase_store.py +186 -0
  10. scenezoo/dataset/scene/_structured3d_store.py +124 -0
  11. scenezoo/dataset/scene/arkitscenes.py +1047 -0
  12. scenezoo/dataset/scene/ase.py +1039 -0
  13. scenezoo/dataset/scene/matterport3d.py +1404 -0
  14. scenezoo/dataset/scene/multiscan.py +823 -0
  15. scenezoo/dataset/scene/s3dis.py +536 -0
  16. scenezoo/dataset/scene/scannet.py +706 -0
  17. scenezoo/dataset/scene/scannetpp.py +1237 -0
  18. scenezoo/dataset/scene/scenenn.py +190 -0
  19. scenezoo/dataset/scene/structured3d.py +1413 -0
  20. scenezoo/dataset/scene/threerscan.py +744 -0
  21. scenezoo/dataset/spec.py +95 -0
  22. scenezoo/dataset/types.py +223 -0
  23. scenezoo/io/__init__.py +44 -0
  24. scenezoo/io/archive.py +66 -0
  25. scenezoo/io/cache.py +98 -0
  26. scenezoo/io/camera.py +162 -0
  27. scenezoo/io/compression.py +112 -0
  28. scenezoo/io/image.py +46 -0
  29. scenezoo/io/rio.py +93 -0
  30. scenezoo/io/sens.py +251 -0
  31. scenezoo/io/video.py +232 -0
  32. scenezoo/metadata/3rscan_semantic_mapping.csv +531 -0
  33. scenezoo/metadata/fixed_arkitscenes_direction.csv +869 -0
  34. scenezoo/metadata/multiscan_direction.csv +28 -0
  35. scenezoo/metadata/multiscan_object_semantic_label_map.csv +57 -0
  36. scenezoo/metadata/multiscan_part_semantic_label_map.csv +8 -0
  37. scenezoo/metadata/multiscan_scans_split.csv +274 -0
  38. scenezoo/metadata/scannetv2_test.txt +100 -0
  39. scenezoo/metadata/scannetv2_train.txt +1201 -0
  40. scenezoo/metadata/scannetv2_val.txt +312 -0
  41. scenezoo/metadata/structured3d_errata.txt +99 -0
  42. scenezoo/metadata/structured3d_labelids.txt +40 -0
  43. scenezoo/metadata/structured3d_room_types.txt +16 -0
  44. scenezoo/ops/__init__.py +43 -0
  45. scenezoo/ops/annotation.py +173 -0
  46. scenezoo/ops/frame.py +335 -0
  47. scenezoo/ops/geometry.py +160 -0
  48. scenezoo/rendering.py +134 -0
  49. scenezoo-0.1.0.dist-info/METADATA +270 -0
  50. scenezoo-0.1.0.dist-info/RECORD +53 -0
  51. scenezoo-0.1.0.dist-info/WHEEL +5 -0
  52. scenezoo-0.1.0.dist-info/licenses/LICENSE +201 -0
  53. scenezoo-0.1.0.dist-info/top_level.txt +1 -0
scenezoo/__init__.py ADDED
@@ -0,0 +1,43 @@
1
+ """A small, extensible toolkit for 3D dataset preprocessing."""
2
+
3
+ from .dataset import (
4
+ CheckIssue,
5
+ DataFormatError,
6
+ Dataset,
7
+ DatasetCheckError,
8
+ DatasetCheckReport,
9
+ DatasetInfo,
10
+ DatasetSpec,
11
+ FrameBatch,
12
+ FrameSourceSpec,
13
+ PointBatch,
14
+ SceneZooError,
15
+ Segmentation3D,
16
+ UnsupportedOperationError,
17
+ get_dataset,
18
+ get_dataset_info,
19
+ list_datasets,
20
+ register_dataset,
21
+ )
22
+
23
+ __version__ = "0.1.0"
24
+
25
+ __all__ = [
26
+ "CheckIssue",
27
+ "DataFormatError",
28
+ "Dataset",
29
+ "DatasetCheckError",
30
+ "DatasetCheckReport",
31
+ "DatasetInfo",
32
+ "DatasetSpec",
33
+ "FrameBatch",
34
+ "FrameSourceSpec",
35
+ "PointBatch",
36
+ "SceneZooError",
37
+ "Segmentation3D",
38
+ "UnsupportedOperationError",
39
+ "get_dataset",
40
+ "get_dataset_info",
41
+ "list_datasets",
42
+ "register_dataset",
43
+ ]
scenezoo/config.py ADDED
@@ -0,0 +1,6 @@
1
+ import os
2
+
3
+ XDG_CACHE_HOME = os.getenv("XDG_CACHE_HOME", "~/.cache")
4
+ SCENEZOO_CACHE_DIR = os.path.expanduser(
5
+ os.getenv("SCENEZOO_CACHE_DIR", os.path.join(XDG_CACHE_HOME, "scenezoo"))
6
+ )
@@ -0,0 +1,52 @@
1
+ """Dataset loading, registration, and shared types."""
2
+
3
+ from .base import (
4
+ DataFormatError,
5
+ Dataset,
6
+ DatasetCheckError,
7
+ SceneZooError,
8
+ UnsupportedOperationError,
9
+ )
10
+ from .check import CheckIssue, DatasetCheckReport
11
+ from .registry import (
12
+ DatasetInfo,
13
+ DatasetRegistry,
14
+ _REGISTRY,
15
+ get_dataset,
16
+ get_dataset_info,
17
+ is_registered,
18
+ list_datasets,
19
+ register_dataset,
20
+ )
21
+ from .spec import DatasetSpec, FrameSourceSpec
22
+ from .types import FrameBatch, PointBatch, Segmentation3D
23
+
24
+ from .builtins import register_builtin_datasets
25
+
26
+ # This package exposes adapter classes lazily through ``__getattr__``.
27
+ from . import scene as scene
28
+
29
+ register_builtin_datasets(_REGISTRY)
30
+
31
+ __all__ = [
32
+ "DataFormatError",
33
+ "CheckIssue",
34
+ "Dataset",
35
+ "DatasetCheckError",
36
+ "DatasetCheckReport",
37
+ "DatasetInfo",
38
+ "DatasetRegistry",
39
+ "DatasetSpec",
40
+ "FrameBatch",
41
+ "FrameSourceSpec",
42
+ "PointBatch",
43
+ "SceneZooError",
44
+ "Segmentation3D",
45
+ "UnsupportedOperationError",
46
+ "get_dataset",
47
+ "get_dataset_info",
48
+ "is_registered",
49
+ "list_datasets",
50
+ "register_dataset",
51
+ "scene",
52
+ ]
@@ -0,0 +1,247 @@
1
+ """Core dataset abstraction."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from functools import cached_property
6
+ from pathlib import Path
7
+ from typing import TYPE_CHECKING, Any, ClassVar, Sequence
8
+
9
+ from .spec import DatasetSpec
10
+
11
+ if TYPE_CHECKING:
12
+ from .check import DatasetCheckReport
13
+
14
+
15
+ class SceneZooError(Exception):
16
+ """Base exception raised by scenezoo."""
17
+
18
+
19
+ class UnsupportedOperationError(SceneZooError):
20
+ """Raised when a dataset does not provide a requested operation or item."""
21
+
22
+
23
+ class DataFormatError(SceneZooError):
24
+ """Raised when source data does not match its documented format."""
25
+
26
+
27
+ class DatasetCheckError(SceneZooError):
28
+ """Raised when an explicitly requested dataset check finds errors."""
29
+
30
+ def __init__(self, report: DatasetCheckReport) -> None:
31
+ self.report = report
32
+ super().__init__(report.format())
33
+
34
+
35
+ class Dataset:
36
+ """Minimal base class for 3D scene datasets.
37
+
38
+ Optional operations are regular methods rather than abstract methods. This
39
+ lets partial adapters expose exactly the data they really provide.
40
+ """
41
+
42
+ name: ClassVar[str] = "dataset"
43
+ spec: ClassVar[DatasetSpec] = DatasetSpec()
44
+ _OPERATIONS: ClassVar[dict[str, str]] = {
45
+ "mesh": "get_mesh",
46
+ "points": "get_points",
47
+ "segmentation": "get_segmentation",
48
+ "boxes": "get_boxes",
49
+ "frames": "get_frames",
50
+ }
51
+
52
+ def __init__(
53
+ self,
54
+ root_dir: str | Path,
55
+ *,
56
+ cache_dir: str | Path | None = None,
57
+ offline: bool = False,
58
+ invalid_obj_id: int = -1,
59
+ ) -> None:
60
+ self.root_dir = Path(root_dir).expanduser()
61
+ self.cache_dir = None if cache_dir is None else Path(cache_dir).expanduser()
62
+ self.offline = offline
63
+ self.invalid_obj_id = invalid_obj_id
64
+
65
+ @cached_property
66
+ def splits(self) -> dict[str, list[str]]:
67
+ """Sample IDs of every named split, loaded once on first access."""
68
+
69
+ splits = self._load_splits()
70
+ if not isinstance(splits, dict):
71
+ raise DataFormatError("_load_splits() must return a dictionary.")
72
+ return splits
73
+
74
+ @cached_property
75
+ def metadata(self) -> dict[str, Any]:
76
+ """Dataset-wide metadata such as label maps, loaded once on first access."""
77
+
78
+ metadata = self._load_metadata()
79
+ if not isinstance(metadata, dict):
80
+ raise DataFormatError("_load_metadata() must return a dictionary.")
81
+ return metadata
82
+
83
+ def _load_splits(self) -> dict[str, list[str]]:
84
+ raise NotImplementedError
85
+
86
+ def _load_metadata(self) -> dict[str, Any]:
87
+ return {}
88
+
89
+ def get_ids(self, split: str) -> list[str]:
90
+ """Return the sample IDs of ``split``; see :attr:`splits` for the names."""
91
+
92
+ try:
93
+ return self.splits[split]
94
+ except KeyError as exc:
95
+ available = ", ".join(sorted(self.splits))
96
+ raise KeyError(
97
+ f"Unknown split {split!r}. Available splits: {available}"
98
+ ) from exc
99
+
100
+ def open_file(self, file_path: str | Path, mode: str = "rb"):
101
+ """Open a local or cached remote metadata file using this dataset's policy."""
102
+ from ..io.cache import open_cached_file
103
+
104
+ return open_cached_file(
105
+ file_path,
106
+ mode,
107
+ cache_dir=self.cache_dir,
108
+ offline=self.offline,
109
+ )
110
+
111
+ def check(
112
+ self,
113
+ *,
114
+ sample_ids: Sequence[str] | None = None,
115
+ require_complete: bool = False,
116
+ raise_on_error: bool = False,
117
+ ) -> DatasetCheckReport:
118
+ """Explicitly inspect the dataset path and return an actionable report.
119
+
120
+ Checks are never run by the constructor or by data access methods. Use
121
+ ``sample_ids`` for a focused check, or ``require_complete=True`` to treat
122
+ missing scenes from declared splits as errors rather than warnings.
123
+ """
124
+
125
+ report = self._check(
126
+ sample_ids=sample_ids,
127
+ require_complete=require_complete,
128
+ )
129
+ if raise_on_error:
130
+ report.raise_for_errors()
131
+ return report
132
+
133
+ def _check(
134
+ self,
135
+ *,
136
+ sample_ids: Sequence[str] | None,
137
+ require_complete: bool,
138
+ ) -> DatasetCheckReport:
139
+ from .check import CheckBuilder
140
+
141
+ builder = CheckBuilder(self.name, self.root_dir)
142
+ builder.require_directory(
143
+ self.root_dir,
144
+ code="missing-root",
145
+ message="The configured dataset root does not exist or is not a directory.",
146
+ expected="An existing directory containing the dataset files.",
147
+ hint="Correct root_dir or download and extract the dataset first.",
148
+ )
149
+ return builder.finish()
150
+
151
+ @classmethod
152
+ def supports(cls, operation: str) -> bool:
153
+ """Whether this adapter implements a standard operation.
154
+
155
+ ``operation`` is one of ``mesh``, ``points``, ``segmentation``,
156
+ ``boxes``, or ``frames``.
157
+ """
158
+
159
+ try:
160
+ method_name = cls._OPERATIONS[operation]
161
+ except KeyError as exc:
162
+ valid = ", ".join(sorted(cls._OPERATIONS))
163
+ raise ValueError(
164
+ f"Unknown operation {operation!r}. Valid operations: {valid}"
165
+ ) from exc
166
+ return getattr(cls, method_name) is not getattr(Dataset, method_name)
167
+
168
+ @classmethod
169
+ def capabilities(cls) -> tuple[str, ...]:
170
+ """The standard operations this adapter implements."""
171
+
172
+ return tuple(name for name in cls._OPERATIONS if cls.supports(name))
173
+
174
+ def _unsupported(self, operation: str) -> None:
175
+ raise UnsupportedOperationError(
176
+ f"{self.__class__.__name__} does not support the {operation!r} operation."
177
+ )
178
+
179
+ def get_mesh(self, sample_id: str, *, mesh_type: str | None = None):
180
+ """Return an Open3D ``TriangleMesh``.
181
+
182
+ ``mesh_type`` selects a dataset-specific variant listed in
183
+ ``spec.mesh_types``; ``None`` selects the adapter's default.
184
+ """
185
+
186
+ self._unsupported("mesh")
187
+
188
+ def get_points(self, sample_id: str):
189
+ """Return a :class:`~scenezoo.PointBatch` with row-aligned attributes."""
190
+
191
+ self._unsupported("points")
192
+
193
+ def get_segmentation(self, sample_id: str):
194
+ """Return :class:`~scenezoo.Segmentation3D` labels.
195
+
196
+ Labels are defined on the ``domain`` the result reports (points, mesh
197
+ vertices, or mesh faces) and align with the matching geometry.
198
+ """
199
+
200
+ self._unsupported("segmentation")
201
+
202
+ def get_boxes(self, sample_id: str, *, box_type: str = "mobb_gravity"):
203
+ """Return ``(boxes_by_id, id_to_name)`` with Open3D bounding boxes.
204
+
205
+ ``box_type`` is ``obb_gt`` for released annotations, or ``aabb``,
206
+ ``obb``, ``mobb``, or ``mobb_gravity`` to fit boxes to annotated points.
207
+ """
208
+
209
+ self._unsupported("boxes")
210
+
211
+ def get_frames(
212
+ self,
213
+ sample_id: str,
214
+ *,
215
+ indices=None,
216
+ step: int = 1,
217
+ items=("rgb", "rgb_intrinsics", "world_to_camera"),
218
+ output_size=None,
219
+ center_crop: bool = False,
220
+ rotate_to_up: bool = True,
221
+ ):
222
+ """Return synchronized frames as a :class:`~scenezoo.FrameBatch`.
223
+
224
+ Args:
225
+ indices: Source frame numbers to read, in the requested order.
226
+ ``None`` selects every frame with a valid camera.
227
+ step: Sampling stride when ``indices`` is ``None``.
228
+ items: :class:`~scenezoo.FrameBatch` fields to load.
229
+ output_size: Optional ``(width, height)`` for every image item.
230
+ center_crop: Preserve the aspect ratio by resizing then cropping.
231
+ rotate_to_up: Rotate portrait captures upright; the camera roll is
232
+ applied to ``world_to_camera`` so intrinsics stay pinhole.
233
+ """
234
+
235
+ self._unsupported("frames")
236
+
237
+ def __repr__(self) -> str:
238
+ loaded_splits = self.__dict__.get("splits")
239
+ split_sizes = (
240
+ None
241
+ if loaded_splits is None
242
+ else {key: len(value) for key, value in loaded_splits.items()}
243
+ )
244
+ return (
245
+ f"{self.__class__.__name__}(root_dir={str(self.root_dir)!r}, "
246
+ f"splits={split_sizes})"
247
+ )
@@ -0,0 +1,320 @@
1
+ """Import-light catalog for built-in dataset adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .spec import DatasetSpec, FrameSourceSpec
6
+
7
+ _RGBD_ITEMS = (
8
+ "rgb",
9
+ "depth",
10
+ "rgb_intrinsics",
11
+ "depth_intrinsics",
12
+ "world_to_camera",
13
+ )
14
+
15
+
16
+ BUILTIN_DATASETS = (
17
+ {
18
+ "name": "scannetv2",
19
+ "aliases": ("scannet",),
20
+ "import_path": "scenezoo.dataset.scene.scannet:ScanNet",
21
+ "description": "ScanNet v2 indoor RGB-D scenes.",
22
+ "spec": DatasetSpec(
23
+ sample_unit="scene",
24
+ operations=("mesh", "segmentation", "boxes", "frames"),
25
+ mesh_types=("raw", "decimated", "semantic"),
26
+ segmentation_types=("instance", "semantic"),
27
+ box_types=("aabb", "obb", "mobb", "mobb_gravity"),
28
+ label_spaces=("scannet", "nyu40"),
29
+ frame_sources=(
30
+ FrameSourceSpec(
31
+ "sens",
32
+ _RGBD_ITEMS
33
+ + ("instance_maps", "semantic_maps", "timestamps", "imu"),
34
+ ("PINHOLE",),
35
+ ),
36
+ ),
37
+ ),
38
+ },
39
+ {
40
+ "name": "scannetppv2",
41
+ "aliases": ("scannet++", "scannetpp", "scannet++v2"),
42
+ "import_path": "scenezoo.dataset.scene.scannetpp:ScanNetPP",
43
+ "description": "ScanNet++ v2 scans with iPhone, DSLR, and panoramic captures.",
44
+ "spec": DatasetSpec(
45
+ sample_unit="scene",
46
+ operations=("mesh", "points", "segmentation", "boxes", "frames"),
47
+ mesh_types=("raw", "semantic"),
48
+ segmentation_types=("instance", "semantic"),
49
+ box_types=("aabb", "obb", "mobb", "mobb_gravity"),
50
+ frame_sources=(
51
+ FrameSourceSpec(
52
+ "iphone",
53
+ _RGBD_ITEMS + ("frame_mask", "timestamps", "imu"),
54
+ ("PINHOLE",),
55
+ ),
56
+ FrameSourceSpec(
57
+ "iphone_colmap",
58
+ _RGBD_ITEMS + ("frame_mask", "timestamps", "imu"),
59
+ ("SIMPLE_PINHOLE", "PINHOLE", "OPENCV", "OPENCV_FISHEYE"),
60
+ ),
61
+ FrameSourceSpec(
62
+ "dslr",
63
+ (
64
+ "rgb",
65
+ "rgb_intrinsics",
66
+ "world_to_camera",
67
+ "frame_mask",
68
+ "is_bad",
69
+ ),
70
+ ("SIMPLE_PINHOLE", "PINHOLE", "OPENCV", "OPENCV_FISHEYE"),
71
+ ),
72
+ FrameSourceSpec(
73
+ "dslr_undistorted",
74
+ (
75
+ "rgb",
76
+ "rgb_intrinsics",
77
+ "world_to_camera",
78
+ "frame_mask",
79
+ "is_bad",
80
+ ),
81
+ ("PINHOLE",),
82
+ ),
83
+ FrameSourceSpec(
84
+ "dslr_original",
85
+ (
86
+ "rgb",
87
+ "rgb_intrinsics",
88
+ "world_to_camera",
89
+ "frame_mask",
90
+ "is_bad",
91
+ ),
92
+ ("SIMPLE_PINHOLE", "PINHOLE", "OPENCV", "OPENCV_FISHEYE"),
93
+ ),
94
+ FrameSourceSpec(
95
+ "panocam",
96
+ (
97
+ "rgb",
98
+ "depth",
99
+ "world_to_camera",
100
+ "frame_mask",
101
+ "azimuth",
102
+ "elevation",
103
+ ),
104
+ ("EQUIRECTANGULAR",),
105
+ ),
106
+ FrameSourceSpec(
107
+ "panocam_resized",
108
+ (
109
+ "rgb",
110
+ "depth",
111
+ "world_to_camera",
112
+ "frame_mask",
113
+ "azimuth",
114
+ "elevation",
115
+ ),
116
+ ("EQUIRECTANGULAR",),
117
+ ),
118
+ ),
119
+ ),
120
+ },
121
+ {
122
+ "name": "arkitscenes",
123
+ "aliases": (),
124
+ "import_path": "scenezoo.dataset.scene.arkitscenes:ARKitScenes",
125
+ "description": "ARKitScenes scans, mobile RGB-D streams, and FARO captures.",
126
+ "spec": DatasetSpec(
127
+ sample_unit="scene",
128
+ operations=("mesh", "segmentation", "boxes", "frames"),
129
+ mesh_types=("raw",),
130
+ segmentation_types=("instance",),
131
+ box_types=("obb_gt",),
132
+ frame_sources=tuple(
133
+ FrameSourceSpec(
134
+ name,
135
+ _RGBD_ITEMS + ("confidence_maps", "timestamps"),
136
+ ("PINHOLE",),
137
+ )
138
+ for name in ("mov", "lowres_wide", "wide")
139
+ )
140
+ + tuple(
141
+ FrameSourceSpec(
142
+ name,
143
+ ("rgb", "rgb_intrinsics", "world_to_camera", "timestamps"),
144
+ ("PINHOLE",),
145
+ )
146
+ for name in ("ultrawide", "vga_wide")
147
+ )
148
+ + (
149
+ FrameSourceSpec(
150
+ "threedod",
151
+ _RGBD_ITEMS + ("timestamps",),
152
+ ("PINHOLE",),
153
+ ),
154
+ ),
155
+ ),
156
+ },
157
+ {
158
+ "name": "multiscan",
159
+ "aliases": (),
160
+ "import_path": "scenezoo.dataset.scene.multiscan:MultiScan",
161
+ "description": "MultiScan indoor scenes.",
162
+ "spec": DatasetSpec(
163
+ sample_unit="scene",
164
+ operations=("mesh", "segmentation", "boxes", "frames"),
165
+ mesh_types=("ply", "textured"),
166
+ segmentation_types=(
167
+ "object_instance",
168
+ "part_instance",
169
+ "object_semantic",
170
+ "part_semantic",
171
+ ),
172
+ box_types=("aabb", "obb", "mobb", "mobb_gravity", "obb_gt"),
173
+ frame_sources=(
174
+ FrameSourceSpec(
175
+ "capture",
176
+ _RGBD_ITEMS
177
+ + ("confidence_maps", "timestamps", "exposure_durations"),
178
+ ("PINHOLE",),
179
+ ),
180
+ ),
181
+ ),
182
+ },
183
+ {
184
+ "name": "ase",
185
+ "aliases": ("aria-ase", "aria-synthetic-environments"),
186
+ "import_path": ("scenezoo.dataset.scene.ase:AriaSyntheticEnvironments"),
187
+ "description": "Aria Synthetic Environments egocentric synthetic scenes.",
188
+ "spec": DatasetSpec(
189
+ sample_unit="sequence",
190
+ operations=("points", "boxes", "frames"),
191
+ box_types=("obb_gt",),
192
+ frame_sources=(
193
+ FrameSourceSpec(
194
+ "rgb",
195
+ _RGBD_ITEMS + ("instance_maps", "frame_mask", "timestamps"),
196
+ ("FISHEYE624",),
197
+ ),
198
+ ),
199
+ ),
200
+ },
201
+ {
202
+ "name": "3rscan",
203
+ "aliases": ("threerscan",),
204
+ "import_path": "scenezoo.dataset.scene.threerscan:ThreeRScan",
205
+ "description": "3RScan indoor scene sequences.",
206
+ "spec": DatasetSpec(
207
+ sample_unit="scene",
208
+ operations=("mesh", "segmentation", "boxes", "frames"),
209
+ mesh_types=("textured", "instance", "instance_aligned"),
210
+ segmentation_types=(
211
+ "instance",
212
+ "global",
213
+ "nyu40",
214
+ "eigen13",
215
+ "rio27",
216
+ "rio7",
217
+ ),
218
+ box_types=("aabb", "obb", "mobb", "mobb_gravity", "obb_gt"),
219
+ label_spaces=("global", "nyu40", "eigen13", "rio27", "rio7"),
220
+ frame_sources=(FrameSourceSpec("sequence", _RGBD_ITEMS, ("PINHOLE",)),),
221
+ ),
222
+ },
223
+ {
224
+ "name": "s3dis",
225
+ "aliases": ("stanford3d", "stanford-3d"),
226
+ "import_path": "scenezoo.dataset.scene.s3dis:S3DIS",
227
+ "description": "S3DIS room point clouds, point-domain labels, and boxes.",
228
+ "spec": DatasetSpec(
229
+ sample_unit="room",
230
+ operations=("points", "segmentation", "boxes"),
231
+ segmentation_types=("instance", "semantic"),
232
+ box_types=("aabb", "obb", "mobb", "mobb_gravity"),
233
+ label_spaces=("s3dis13",),
234
+ ),
235
+ },
236
+ {
237
+ "name": "matterport3d",
238
+ "aliases": (),
239
+ "import_path": "scenezoo.dataset.scene.matterport3d:Matterport3D",
240
+ "description": "Matterport3D houses with region annotations and RGB-D views.",
241
+ "spec": DatasetSpec(
242
+ sample_unit="scene",
243
+ operations=("mesh", "segmentation", "boxes", "frames"),
244
+ mesh_types=("raw", "house", "region", "poisson"),
245
+ segmentation_types=("instance", "semantic"),
246
+ box_types=("obb_gt", "aabb", "obb", "mobb", "mobb_gravity"),
247
+ label_spaces=("raw", "mpcat40", "nyu40", "eigen13"),
248
+ frame_sources=(
249
+ FrameSourceSpec(
250
+ "raw",
251
+ _RGBD_ITEMS,
252
+ ("OPENCV",),
253
+ ),
254
+ FrameSourceSpec(
255
+ "undistorted",
256
+ _RGBD_ITEMS,
257
+ ("PINHOLE",),
258
+ ),
259
+ ),
260
+ ),
261
+ },
262
+ {
263
+ "name": "scenenn",
264
+ "aliases": (),
265
+ "import_path": "scenezoo.dataset.scene.scenenn:SceneNN",
266
+ "description": "SceneNN meshes and vertex-domain instance segmentation.",
267
+ "spec": DatasetSpec(
268
+ sample_unit="scene",
269
+ operations=("mesh", "segmentation"),
270
+ mesh_types=("raw", "instance"),
271
+ segmentation_types=("instance",),
272
+ ),
273
+ },
274
+ {
275
+ "name": "structured3d",
276
+ "aliases": ("structure3d",),
277
+ "import_path": "scenezoo.dataset.scene.structured3d:Structured3D",
278
+ "description": "Structured3D renderings, layouts, boxes, and fused points.",
279
+ "spec": DatasetSpec(
280
+ sample_unit="scene",
281
+ operations=("mesh", "points", "segmentation", "boxes", "frames"),
282
+ mesh_types=("layout",),
283
+ segmentation_types=("instance", "semantic"),
284
+ box_types=("obb_gt",),
285
+ label_spaces=("nyu40", "pointcept25"),
286
+ frame_sources=(
287
+ FrameSourceSpec(
288
+ "perspective",
289
+ _RGBD_ITEMS
290
+ + ("semantic_maps", "instance_maps", "albedo", "normal_maps"),
291
+ ("PINHOLE",),
292
+ ("empty", "full"),
293
+ ("room_id",),
294
+ ),
295
+ FrameSourceSpec(
296
+ "panorama",
297
+ (
298
+ "rgb",
299
+ "depth",
300
+ "world_to_camera",
301
+ "semantic_maps",
302
+ "instance_maps",
303
+ "albedo",
304
+ "normal_maps",
305
+ ),
306
+ ("EQUIRECTANGULAR",),
307
+ ("empty", "simple", "full"),
308
+ ("room_id",),
309
+ ),
310
+ ),
311
+ ),
312
+ },
313
+ )
314
+
315
+
316
+ def register_builtin_datasets(registry) -> None:
317
+ """Populate a registry without importing any adapter modules."""
318
+
319
+ for entry in BUILTIN_DATASETS:
320
+ registry.register_lazy(**entry)