22
33import os .path as osp
44import warnings
5- from typing import TYPE_CHECKING , Sequence , overload
5+ from typing import TYPE_CHECKING , Callable , Sequence , overload
66
77import numpy as np
88import rerun as rr
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+
4175class 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