5
5
# This GUI is built on top of the great work of MonoGS (https://github.com/muskie82/MonoGS/blob/main/gui/slam_gui.py)
6
6
7
7
from typing import Dict , List , Tuple
8
- import pathlib
9
8
import threading
10
9
import time
11
10
from datetime import datetime
18
17
import open3d as o3d
19
18
import open3d .visualization .gui as gui
20
19
import open3d .visualization .rendering as rendering
21
- import torch
22
20
23
21
from pickle import load , dump
24
22
@@ -303,7 +301,7 @@ def init_widget(self):
303
301
self ._on_load_view_btn
304
302
) # set the callback function
305
303
306
- self .reset_view_btn = gui .Button ("Reset Viewpoint " )
304
+ self .reset_view_btn = gui .Button ("Reset" )
307
305
self .reset_view_btn .set_on_clicked (
308
306
self ._on_reset_view_btn
309
307
) # set the callback function
@@ -336,24 +334,19 @@ def init_widget(self):
336
334
chbox_tile_3dobj .add_child (self .mesh_chbox )
337
335
self .mesh_name = "pin_mesh"
338
336
339
- self .cmesh_chbox = gui .Checkbox ("Mesh (color)" )
340
- self .cmesh_chbox .checked = False
341
- self .cmesh_chbox .set_on_checked (self ._on_cmesh_chbox )
342
- chbox_tile_3dobj .add_child (self .cmesh_chbox )
343
-
344
337
self .sdf_chbox = gui .Checkbox ("SDF Slice" )
345
338
self .sdf_chbox .checked = self .sdf_default_on
346
339
self .sdf_chbox .set_on_checked (self ._on_sdf_chbox )
347
340
chbox_tile_3dobj .add_child (self .sdf_chbox )
348
341
self .sdf_name = "cur_sdf_slice"
349
-
350
- chbox_tile_3dobj_2 = gui .Horiz (0.5 * em , gui .Margins (margin ))
351
342
352
343
self .cad_chbox = gui .Checkbox ("Robot" )
353
344
self .cad_chbox .checked = self .robot_default_on
354
345
self .cad_chbox .set_on_checked (self ._on_cad_chbox )
355
- chbox_tile_3dobj_2 .add_child (self .cad_chbox )
346
+ chbox_tile_3dobj .add_child (self .cad_chbox )
356
347
self .cad_name = "sensor_cad"
348
+
349
+ chbox_tile_3dobj_2 = gui .Horiz (0.5 * em , gui .Margins (margin ))
357
350
358
351
self .gt_traj_chbox = gui .Checkbox ("GT Trajectory" )
359
352
self .gt_traj_chbox .checked = False
@@ -386,11 +379,6 @@ def init_widget(self):
386
379
chbox_tile_3dobj_3 .add_child (self .sdf_pool_chbox )
387
380
self .sdf_pool_name = "sdf_sample_pool"
388
381
389
- self .source_pc_chbox = gui .Checkbox ("Scan Registration Weight" )
390
- self .source_pc_chbox .checked = False
391
- chbox_tile_3dobj_3 .add_child (self .source_pc_chbox )
392
- self .source_pc_name = "source_pc"
393
-
394
382
self .range_circle_chbox = gui .Checkbox ("Range Rings" )
395
383
self .range_circle_chbox .checked = False
396
384
self .range_circle_chbox .set_on_checked (self ._on_range_circle_chbox )
@@ -400,6 +388,40 @@ def init_widget(self):
400
388
self .panel .add_child (chbox_tile_3dobj )
401
389
self .panel .add_child (chbox_tile_3dobj_2 )
402
390
self .panel .add_child (chbox_tile_3dobj_3 )
391
+
392
+ self .panel .add_child (gui .Label ("Scan Color Options" ))
393
+ chbox_tile_scan_color = gui .Horiz (0.5 * em , gui .Margins (margin ))
394
+
395
+ # mode 1
396
+ self .scan_color_chbox = gui .Checkbox ("Color" )
397
+ self .scan_color_chbox .checked = True
398
+ self .scan_color_chbox .set_on_checked (self ._on_scan_color_chbox )
399
+ chbox_tile_scan_color .add_child (self .scan_color_chbox )
400
+
401
+ # mode 2
402
+ self .scan_regis_color_chbox = gui .Checkbox ("Registration Weight" )
403
+ self .scan_regis_color_chbox .checked = False
404
+ self .scan_regis_color_chbox .set_on_checked (self ._on_scan_regis_color_chbox )
405
+ chbox_tile_scan_color .add_child (self .scan_regis_color_chbox )
406
+
407
+ # mode 3
408
+ self .scan_height_color_chbox = gui .Checkbox ("Height" )
409
+ self .scan_height_color_chbox .checked = False
410
+ self .scan_height_color_chbox .set_on_checked (self ._on_scan_height_color_chbox )
411
+ chbox_tile_scan_color .add_child (self .scan_height_color_chbox )
412
+
413
+ self .panel .add_child (chbox_tile_scan_color )
414
+
415
+ scan_point_size_slider_tile = gui .Horiz (0.5 * em , gui .Margins (margin ))
416
+ scan_point_size_slider_label = gui .Label ("Scan point size (1-6) " )
417
+ self .scan_point_size_slider = gui .Slider (gui .Slider .INT )
418
+ self .scan_point_size_slider .set_limits (1 , 6 )
419
+ self .scan_point_size_slider .int_value = self .scan_render_init_size_unit
420
+ self .scan_point_size_slider .set_on_value_changed (self ._on_scan_point_size_changed )
421
+ scan_point_size_slider_tile .add_child (scan_point_size_slider_label )
422
+ scan_point_size_slider_tile .add_child (self .scan_point_size_slider )
423
+ self .panel .add_child (scan_point_size_slider_tile )
424
+
403
425
404
426
self .panel .add_child (gui .Label ("Neural Point Color Options" ))
405
427
chbox_tile_neuralpoint = gui .Horiz (0.5 * em , gui .Margins (margin ))
@@ -440,17 +462,29 @@ def init_widget(self):
440
462
map_point_size_slider_tile .add_child (self .map_point_size_slider )
441
463
self .panel .add_child (map_point_size_slider_tile )
442
464
443
- scan_point_size_slider_tile = gui .Horiz (0.5 * em , gui .Margins (margin ))
444
- scan_point_size_slider_label = gui .Label ("Scan point size (1-6) " )
445
- self .scan_point_size_slider = gui .Slider (gui .Slider .INT )
446
- self .scan_point_size_slider .set_limits (1 , 6 )
447
- self .scan_point_size_slider .int_value = self .scan_render_init_size_unit
448
- self .scan_point_size_slider .set_on_value_changed (self ._on_scan_point_size_changed )
449
- scan_point_size_slider_tile .add_child (scan_point_size_slider_label )
450
- scan_point_size_slider_tile .add_child (self .scan_point_size_slider )
451
- self .panel .add_child (scan_point_size_slider_tile )
465
+ self .panel .add_child (gui .Label ("Mesh Color Options" ))
452
466
453
- self .panel .add_child (gui .Label ("Mesh Reconstruction Options" ))
467
+ chbox_tile_mesh_color = gui .Horiz (0.5 * em , gui .Margins (margin ))
468
+
469
+ # mode 1
470
+ self .mesh_normal_chbox = gui .Checkbox ("Normal" )
471
+ self .mesh_normal_chbox .checked = True
472
+ self .mesh_normal_chbox .set_on_checked (self ._on_mesh_normal_chbox )
473
+ chbox_tile_mesh_color .add_child (self .mesh_normal_chbox )
474
+
475
+ # mode 2
476
+ self .mesh_color_chbox = gui .Checkbox ("Color" )
477
+ self .mesh_color_chbox .checked = False
478
+ self .mesh_color_chbox .set_on_checked (self ._on_mesh_color_chbox )
479
+ chbox_tile_mesh_color .add_child (self .mesh_color_chbox )
480
+
481
+ # mode 3
482
+ self .mesh_height_chbox = gui .Checkbox ("Height" )
483
+ self .mesh_height_chbox .checked = False
484
+ self .mesh_height_chbox .set_on_checked (self ._on_mesh_height_chbox )
485
+ chbox_tile_mesh_color .add_child (self .mesh_height_chbox )
486
+
487
+ self .panel .add_child (chbox_tile_mesh_color )
454
488
455
489
mesh_freq_frame_slider_tile = gui .Horiz (0.5 * em , gui .Margins (margin ))
456
490
mesh_freq_frame_slider_label = gui .Label ("Mesh update per X frames (1-100)" )
@@ -602,13 +636,6 @@ def _on_neural_point_chbox(self, is_checked):
602
636
def _on_mesh_chbox (self , is_checked ):
603
637
self .visualize_mesh ()
604
638
605
- def _on_cmesh_chbox (self , is_checked ):
606
- if is_checked :
607
- self .mesh_render .shader = "defaultLit"
608
- else :
609
- self .mesh_render .shader = "normals"
610
- self .visualize_mesh ()
611
-
612
639
def _on_scan_chbox (self , is_checked ):
613
640
self .visualize_scan ()
614
641
@@ -646,29 +673,72 @@ def _on_range_circle_chbox(self, is_checked):
646
673
else :
647
674
self .widget3d .scene .remove_geometry (self .range_circle_name )
648
675
676
+ def _on_mesh_normal_chbox (self , is_checked ):
677
+ if is_checked :
678
+ self .mesh_render .shader = "normals"
679
+ self .mesh_color_chbox .checked = False
680
+ self .mesh_height_chbox .checked = False
681
+ self .visualize_mesh ()
682
+
683
+ def _on_mesh_color_chbox (self , is_checked ):
684
+ if is_checked :
685
+ self .mesh_render .shader = "defaultLit"
686
+ self .mesh_normal_chbox .checked = False
687
+ self .mesh_height_chbox .checked = False
688
+ self .visualize_mesh ()
689
+
690
+ def _on_mesh_height_chbox (self , is_checked ):
691
+ if is_checked :
692
+ self .mesh_render .shader = "defaultLit"
693
+ self .mesh_normal_chbox .checked = False
694
+ self .mesh_color_chbox .checked = False
695
+ self .visualize_mesh ()
696
+
697
+ def _on_scan_color_chbox (self , is_checked ):
698
+ if is_checked :
699
+ self .scan_height_color_chbox .checked = False
700
+ self .scan_regis_color_chbox .checked = False
701
+ self .visualize_scan ()
702
+
703
+ def _on_scan_regis_color_chbox (self , is_checked ):
704
+ if is_checked :
705
+ self .scan_height_color_chbox .checked = False
706
+ self .scan_color_chbox .checked = False
707
+ self .visualize_scan ()
708
+
709
+ def _on_scan_height_color_chbox (self , is_checked ):
710
+ if is_checked :
711
+ self .scan_color_chbox .checked = False
712
+ self .scan_regis_color_chbox .checked = False
713
+ self .visualize_scan ()
714
+
649
715
def _on_neuralpoint_geofeature_chbox (self , is_checked ):
650
716
if is_checked :
651
717
self .neuralpoint_colorfeature_chbox .checked = False
652
718
self .neuralpoint_height_chbox .checked = False
653
719
self .neuralpoint_ts_chbox .checked = False
720
+ self .visualize_neural_points ()
654
721
655
722
def _on_neuralpoint_colorfeature_chbox (self , is_checked ):
656
723
if is_checked :
657
724
self .neuralpoint_geofeature_chbox .checked = False
658
725
self .neuralpoint_height_chbox .checked = False
659
726
self .neuralpoint_ts_chbox .checked = False
727
+ self .visualize_neural_points ()
660
728
661
729
def _on_neuralpoint_ts_chbox (self , is_checked ):
662
730
if is_checked :
663
731
self .neuralpoint_geofeature_chbox .checked = False
664
732
self .neuralpoint_height_chbox .checked = False
665
733
self .neuralpoint_colorfeature_chbox .checked = False
734
+ self .visualize_neural_points ()
666
735
667
736
def _on_neuralpoint_height_chbox (self , is_checked ):
668
737
if is_checked :
669
738
self .neuralpoint_geofeature_chbox .checked = False
670
739
self .neuralpoint_ts_chbox .checked = False
671
740
self .neuralpoint_colorfeature_chbox .checked = False
741
+ self .visualize_neural_points ()
672
742
673
743
def _on_neural_point_point_size_changed (self , value ):
674
744
self .neural_points_render .point_size = value * self .window .scaling
@@ -815,12 +885,21 @@ def visualize_mesh(self, data_packet = None):
815
885
o3d .utility .Vector3dVector (data_packet .mesh_verts ),
816
886
o3d .utility .Vector3iVector (data_packet .mesh_faces ),
817
887
)
818
- if data_packet .mesh_verts_rgb is not None :
819
- self .mesh .vertex_colors = o3d .utility .Vector3dVector (data_packet .mesh_verts_rgb )
820
888
self .mesh .compute_vertex_normals ()
889
+
890
+ if data_packet .mesh_verts_rgb is not None :
891
+ self .mesh .vertex_colors = o3d .utility .Vector3dVector (data_packet .mesh_verts_rgb )
892
+
893
+ if self .mesh_height_chbox .checked :
894
+ z_values = np .array (self .mesh .vertices , dtype = np .float64 )[:, 2 ]
895
+ z_min , z_max = z_values .min (), z_values .max ()
896
+ z_normalized = (z_values - z_min ) / (z_max - z_min + 1e-6 )
897
+ color_map = cm .get_cmap ("jet" )
898
+ mesh_verts_colors_np = color_map (z_normalized )[:, :3 ].astype (np .float64 )
899
+ self .mesh .vertex_colors = o3d .utility .Vector3dVector (mesh_verts_colors_np )
821
900
822
- if self .ego_chbox .checked :
823
- self .mesh .transform (np .linalg .inv (self .cur_pose ))
901
+ if self .ego_chbox .checked :
902
+ self .mesh .transform (np .linalg .inv (self .cur_pose ))
824
903
825
904
self .widget3d .scene .remove_geometry (self .mesh_name )
826
905
self .widget3d .scene .add_geometry (self .mesh_name , self .mesh , self .mesh_render )
@@ -864,42 +943,46 @@ def visualize_neural_points(self, data_packet = None):
864
943
neural_point_vis_down_rate = find_closest_prime (point_count // 200000 )
865
944
866
945
if local_mask is not None and self .local_map_chbox .checked :
867
- neural_point_position = data_packet .neural_points_data ["position" ][local_mask ]. detach (). cpu (). numpy ()
946
+ neural_point_position = data_packet .neural_points_data ["position" ][local_mask ]
868
947
else :
869
- neural_point_position = data_packet .neural_points_data ["position" ].detach ().cpu ().numpy ()
948
+ neural_point_position = data_packet .neural_points_data ["position" ]
949
+
950
+ neural_point_position_np = neural_point_position [::neural_point_vis_down_rate , :].detach ().cpu ().numpy ()
870
951
871
- neural_point_colors = None
952
+ neural_point_colors_np = None
872
953
873
954
if "color_pca_geo" in dict_keys and self .neuralpoint_geofeature_chbox .checked :
874
955
if local_mask is not None and self .local_map_chbox .checked :
875
- neural_point_colors = data_packet .neural_points_data ["color_pca_geo" ][local_mask ]. detach (). cpu (). numpy ()
956
+ neural_point_colors = data_packet .neural_points_data ["color_pca_geo" ][local_mask ]
876
957
else :
877
- neural_point_colors = data_packet .neural_points_data ["color_pca_geo" ].detach ().cpu ().numpy ()
958
+ neural_point_colors = data_packet .neural_points_data ["color_pca_geo" ]
959
+ neural_point_colors_np = neural_point_colors [::neural_point_vis_down_rate , :].detach ().cpu ().numpy ()
878
960
elif "color_pca_color" in dict_keys and self .neuralpoint_colorfeature_chbox .checked :
879
961
if local_mask is not None and self .local_map_chbox .checked :
880
- neural_point_colors = data_packet .neural_points_data ["color_pca_color" ][local_mask ]. detach (). cpu (). numpy ()
962
+ neural_point_colors = data_packet .neural_points_data ["color_pca_color" ][local_mask ]
881
963
else :
882
- neural_point_colors = data_packet .neural_points_data ["color_pca_color" ].detach ().cpu ().numpy ()
964
+ neural_point_colors = data_packet .neural_points_data ["color_pca_color" ]
965
+ neural_point_colors_np = neural_point_colors [::neural_point_vis_down_rate , :].detach ().cpu ().numpy ()
883
966
elif "ts" in dict_keys and self .neuralpoint_ts_chbox .checked :
884
- max_ts = torch .max (data_packet .neural_points_data ["ts" ]) * 1.0
885
967
if local_mask is not None and self .local_map_chbox .checked :
886
- ts_np = (data_packet .neural_points_data ["ts" ][local_mask ]/ max_ts ). detach (). cpu (). numpy ( )
968
+ ts_np = (data_packet .neural_points_data ["ts" ][local_mask ])
887
969
else :
888
- ts_np = (data_packet .neural_points_data ["ts" ]/ max_ts ).detach ().cpu ().numpy ()
970
+ ts_np = (data_packet .neural_points_data ["ts" ])
971
+ ts_np = ts_np [::neural_point_vis_down_rate ].detach ().cpu ().numpy ()
972
+ ts_np = ts_np / ts_np .max ()
889
973
color_map = cm .get_cmap ("jet" )
890
- neural_point_colors = color_map (ts_np )[:, :3 ].astype (np .float64 )
891
-
974
+ neural_point_colors_np = color_map (ts_np )[:, :3 ].astype (np .float64 )
892
975
elif self .neuralpoint_height_chbox .checked :
893
- z_values = neural_point_position [:, 2 ]
976
+ z_values = neural_point_position_np [:, 2 ]
894
977
z_min , z_max = z_values .min (), z_values .max ()
895
978
z_normalized = (z_values - z_min ) / (z_max - z_min + 1e-6 )
896
979
color_map = cm .get_cmap ("jet" )
897
- neural_point_colors = color_map (z_normalized )[:, :3 ].astype (np .float64 )
898
-
899
- self .neural_points .points = o3d .utility .Vector3dVector (neural_point_position [:: neural_point_vis_down_rate , :] )
980
+ neural_point_colors_np = color_map (z_normalized )[:, :3 ].astype (np .float64 )
981
+
982
+ self .neural_points .points = o3d .utility .Vector3dVector (neural_point_position_np )
900
983
901
- if neural_point_colors is not None :
902
- self .neural_points .colors = o3d .utility .Vector3dVector (neural_point_colors [:: neural_point_vis_down_rate , :] )
984
+ if neural_point_colors_np is not None :
985
+ self .neural_points .colors = o3d .utility .Vector3dVector (neural_point_colors_np )
903
986
else :
904
987
self .neural_points .paint_uniform_color (LIGHTBLUE )
905
988
@@ -920,9 +1003,17 @@ def visualize_scan(self, data_packet = None):
920
1003
if data_packet .current_pointcloud_rgb is not None :
921
1004
self .scan .colors = o3d .utility .Vector3dVector (data_packet .current_pointcloud_rgb )
922
1005
923
- if not (self .config .color_on or self .config .semantic_on or self .source_pc_chbox .checked ):
1006
+ if not (self .config .color_on or self .config .semantic_on or self .scan_regis_color_chbox .checked ):
924
1007
self .scan .paint_uniform_color (SILVER )
925
1008
1009
+ if self .scan_height_color_chbox .checked :
1010
+ z_values = data_packet .current_pointcloud_xyz [:, 2 ]
1011
+ z_min , z_max = z_values .min (), z_values .max ()
1012
+ z_normalized = (z_values - z_min ) / (z_max - z_min + 1e-6 )
1013
+ color_map = cm .get_cmap ("jet" )
1014
+ scan_colors_np = color_map (z_normalized )[:, :3 ].astype (np .float64 )
1015
+ self .scan .colors = o3d .utility .Vector3dVector (scan_colors_np )
1016
+
926
1017
if self .ego_chbox .checked :
927
1018
self .scan .transform (np .linalg .inv (self .cur_pose ))
928
1019
@@ -951,7 +1042,7 @@ def send_data(self):
951
1042
packet = ControlPacket ()
952
1043
packet .flag_pause = not self .slider_slam .is_on
953
1044
packet .flag_vis = self .slider_vis .is_on
954
- packet .flag_source = self .source_pc_chbox .checked
1045
+ packet .flag_source = self .scan_regis_color_chbox .checked
955
1046
packet .flag_mesh = self .mesh_chbox .checked
956
1047
packet .flag_sdf = self .sdf_chbox .checked
957
1048
packet .flag_global = not self .local_map_chbox .checked
0 commit comments