diff --git a/config.ini b/config.ini index fef1f24..a063f5e 100644 --- a/config.ini +++ b/config.ini @@ -51,6 +51,9 @@ show_orientation = True background_color = 100, 100, 100 ; number of decimal places shown for the parameters of the active bounding box viewing_precision = 2 -; near and far clipping plane for OpenGL (where objects are visible, in meter) -near_plane=0.1 -far_plane=300 +; near and far clipping plane for opengl (where objects are visible, in meter) +near_plane = 0.1 +far_plane = 300 +; keep last perspective between point clouds +keep_perspective = False + diff --git a/labelCloud/control/pcd_manager.py b/labelCloud/control/pcd_manager.py index 9c3d652..c7a43e5 100644 --- a/labelCloud/control/pcd_manager.py +++ b/labelCloud/control/pcd_manager.py @@ -15,10 +15,18 @@ from .config_manager import config from .label_manager import LabelManager +from dataclasses import dataclass + if TYPE_CHECKING: from view.gui import GUI +@dataclass +class Perspective: + zoom: float + rotation: Tuple[float, float, float] + + def color_pointcloud(points, z_min, z_max): palette = np.loadtxt("labelCloud/ressources/rocket-palette.txt") palette_len = len(palette) - 1 @@ -49,6 +57,7 @@ def __init__(self): # Point cloud control self.pointcloud = None self.collected_object_classes = set() + self.saved_perspective: Perspective = None def read_pointcloud_folder(self): """Checks point cloud folder and sets self.pcds to all valid point cloud file names.""" @@ -137,10 +146,24 @@ def save_labels_into_file(self, bboxes: List[BBox]): else: print("No point clouds to save labels for!") + def save_current_perspective(self, active: bool = True) -> None: + if active: + self.saved_perspective = Perspective( + zoom=self.pointcloud.trans_z, + rotation=tuple(self.pointcloud.get_rotations()), + ) + print(f"Saved current perspective ({self.saved_perspective}).") + else: + self.saved_perspective = None + print("Reset saved perspective.") + # MANIPULATOR def load_pointcloud(self, path_to_pointcloud: str) -> PointCloud: print("=" * 20, "Loading", ntpath.basename(path_to_pointcloud), "=" * 20) + if config.getboolean("USER_INTERFACE", "keep_perspective"): + self.save_current_perspective() + if ( os.path.splitext(path_to_pointcloud)[1] == ".bin" ): # Loading binary pcds with numpy @@ -180,6 +203,12 @@ def load_pointcloud(self, path_to_pointcloud: str) -> PointCloud: tmp_pcd.init_translation = -self.current_o3d_pcd.get_center() - [0, 0, diagonal] + if self.saved_perspective != None: + tmp_pcd.init_translation = tuple( + list(tmp_pcd.init_translation[:2]) + [self.saved_perspective.zoom] + ) + tmp_pcd.set_rotations(*self.saved_perspective.rotation) + tmp_pcd.reset_translation() tmp_pcd.print_details() if self.pointcloud is not None: # Skip first pcd to intialize OpenGL first diff --git a/labelCloud/model/point_cloud.py b/labelCloud/model/point_cloud.py index 54b68f0..7c60bb3 100644 --- a/labelCloud/model/point_cloud.py +++ b/labelCloud/model/point_cloud.py @@ -73,6 +73,11 @@ def set_rot_y(self, angle): def set_rot_z(self, angle): self.rot_z = angle % 360 + def set_rotations(self, x: float, y: float, z: float): + self.rot_x = x % 360 + self.rot_y = y % 360 + self.rot_z = z % 360 + def set_trans_x(self, val): self.trans_x = val @@ -82,6 +87,11 @@ def set_trans_y(self, val): def set_trans_z(self, val): self.trans_z = val + def set_translations(self, x: float, y: float, z: float): + self.trans_x = x + self.trans_y = y + self.trans_z = z + # MANIPULATORS def transform_data(self): diff --git a/labelCloud/ressources/default_config.ini b/labelCloud/ressources/default_config.ini index e81fdb5..d6b6e8a 100644 --- a/labelCloud/ressources/default_config.ini +++ b/labelCloud/ressources/default_config.ini @@ -53,4 +53,6 @@ background_color = 100, 100, 100 viewing_precision = 2 ; near and far clipping plane for OpenGL (where objects are visible, in meter) near_plane=0.1 -far_plane=300 \ No newline at end of file +far_plane=300 +; keep last perspective between point clouds +keep_perspective = False \ No newline at end of file diff --git a/labelCloud/ressources/interface.ui b/labelCloud/ressources/interface.ui index 01f5533..cb5203a 100644 --- a/labelCloud/ressources/interface.ui +++ b/labelCloud/ressources/interface.ui @@ -1538,6 +1538,7 @@ QListWidget#label_list::item:selected { + @@ -1614,6 +1615,17 @@ QListWidget#label_list::item:selected { Show Orientation + + + true + + + false + + + Save current Perspective + + true diff --git a/labelCloud/ressources/settings_interface.ui b/labelCloud/ressources/settings_interface.ui index a43e3a4..df15ad9 100644 --- a/labelCloud/ressources/settings_interface.ui +++ b/labelCloud/ressources/settings_interface.ui @@ -22,77 +22,64 @@ 0 - - + + - Rasterized diameter of each point from the point cloud. + Visualizes the object's orientation with an arrow. - Point Size + Show Bounding Box Orientation - - + + number of decimal places shown for the parameters of the active bounding box. + + Viewing Precision of +Bounding Box Parameter + - - + + Standard step for zooming. - - 4 - - - 0.010000000000000 + + Standard Zoom Factor - - + + - Point color for colorless point clouds (r,g,b). + Path to the folder where the label files will be saved. - - - - - 0 - 0 - + + + + Standard step for zooming. - - - 75 - true - + + 4 - - File Settings + + 0.010000000000000 - - + + - Point color for colorless point clouds (r,g,b). + Path to the folder where the label files will be saved. - Point Color -(for colorless point clouds) - - - - - - - Background color of the point cloud viewer (rgb). + Label Folder @@ -106,29 +93,23 @@ - - + + - Colerize colorless point clouds by height value. - - - Colorize colorless point clouds by height + Point color for colorless point clouds (r,g,b). - - - - - 75 - true - + + + + Rasterized diameter of each point from the point cloud. - - margin-top: 10px + + 2 - - User Interface + + 500.000000000000000 @@ -154,13 +135,43 @@ - - + + - Path to the folder where the label files will be saved. + Path to the folder that contains the point cloud files. + + + + + + + Background color of the point cloud viewer (rgb). + + + + + + + number of decimal places shown for the parameters of the active bounding box. + + + + + + + + 0 + 0 + + + + + 75 + true + - Label Folder + File Settings @@ -177,47 +188,39 @@ - - + + - number of decimal places shown for the parameters of the active bounding box. + Colerize colorless point clouds by height value. - Viewing Precision of -Bounding Box Parameter + Colorize colorless point clouds by height - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + - Standard step for point cloud translation. + Background color of the point cloud viewer (rgb). - Standard Translation + Background Color - - - - Standard step for zooming. + + + + + 75 + true + + + + margin-top: 10px - Standard Zoom Factor + User Interface @@ -231,62 +234,69 @@ Bounding Box Parameter - - + + Rasterized diameter of each point from the point cloud. - - 2 - - - 500.000000000000000 + + Point Size - - - - Visualizes the object's orientation with an arrow. + + + + Qt::Vertical - - Show Bounding Box Orientation + + + 20 + 40 + - + - - - - Path to the folder that contains the point cloud files. + + + + + true + + + + Note: Some settings might require a restart to take effect! - - + + - Background color of the point cloud viewer (rgb). + Standard step for point cloud translation. - Background Color + Standard Translation - - + + - Path to the folder where the label files will be saved. + Point color for colorless point clouds (r,g,b). + + + Point Color +(for colorless point clouds) - - - - - true - + + + + Applies the last perspective of the previous point cloud to the current point cloud when loading. - Note: Some settings might require a restart to take effect! + Keep last Perspective between Point Clouds diff --git a/labelCloud/view/gui.py b/labelCloud/view/gui.py index e7b038c..b177c7d 100644 --- a/labelCloud/view/gui.py +++ b/labelCloud/view/gui.py @@ -71,6 +71,9 @@ def __init__(self, control: "Controller"): self.action_showorientation = self.findChild( QtWidgets.QAction, "action_showorientation" ) + self.action_saveperspective = self.findChild( + QtWidgets.QAction, "action_saveperspective" + ) self.action_alignpcd = self.findChild(QtWidgets.QAction, "action_alignpcd") self.action_change_settings = self.findChild( QtWidgets.QAction, "action_changesettings" @@ -296,6 +299,9 @@ def connect_events(self): self.action_zrotation.toggled.connect(set_zrotation_only) self.action_showfloor.toggled.connect(set_floor_visibility) self.action_showorientation.toggled.connect(set_orientation_visibility) + self.action_saveperspective.toggled.connect( + lambda state: self.controller.pcd_manager.save_current_perspective(state) + ) self.action_alignpcd.toggled.connect( self.controller.align_mode.change_activation ) diff --git a/labelCloud/view/settings_dialog.py b/labelCloud/view/settings_dialog.py index c96b838..1661ac3 100644 --- a/labelCloud/view/settings_dialog.py +++ b/labelCloud/view/settings_dialog.py @@ -82,6 +82,9 @@ def fill_with_current_settings(self): self.checkBox_showbboxorientation.setChecked( config.getboolean("USER_INTERFACE", "show_orientation") ) + self.checkBox_keepperspective.setChecked( + config.getboolean("USER_INTERFACE", "keep_perspective") + ) self.spinBox_viewingprecision.setValue( config.getint("USER_INTERFACE", "viewing_precision") ) @@ -140,7 +143,10 @@ def save(self) -> None: self.checkBox_showfloor.isChecked() ) config["USER_INTERFACE"]["show_orientation"] = str( - self.checkBox_showbboxorientation.isChecked() + self.checkBox_keepperspective.isChecked() + ) + config["USER_INTERFACE"]["keep_perspective"] = str( + self.checkBox_keepperspective.isChecked() ) config["USER_INTERFACE"][ "background_color"