Skip to content

Commit b1e945e

Browse files
committed
feat: add decorators to check if the corresponding view space exists
Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
1 parent 337ccde commit b1e945e

1 file changed

Lines changed: 43 additions & 33 deletions

File tree

t4_devkit/viewer/viewer.py

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import os.path as osp
44
import warnings
5-
from typing import TYPE_CHECKING, Sequence, overload
5+
from typing import TYPE_CHECKING, Callable, Sequence, overload
66

77
import numpy as np
88
import rerun as rr
@@ -38,6 +38,40 @@
3838
__all__ = ["RerunViewer"]
3939

4040

41+
def _check_spatial3d(function: Callable) -> Callable:
42+
"""Check if the viewer has the 3D view space.
43+
44+
Note:
45+
This function is supposed to be used as a decorator for methods of RerunViewer.
46+
"""
47+
48+
def checker(viewer: RerunViewer, *args, **kwargs):
49+
if not viewer.config.has_spatial3d():
50+
warnings.warn("There is no 3D view space")
51+
return
52+
else:
53+
return function(viewer, *args, **kwargs)
54+
55+
return checker
56+
57+
58+
def _check_spatial2d(function: Callable) -> Callable:
59+
"""Check if the viewer has the 2D view space.
60+
61+
Note:
62+
This function is supposed to be used as a decorator for methods of RerunViewer.
63+
"""
64+
65+
def checker(viewer: RerunViewer, *args, **kwargs):
66+
if not viewer.config.has_spatial2d():
67+
warnings.warn("There is no 2D view space")
68+
return
69+
else:
70+
return function(viewer, *args, **kwargs)
71+
72+
return checker
73+
74+
4175
class RerunViewer:
4276
"""A viewer class that renders some components powered by rerun."""
4377

@@ -154,12 +188,9 @@ def render_box3ds(
154188
"""
155189
pass
156190

191+
@_check_spatial3d
157192
def render_box3ds(self, *args, **kwargs) -> None:
158193
"""Render 3D boxes."""
159-
if not self.config.has_spatial3d():
160-
warnings.warn("There is no 3D view space")
161-
return
162-
163194
if len(args) + len(kwargs) == 2:
164195
self._render_box3ds_with_boxes(*args, **kwargs)
165196
else:
@@ -286,12 +317,9 @@ def render_box2ds(
286317
"""
287318
pass
288319

320+
@_check_spatial2d
289321
def render_box2ds(self, *args, **kwargs) -> None:
290322
"""Render 2D boxes."""
291-
if not self.config.has_spatial2d():
292-
warnings.warn("There is no 2D view space")
293-
return
294-
295323
if len(args) + len(kwargs) == 2:
296324
self._render_box2ds_with_boxes(*args, **kwargs)
297325
else:
@@ -330,6 +358,7 @@ def _render_box2ds_with_elements(
330358
rr.set_time_seconds(self.config.timeline, seconds)
331359
rr.log(format_entity(self.config.ego_entity, camera, "box"), batch.as_boxes2d())
332360

361+
@_check_spatial2d
333362
def render_segmentation2d(
334363
self,
335364
seconds: float,
@@ -348,10 +377,6 @@ def render_segmentation2d(
348377
class_ids (Sequence[int]): Sequence of label ids.
349378
uuids (Sequence[str | None] | None, optional): Sequence of each instance ID.
350379
"""
351-
if not self.config.has_spatial2d():
352-
warnings.warn("There is no 2D view space")
353-
return
354-
355380
rr.set_time_seconds(self.config.timeline, seconds)
356381

357382
batch = BatchSegmentation2D()
@@ -365,6 +390,7 @@ def render_segmentation2d(
365390
batch.as_segmentation_image(),
366391
)
367392

393+
@_check_spatial3d
368394
def render_pointcloud(self, seconds: float, channel: str, pointcloud: PointCloudLike) -> None:
369395
"""Render pointcloud.
370396
@@ -373,10 +399,6 @@ def render_pointcloud(self, seconds: float, channel: str, pointcloud: PointCloud
373399
channel (str): Name of the pointcloud sensor channel.
374400
pointcloud (PointCloudLike): Inherence object of `PointCloud`.
375401
"""
376-
if not self.config.has_spatial3d():
377-
warnings.warn("There is no 3D view space")
378-
return
379-
380402
# TODO(ktro2828): add support of rendering pointcloud on images
381403
rr.set_time_seconds(self.config.timeline, seconds)
382404

@@ -386,6 +408,7 @@ def render_pointcloud(self, seconds: float, channel: str, pointcloud: PointCloud
386408
rr.Points3D(pointcloud.points[:3].T, colors=colors),
387409
)
388410

411+
@_check_spatial2d
389412
def render_image(self, seconds: float, camera: str, image: str | NDArrayU8) -> None:
390413
"""Render an image.
391414
@@ -394,10 +417,6 @@ def render_image(self, seconds: float, camera: str, image: str | NDArrayU8) -> N
394417
camera (str): Name of the camera channel.
395418
image (str | NDArrayU8): Image tensor or path of the image file.
396419
"""
397-
if not self.config.has_spatial3d():
398-
warnings.warn("There is no 3D view space")
399-
return
400-
401420
rr.set_time_seconds(self.config.timeline, seconds)
402421

403422
if isinstance(image, str):
@@ -434,12 +453,9 @@ def render_ego(
434453
"""
435454
pass
436455

456+
@_check_spatial3d
437457
def render_ego(self, *args, **kwargs) -> None:
438458
"""Render an ego pose."""
439-
if not self.config.has_spatial3d():
440-
warnings.warn("There is no 3D view space")
441-
return
442-
443459
if len(args) + len(kwargs) == 1:
444460
self._render_ego_with_schema(*args, **kwargs)
445461
else:
@@ -522,12 +538,9 @@ def render_calibration(
522538
"""
523539
pass
524540

541+
@_check_spatial3d
525542
def render_calibration(self, *args, **kwargs) -> None:
526543
"""Render a sensor calibration."""
527-
if not self.config.has_spatial3d():
528-
warnings.warn("There is no 3D view space")
529-
return
530-
531544
if len(args) + len(kwargs) <= 3:
532545
self._render_calibration_with_schema(*args, **kwargs)
533546
else:
@@ -580,16 +593,13 @@ def _render_calibration_without_schema(
580593
static=True,
581594
)
582595

596+
@_check_spatial3d
583597
def render_map(self, filepath: str) -> None:
584598
"""Render vector map.
585599
586600
Args:
587601
filepath (str): Path to OSM file.
588602
"""
589-
if not self.config.has_spatial3d():
590-
warnings.warn("There is no 3D view space")
591-
return
592-
593603
parser = LaneletParser(filepath, verbose=False)
594604

595605
root_entity = format_entity(self.config.map_entity, "vector_map")

0 commit comments

Comments
 (0)