diff --git a/scripts/debug_tool/tabs/edge_net_tab.py b/scripts/debug_tool/tabs/edge_net_tab.py index dc888bed9a226847193e7eecfc4546fc2c1e37dc..1df96d36301af3681d1e7bffa4a868dc89eb3e4e 100644 --- a/scripts/debug_tool/tabs/edge_net_tab.py +++ b/scripts/debug_tool/tabs/edge_net_tab.py @@ -236,8 +236,8 @@ class EdgeNetTab(QWidget): self.current_thread.progress.connect(self.update_status) self.current_thread.start() - def clean_output_directory(self): - if show_confirmation_dialog(self, "Confirm Clean", "Clean output directory?"): + def clean_output_directory(self, silent=False): + if silent or show_confirmation_dialog(self, "Confirm Clean", "Clean output directory?"): if clean_directory(self.output_dir, self.update_status): self.update_status("Output directory cleaned") update_status_indicator(self.split_status, "Not started") diff --git a/scripts/debug_tool/tabs/material_tab.py b/scripts/debug_tool/tabs/material_tab.py index b38111daed8eeae8998acc77a474f9f2c6a22683..d7213229c5109f2b7c0342ffe5f4803b630fb12d 100644 --- a/scripts/debug_tool/tabs/material_tab.py +++ b/scripts/debug_tool/tabs/material_tab.py @@ -1,7 +1,7 @@ # tabs/material_tab.py from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QMessageBox, QTabWidget) -from PyQt6.QtCore import Qt +from PyQt6.QtCore import Qt, QThread, pyqtSignal import os from utils.qt_widgets import (create_group_with_text, create_button_layout, @@ -13,6 +13,11 @@ from utils.image_handlers import (update_preview, update_face_previews, clear_previews) class MaterialTab(QWidget): + # Add signals for UI updates + status_update = pyqtSignal(str) + progress_update = pyqtSignal(str, str) # (status_name, new_status) + preview_update = pyqtSignal(str, str) # (preview_type, file_path) + def __init__(self, config_reader): super().__init__() self.config_reader = config_reader @@ -26,6 +31,11 @@ class MaterialTab(QWidget): self.setup_ui() self.verify_checkpoint() + + # Connect signals to UI update methods + self.status_update.connect(self._update_status) + self.progress_update.connect(self._update_progress) + self.preview_update.connect(self._update_preview) def setup_ui(self): main_layout = QHBoxLayout(self) @@ -134,12 +144,13 @@ class MaterialTab(QWidget): error_callback=self.update_status) self.reset_status_indicators() - def clean_working_dir(self): + def clean_working_dir(self, silent=False): dirs_to_clean = [self.cubemap_dir, self.material_output_dir] for directory in dirs_to_clean: if not clean_directory(directory, self.update_status): - QMessageBox.critical(self, "Error", f"Failed to clean directory: {directory}") + if not silent: + QMessageBox.critical(self, "Error", f"Failed to clean directory: {directory}") return clear_previews( @@ -152,34 +163,36 @@ class MaterialTab(QWidget): def run_split_360(self): if not self.input_file_path: - QMessageBox.warning(self, "Warning", "Please select an input file first") - return + self.status_update.emit("No input file selected") + return False - self.update_status("Running 360 image splitting...") - update_status_indicator(self.split_status, "Running") + self.status_update.emit("Running 360 image splitting...") + self.progress_update.emit("split", "Running") original_dir = os.getcwd() os.chdir(self.material_recog_dir) cmd = f'''call "{self.config_reader.config["condaDir"]}\\condabin\\activate.bat" {self.config_reader.config["materialEnv"]} && python split_img.py "{self.input_file_path}" && call "{self.config_reader.config["condaDir"]}\\condabin\\deactivate.bat"''' - success, _ = run_command(self, cmd, self.update_status) + success, _ = run_command(None, cmd, lambda msg: self.status_update.emit(msg)) os.chdir(original_dir) if success: - update_status_indicator(self.split_status, "Complete") - self.update_face_previews('rgb') + self.progress_update.emit("split", "Complete") + self.preview_update.emit("rgb", "") # Empty string triggers face preview update + return True else: - update_status_indicator(self.split_status, "Failed") + self.progress_update.emit("split", "Failed") + return False def run_material_recognition(self): if not os.path.exists(self.cubemap_dir): - QMessageBox.warning(self, "Warning", "Please run Split 360 first") - return + self.status_update.emit("Please run Split 360 first") + return False - self.update_status("Running material recognition...") - update_status_indicator(self.recognition_status, "Running") + self.status_update.emit("Running material recognition...") + self.progress_update.emit("recognition", "Running") original_dir = os.getcwd() os.chdir(self.material_recog_dir) @@ -193,50 +206,59 @@ class MaterialTab(QWidget): f'--infer "{self.material_recog_dir}/cubemap_faces/"' ) - success, _ = run_command(self, cmd, self.update_status) + success, _ = run_command(None, cmd, lambda msg: self.status_update.emit(msg)) os.chdir(original_dir) if success: - update_status_indicator(self.recognition_status, "Complete") - self.update_face_previews('material') + self.progress_update.emit("recognition", "Complete") + self.preview_update.emit("material", "") + return True else: - update_status_indicator(self.recognition_status, "Failed") + self.progress_update.emit("recognition", "Failed") + return False def run_combine(self): - self.update_status("Running combine step...") - update_status_indicator(self.combine_status, "Running") + self.status_update.emit("Running combine step...") + self.progress_update.emit("combine", "Running") original_dir = os.getcwd() os.chdir(self.material_recog_dir) cmd = f'''call "{self.config_reader.config["condaDir"]}\\condabin\\activate.bat" {self.config_reader.config["materialEnv"]} && python combine_img.py && call "{self.config_reader.config["condaDir"]}\\condabin\\deactivate.bat"''' - success, _ = run_command(self, cmd, self.update_status) + success, _ = run_command(None, cmd, lambda msg: self.status_update.emit(msg)) os.chdir(original_dir) if success: - update_status_indicator(self.combine_status, "Complete") + self.progress_update.emit("combine", "Complete") output_path = os.path.join( self.config_reader.directories['edgeNetDir'], 'Data', 'Input', 'material.png' ) - update_preview(self.output_preview, output_path, - error_callback=self.update_status) + self.preview_update.emit("output", output_path) + return True else: - update_status_indicator(self.combine_status, "Failed") + self.progress_update.emit("combine", "Failed") + return False def run_all_steps(self): + """Main processing method that can be called from any thread""" if not self.input_file_path: - QMessageBox.warning(self, "Warning", "Please select an input file first") - return + self.status_update.emit("Please select an input file first") + return False + + if not self.run_split_360(): + return False + + if not self.run_material_recognition(): + return False + + if not self.run_combine(): + return False - self.run_split_360() - if get_status_text(self.split_status) == "Complete": - self.run_material_recognition() - if get_status_text(self.recognition_status) == "Complete": - self.run_combine() + return True def update_status(self, message): self.status_text.append(message) @@ -268,4 +290,27 @@ class MaterialTab(QWidget): self.info_labels["Checkpoint:"].setText("✓ Found" if exists else "✗ Missing") self.info_labels["Checkpoint:"].setStyleSheet( "color: green" if exists else "color: red") - return exists \ No newline at end of file + return exists + + # Private UI update methods - only called via signals in main thread + def _update_status(self, message): + self.status_text.append(message) + scrollbar = self.status_text.verticalScrollBar() + scrollbar.setValue(scrollbar.maximum()) + + def _update_progress(self, status_name, new_status): + if status_name == "split": + update_status_indicator(self.split_status, new_status) + elif status_name == "recognition": + update_status_indicator(self.recognition_status, new_status) + elif status_name == "combine": + update_status_indicator(self.combine_status, new_status) + + def _update_preview(self, preview_type, file_path): + if preview_type == "rgb": + self.update_face_previews("rgb") + elif preview_type == "material": + self.update_face_previews("material") + elif preview_type == "output": + update_preview(self.output_preview, file_path, + error_callback=lambda msg: self.status_update.emit(msg)) \ No newline at end of file diff --git a/scripts/simple_tab.py b/scripts/simple_tab.py index 88c392456bf51a3fc8045c1c9da515bff6a67d29..77d2420b368ea072cb5d93d19e5cd52a5fea19b4 100644 --- a/scripts/simple_tab.py +++ b/scripts/simple_tab.py @@ -30,33 +30,87 @@ class PipelineWorker(QThread): self.run_pipeline() self.finished.emit(True, "Pipeline completed successfully!") except Exception as e: + print(f"Pipeline failed with error: {str(e)}") # Debug print self.finished.emit(False, f"Pipeline failed: {str(e)}") + def clean_temp_files(self): + self.tab.depth.clean_input_dir() # This one doesn't have dialogs + self.progress.emit("Cleaning input directory...") + self.tab.depth.remove_rgb() + self.progress.emit("Removing RGB image from 360monodepthexecution...") + self.tab.material.clean_working_dir(silent=True) + self.progress.emit("Cleaning Dynamic-Backward-Attention-Transformer temp directory...") + self.tab.edge_net.clean_output_directory(silent=True) + self.progress.emit("Cleaning EdgeNet output directory...") + + def copy_file(self): + self.progress.emit("Copying input file to scripts/360monodepthexecution...") + self.tab.depth.copy_file() + def shift_image(self): + print("Starting shift_image") # Debug print if not self.tab.shift_image_check.isChecked(): self.progress.emit("Skipping image shift...") return self.progress.emit("Shifting input image...") self.tab.shifter.run_shifter() + print("Completed shift_image") # Debug print def run_depth_estimation(self): + print("Starting depth_estimation") # Debug print self.progress.emit("Running depth estimation...") - self.tab.depth.clean_input_dir() - self.tab.depth.remove_rgb() - self.tab.depth.copy_file() self.tab.depth.run_depth_estimation() + print("Completed depth_estimation") # Debug print def run_material_recognition(self): + print("Starting material_recognition") self.progress.emit("Running material recognition...") - self.tab.material.run_all_steps() + + try: + print(f"Input file path: {self.tab.material.input_file_path}") + + print("Running split 360...") + success = self.tab.material.run_split_360() + if not success: + raise Exception("Split 360 failed") + + print("Running material recognition...") + success = self.tab.material.run_material_recognition() + if not success: + raise Exception("Material recognition step failed") + + print("Starting combine step...") + print(f"Current working directory: {os.getcwd()}") + print(f"Material recognition directory: {self.tab.material.material_recog_dir}") + print(f"Checking if cubemap directory exists: {os.path.exists(self.tab.material.cubemap_dir)}") + print(f"Checking if material output directory exists: {os.path.exists(self.tab.material.material_output_dir)}") + print("Files in cubemap directory:") + if os.path.exists(self.tab.material.cubemap_dir): + print("\n".join(os.listdir(self.tab.material.cubemap_dir))) + print("Files in material output directory:") + if os.path.exists(self.tab.material.material_output_dir): + print("\n".join(os.listdir(self.tab.material.material_output_dir))) + + success = self.tab.material.run_combine() + if not success: + raise Exception("Combine step failed") + + except Exception as e: + print(f"Material recognition error: {str(e)}") + raise + + print("Completed material_recognition") def run_edge_net(self): + print("Starting edge_net") # Debug print self.progress.emit("Running EdgeNet...") self.tab.edge_net.include_top = self.tab.include_top_check.isChecked() - self.tab.edge_net.clean_output_directory() self.tab.edge_net.run_all_steps() + print("Completed edge_net") # Debug print def run_pipeline(self): + self.clean_temp_files() + self.copy_file() self.shift_image() self.run_depth_estimation() self.run_material_recognition() @@ -164,10 +218,10 @@ class SimpleTab(QWidget): self.run_pipeline_btn.setEnabled(True) # Provide input path to all modules - self.shifter.depth_input_path = file_path + self.shifter.input_file_path = file_path self.depth.depth_input_path = file_path - self.material.input_path = file_path - self.edge_net.input_path = file_path + self.material.input_file_path = file_path + # self.edge_net.input_path = file_path # edgenet have default input path def run_full_pipeline(self): if not self.input_path: