@@ -318,6 +318,53 @@ def render_pointcloud(
318318 ),
319319 )
320320
321+ def render_lidarseg (
322+ self ,
323+ * ,
324+ max_time_seconds : float = np .inf ,
325+ ignore_distortion : bool = True ,
326+ save_dir : str | None = None ,
327+ ) -> None :
328+ """Render lidar segmentation.
329+
330+ Args:
331+ max_time_seconds (float, optional): Max time length to be rendered [s].
332+ ignore_distortion (bool, optional): Whether to ignore distortion parameters.
333+ save_dir (str | None, optional): Directory path to save the recording.
334+ Viewer will be spawned if it is None, otherwise not.
335+ """
336+ if self ._sample_data_to_lidarseg_filename is None :
337+ return
338+
339+ app_id = f"lidarseg@{ self ._t4 .dataset_id } "
340+ viewer = self ._init_viewer (app_id , render_ann = True , save_dir = save_dir )
341+
342+ self ._render_map (viewer )
343+
344+ # search first lidar sample data token
345+ first_lidar_token : str | None = None
346+ for sensor in self ._t4 .sensor :
347+ if sensor .modality != SensorModality .LIDAR :
348+ continue
349+ first_lidar_token = sensor .first_sd_token
350+
351+ if first_lidar_token is None :
352+ raise ValueError ("There is no 3D pointcloud data." )
353+
354+ first_lidar_sample_data : Sample = self ._t4 .get ("sample_data" , first_lidar_token )
355+ max_timestamp_us = first_lidar_sample_data .timestamp + seconds2microseconds (
356+ max_time_seconds
357+ )
358+
359+ concurrent .futures .wait (
360+ self ._render_lidar_and_ego (
361+ viewer = viewer ,
362+ first_lidar_tokens = [first_lidar_token ],
363+ max_timestamp_us = max_timestamp_us ,
364+ color_mode = PointCloudColorMode .SEGMENTATION ,
365+ )
366+ )
367+
321368 def _render_map (self , viewer : RerunViewer ) -> None :
322369 lanelet_path = osp .join (self ._t4 .map_dir , "lanelet2_map.osm" )
323370 viewer .render_map (lanelet_path )
@@ -342,6 +389,7 @@ def _render_lidar_and_ego(
342389 viewer : RerunViewer ,
343390 first_lidar_tokens : list [str ],
344391 max_timestamp_us : float ,
392+ * ,
345393 color_mode : PointCloudColorMode = PointCloudColorMode .DISTANCE ,
346394 ) -> list [Future ]:
347395 def _render_single_lidar (first_lidar_token : str ) -> None :
@@ -358,26 +406,34 @@ def _render_single_lidar(first_lidar_token: str) -> None:
358406 viewer .render_ego (ego_pose = ego_pose )
359407
360408 # render segmentation pointcloud if available, otherwise render raw pointcloud
361- if (
362- self ._sample_data_to_lidarseg_filename
363- and sample_data .token in self ._sample_data_to_lidarseg_filename
364- ):
409+ if color_mode == PointCloudColorMode .SEGMENTATION :
410+ if not (
411+ self ._sample_data_to_lidarseg_filename
412+ and sample_data .token in self ._sample_data_to_lidarseg_filename
413+ ):
414+ continue
415+
365416 label_filename = self ._sample_data_to_lidarseg_filename [sample_data .token ]
366417 pointcloud = SegmentationPointCloud .from_file (
367418 point_filepath = osp .join (self ._t4 .data_root , sample_data .filename ),
368419 label_filepath = osp .join (self ._t4 .data_root , label_filename ),
369420 )
421+ viewer .render_lidarseg (
422+ seconds = microseconds2seconds (sample_data .timestamp ),
423+ channel = sample_data .channel ,
424+ pointcloud = pointcloud ,
425+ )
370426 else :
371427 pointcloud = LidarPointCloud .from_file (
372428 osp .join (self ._t4 .data_root , sample_data .filename )
373429 )
374430
375- viewer .render_pointcloud (
376- seconds = microseconds2seconds (sample_data .timestamp ),
377- channel = sample_data .channel ,
378- pointcloud = pointcloud ,
379- color_mode = color_mode ,
380- )
431+ viewer .render_pointcloud (
432+ seconds = microseconds2seconds (sample_data .timestamp ),
433+ channel = sample_data .channel ,
434+ pointcloud = pointcloud ,
435+ color_mode = color_mode ,
436+ )
381437
382438 current_lidar_token = sample_data .next
383439
0 commit comments