Skip to content
Snippets Groups Projects
Commit 8b140465 authored by mhby1g21's avatar mhby1g21
Browse files

Merge branch '4.3.1' into 'master'

4.3.1 - Redesign GUI and remove .bat dependencies and GDP 4.3.3 - Delete Temporary Files On Main Pipeline Run on new GUI.py

See merge request !7
parents 7445f3ae 65f071d0
Branches
No related tags found
1 merge request!74.3.1 - Redesign GUI and remove .bat dependencies and GDP 4.3.3 - Delete Temporary Files On Main Pipeline Run on new GUI.py
import tkinter as tk
import tkinter.filedialog
import subprocess
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QTabWidget, QMessageBox, QGroupBox, QLabel)
from PyQt6.QtCore import Qt
import sys
import time
from threading import Thread
import shutil
import os
# Get the directory of the current script
# Add debug_tool to Python path for importing utilities
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# Get the root directory (AVVR-Pipeline-Internship)
ROOT_DIR = os.path.dirname(SCRIPT_DIR)
file_path = None
createDepth = "0"
def shift_image_selection():
# This function can be used if you want to perform any action when the checkbox is clicked
pass
def copy_intermediary_outputs():
source_folder = os.path.join(ROOT_DIR, "edgenet-360", "Data", "Input")
destination_folder = os.path.join(ROOT_DIR, "edgenet-360", "Output")
files_to_copy = ["depth_e.png", "enhanced_depth_e.png", "material.png", "rgb.png"]
for file_name in files_to_copy:
source_path = os.path.join(source_folder, file_name)
destination_path = os.path.join(destination_folder, file_name)
try:
shutil.copy(source_path, destination_path)
print(f"Copied {file_name} to {destination_folder}")
except FileNotFoundError:
print(f"Warning: {file_name} not found in {source_folder}")
def select_Image(event):
global file_path
file_path = tkinter.filedialog.askopenfilename()
file_path = os.path.normpath(file_path)
select_button.configure(text="Selected", bg="red")
label.configure(text="Image is selected. Press run to create scene.")
def depthmap_creation():
print("Manually upload depth map: ", uploadDepthCheck.get())
if uploadDepthCheck.get() == 1: # if manually upload checked
check.set(0) # disable auto generation of depth map
upload_depth_path = tkinter.filedialog.askopenfilename(title="Select a depth map", filetypes=[("PNG files", "*.png")]) #dialog box to upload depth map
DEBUG_TOOL_DIR = os.path.join(SCRIPT_DIR, 'debug_tool')
sys.path.append(DEBUG_TOOL_DIR)
from debug_tool.utils.config_reader import ConfigReader
from simple_tab import SimpleTab
from advanced_tab import AdvancedTab
class VRSceneCreatorGUI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Immersive VR Scene Creator")
self.setGeometry(100, 100, 1600, 800)
if upload_depth_path:
print(f"Uploaded depth map: {upload_depth_path}")
#TODO implement Mona's monodepth upload
else:
print("No depth map selected")
check.set(1) # if no depth map selected, enable auto generation of depth map
depth_check.deselect() # uncheck the depth map check box
else:
check.set(1) # if manually upload unchecked, enable auto generation of depth map
upload_depth_path = None
print("Removed uploaded depth map")
# Initialize paths
self.SCRIPT_DIR = SCRIPT_DIR
self.ROOT_DIR = ROOT_DIR
self.DEBUG_TOOL_DIR = DEBUG_TOOL_DIR
def stanfordRoom_selection():
if checkStanford.get() == 1:
global stanford_frame
stanford_frame = tk.Frame(window)
stanford_frame.pack(fill=tk.X, padx=5, pady=5)
global labelRoomArea
labelRoomArea = tk.Label(stanford_frame, text="Please Input Room Area: ")
labelRoomArea.pack(side="left")
global stanford_text
stanford_text = tk.Entry(stanford_frame)
stanford_text.pack(side="left", fill=tk.X, expand=True)
else:
stanford_frame.pack_forget()
select_button.pack(side="top", fill=tk.X, expand=True, padx=5, pady=5)
run_button.pack(side="top", fill=tk.X, expand=True, padx=5, pady=5)
def run_Image(event):
if checkStanford.get() == 0:
label.configure(text="Pipeline is running. Creating scene...", height=15)
else:
label.configure(text="Pipeline is running for Stanford2D3D dataset. Creating scene...", height=15)
labelRoomArea.configure(text="Room Area Running : ")
stanford_text.configure(state="disabled")
select_button.pack_forget()
run_button.pack_forget()
depth_check.pack_forget()
include_top_check.pack_forget()
stanford_check.pack_forget()
shift_image_check.pack_forget()
threading()
def runProcess():
global file_path
include_top_option = "y" if include_top.get() == 1 else ""
shift_image_option = "y" if shift_image.get() == 1 else ""
try:
if checkStanford.get() == 0:
combined_bat = os.path.join(SCRIPT_DIR, "combined.bat")
print(f"Attempting to run: {combined_bat}")
print(f"With arguments: {file_path}, {str(check.get())}, {include_top_option}, {shift_image_option}")
# depth map check
if check.get() == 1:
print("Auto depth map")
else:
print("Manual depth map")
p = subprocess.Popen(
[combined_bat, file_path, str(check.get()), include_top_option, shift_image_option],
stdout=sys.stdout)
p.communicate()
else:
temp = os.path.split(file_path)
suffices = temp[-1].split("_")
camera_pos = str(suffices[1])
room_name = suffices[2] + "_" + suffices[3]
room_area = stanford_text.get()
print(room_area, room_name, camera_pos)
combined_stanford_bat = os.path.join(SCRIPT_DIR, "combined_stanford.bat")
p = subprocess.Popen(
[combined_stanford_bat, file_path, camera_pos, str(room_area), room_name],
stdout=sys.stdout)
p.communicate()
copy_intermediary_outputs()
label.configure(text="Pipeline execution complete, check output folder.")
# Read configuration
self.config_reader = ConfigReader(self.DEBUG_TOOL_DIR, self.ROOT_DIR)
# Setup UI
self.setup_ui()
except Exception as e:
print(f"An error occurred: {e}")
label.configure(text=f"An error occurred: {e}")
try:
labelRoomArea.pack_forget()
stanford_text.pack_forget()
except Exception as e:
print(e)
def threading():
thread1 = Thread(target=runProcess)
thread1.start()
window = tk.Tk()
window.title("Immersive VR scene creator")
check = tk.IntVar()
check.set(1) #automatically generate depth map as default
uploadDepthCheck = tk.IntVar() # added uploadDepthCheck vaiable: 0 = automatically upload depth map, 1 = manually upload depth map
checkStanford = tk.IntVar()
include_top = tk.IntVar()
shift_image = tk.IntVar()
label = tk.Label(
text="Please Input a RGB image for scene creation",
foreground="black",
background="white",
width=50,
height=10,
)
select_button = tk.Button(
text="Select",
width=50,
height=5,
bg="green",
fg="white",
)
run_button = tk.Button(
text="Run",
width=50,
height=5,
bg="green",
fg="white",
)
depth_check = tk.Checkbutton(window, text='Upload a depth map(360 MonoDepth)',variable=uploadDepthCheck, onvalue=1, offvalue=0, command=depthmap_creation)
stanford_check = tk.Checkbutton(window, text='Run for stanford2D3D dataset',variable=checkStanford, onvalue=1, offvalue=0,command=stanfordRoom_selection )
include_top_check = tk.Checkbutton(window, text='Include Top in Mesh', variable=include_top, onvalue=1, offvalue=0)
shift_image_check = tk.Checkbutton(window, text='Shift input image', variable=shift_image, onvalue=1, offvalue=0, command=shift_image_selection)
label.pack()
depth_check.pack()
stanford_check.pack()
include_top_check.pack()
shift_image_check.pack()
select_button.pack()
run_button.pack()
def setup_ui(self):
# Create main widget and layout
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout(main_widget)
# Add title/header
header_label = QLabel("Immersive VR Scene Creator")
header_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
header_label.setStyleSheet("font-size: 24px; font-weight: bold; margin: 10px;")
layout.addWidget(header_label)
# Create tab widget
self.tabs = QTabWidget()
layout.addWidget(self.tabs)
# Initialize tabs
self.simple_tab = SimpleTab(self.config_reader)
self.advanced_tab = AdvancedTab(self.config_reader)
self.tabs.addTab(self.simple_tab, "Simple Pipeline")
self.tabs.addTab(self.advanced_tab, "Advanced Options")
select_button.bind('<Button-1>', select_Image)
run_button.bind('<Button-1>', run_Image)
def main():
app = QApplication(sys.argv)
window = VRSceneCreatorGUI()
window.show()
sys.exit(app.exec())
window.mainloop()
\ No newline at end of file
if __name__ == "__main__":
main()
\ No newline at end of file
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QGroupBox, QScrollArea)
from PyQt6.QtCore import Qt
import os
import sys
# Import utilities from debug_tool
from debug_tool.utils.qt_widgets import (create_group_with_text, create_button_layout,
create_info_group, create_preview_group)
from debug_tool.utils.file_handlers import select_file, clean_directory, copy_file, run_command
from debug_tool.utils.image_handlers import update_preview
class AdvancedTab(QWidget):
def __init__(self, config_reader):
super().__init__()
self.config_reader = config_reader
# Initialize paths
self.mono_depth_dir = self.config_reader.directories['monoDepthDir']
self.edge_net_dir = self.config_reader.directories['edgeNetDir']
self.material_dir = self.config_reader.directories['materialRecogDir']
self.setup_ui()
def setup_ui(self):
# Create main layout
main_layout = QVBoxLayout(self)
# Create scroll area for module controls
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# Container for module controls
container = QWidget()
container_layout = QVBoxLayout(container)
# Add module control groups
self.add_module_controls(container_layout)
scroll.setWidget(container)
main_layout.addWidget(scroll)
def add_module_controls(self, layout):
# Status section for overall progress
status_group, self.status_text = create_group_with_text("Pipeline Status", 100)
layout.addWidget(status_group)
# Image Shifter Controls
shifter_group = QGroupBox("Image Shifter")
shifter_layout = QVBoxLayout(shifter_group)
# Add shifter specific controls
layout.addWidget(shifter_group)
# Depth Estimation Controls
depth_group = QGroupBox("Depth Estimation")
depth_layout = QVBoxLayout(depth_group)
# Add depth estimation specific controls
layout.addWidget(depth_group)
# Material Recognition Controls
material_group = QGroupBox("Material Recognition")
material_layout = QVBoxLayout(material_group)
# Add material recognition specific controls
layout.addWidget(material_group)
# EdgeNet Controls
edgenet_group = QGroupBox("EdgeNet")
edgenet_layout = QVBoxLayout(edgenet_group)
# Add EdgeNet specific controls
layout.addWidget(edgenet_group)
# Mesh Processing Controls
mesh_group = QGroupBox("Mesh Processing")
mesh_layout = QVBoxLayout(mesh_group)
# Add mesh processing specific controls
layout.addWidget(mesh_group)
# Preview section
preview_group = QGroupBox("Preview")
preview_layout = QHBoxLayout(preview_group)
input_group, self.input_preview = create_preview_group("Input")
output_group, self.output_preview = create_preview_group("Output")
preview_layout.addWidget(input_group)
preview_layout.addWidget(output_group)
layout.addWidget(preview_group)
# Add some spacing at the bottom
layout.addStretch()
def update_status(self, message):
self.status_text.append(message)
# Scroll to bottom
scrollbar = self.status_text.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())
\ No newline at end of file
......@@ -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")
......
# 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
......@@ -13,17 +13,28 @@ class ConfigReader:
def read_config(self):
config = {}
# Use config.ini from scripts directory
# First try normal path
config_path = os.path.join(self.PIPELINE_DIR, "config.ini")
try:
with open(config_path, 'r') as f:
for line in f:
if '=' in line:
key, value = line.strip().split('=', 1)
config[key.strip()] = value.strip()
return config
except FileNotFoundError:
raise Exception(f"config.ini not found in {self.PIPELINE_DIR}")
return config
# If not found, try scripts directory
scripts_config = os.path.join(self.ROOT_DIR, "scripts", "config.ini")
try:
with open(scripts_config, 'r') as f:
for line in f:
if '=' in line:
key, value = line.strip().split('=', 1)
config[key.strip()] = value.strip()
return config
except FileNotFoundError:
raise Exception(f"config.ini not found in {self.PIPELINE_DIR} or {os.path.dirname(scripts_config)}")
def setup_directories(self):
return {
......
import tkinter as tk
import tkinter.filedialog
import subprocess
import sys
import time
from threading import Thread
import shutil
import os
# Get the directory of the current script
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# Get the root directory (AVVR-Pipeline-Internship)
ROOT_DIR = os.path.dirname(SCRIPT_DIR)
file_path = None
createDepth = "0"
def shift_image_selection():
# This function can be used if you want to perform any action when the checkbox is clicked
pass
def copy_intermediary_outputs():
source_folder = os.path.join(ROOT_DIR, "edgenet-360", "Data", "Input")
destination_folder = os.path.join(ROOT_DIR, "edgenet-360", "Output")
files_to_copy = ["depth_e.png", "enhanced_depth_e.png", "material.png", "rgb.png"]
for file_name in files_to_copy:
source_path = os.path.join(source_folder, file_name)
destination_path = os.path.join(destination_folder, file_name)
try:
shutil.copy(source_path, destination_path)
print(f"Copied {file_name} to {destination_folder}")
except FileNotFoundError:
print(f"Warning: {file_name} not found in {source_folder}")
def select_Image(event):
global file_path
file_path = tkinter.filedialog.askopenfilename()
file_path = os.path.normpath(file_path)
select_button.configure(text="Selected", bg="red")
label.configure(text="Image is selected. Press run to create scene.")
def depthmap_creation():
print("Manually upload depth map: ", uploadDepthCheck.get())
if uploadDepthCheck.get() == 1: # if manually upload checked
check.set(0) # disable auto generation of depth map
upload_depth_path = tkinter.filedialog.askopenfilename(title="Select a depth map", filetypes=[("PNG files", "*.png")]) #dialog box to upload depth map
if upload_depth_path:
print(f"Uploaded depth map: {upload_depth_path}")
#TODO implement Mona's monodepth upload
else:
print("No depth map selected")
check.set(1) # if no depth map selected, enable auto generation of depth map
depth_check.deselect() # uncheck the depth map check box
else:
check.set(1) # if manually upload unchecked, enable auto generation of depth map
upload_depth_path = None
print("Removed uploaded depth map")
def stanfordRoom_selection():
if checkStanford.get() == 1:
global stanford_frame
stanford_frame = tk.Frame(window)
stanford_frame.pack(fill=tk.X, padx=5, pady=5)
global labelRoomArea
labelRoomArea = tk.Label(stanford_frame, text="Please Input Room Area: ")
labelRoomArea.pack(side="left")
global stanford_text
stanford_text = tk.Entry(stanford_frame)
stanford_text.pack(side="left", fill=tk.X, expand=True)
else:
stanford_frame.pack_forget()
select_button.pack(side="top", fill=tk.X, expand=True, padx=5, pady=5)
run_button.pack(side="top", fill=tk.X, expand=True, padx=5, pady=5)
def run_Image(event):
if checkStanford.get() == 0:
label.configure(text="Pipeline is running. Creating scene...", height=15)
else:
label.configure(text="Pipeline is running for Stanford2D3D dataset. Creating scene...", height=15)
labelRoomArea.configure(text="Room Area Running : ")
stanford_text.configure(state="disabled")
select_button.pack_forget()
run_button.pack_forget()
depth_check.pack_forget()
include_top_check.pack_forget()
stanford_check.pack_forget()
shift_image_check.pack_forget()
threading()
def runProcess():
global file_path
include_top_option = "y" if include_top.get() == 1 else ""
shift_image_option = "y" if shift_image.get() == 1 else ""
try:
if checkStanford.get() == 0:
combined_bat = os.path.join(SCRIPT_DIR, "combined.bat")
print(f"Attempting to run: {combined_bat}")
print(f"With arguments: {file_path}, {str(check.get())}, {include_top_option}, {shift_image_option}")
# depth map check
if check.get() == 1:
print("Auto depth map")
else:
print("Manual depth map")
p = subprocess.Popen(
[combined_bat, file_path, str(check.get()), include_top_option, shift_image_option],
stdout=sys.stdout)
p.communicate()
else:
temp = os.path.split(file_path)
suffices = temp[-1].split("_")
camera_pos = str(suffices[1])
room_name = suffices[2] + "_" + suffices[3]
room_area = stanford_text.get()
print(room_area, room_name, camera_pos)
combined_stanford_bat = os.path.join(SCRIPT_DIR, "combined_stanford.bat")
p = subprocess.Popen(
[combined_stanford_bat, file_path, camera_pos, str(room_area), room_name],
stdout=sys.stdout)
p.communicate()
copy_intermediary_outputs()
label.configure(text="Pipeline execution complete, check output folder.")
except Exception as e:
print(f"An error occurred: {e}")
label.configure(text=f"An error occurred: {e}")
try:
labelRoomArea.pack_forget()
stanford_text.pack_forget()
except Exception as e:
print(e)
def threading():
thread1 = Thread(target=runProcess)
thread1.start()
window = tk.Tk()
window.title("Immersive VR scene creator")
check = tk.IntVar()
check.set(1) #automatically generate depth map as default
uploadDepthCheck = tk.IntVar() # added uploadDepthCheck vaiable: 0 = automatically upload depth map, 1 = manually upload depth map
checkStanford = tk.IntVar()
include_top = tk.IntVar()
shift_image = tk.IntVar()
label = tk.Label(
text="Please Input a RGB image for scene creation",
foreground="black",
background="white",
width=50,
height=10,
)
select_button = tk.Button(
text="Select",
width=50,
height=5,
bg="green",
fg="white",
)
run_button = tk.Button(
text="Run",
width=50,
height=5,
bg="green",
fg="white",
)
depth_check = tk.Checkbutton(window, text='Upload a depth map(360 MonoDepth)',variable=uploadDepthCheck, onvalue=1, offvalue=0, command=depthmap_creation)
stanford_check = tk.Checkbutton(window, text='Run for stanford2D3D dataset',variable=checkStanford, onvalue=1, offvalue=0,command=stanfordRoom_selection )
include_top_check = tk.Checkbutton(window, text='Include Top in Mesh', variable=include_top, onvalue=1, offvalue=0)
shift_image_check = tk.Checkbutton(window, text='Shift input image', variable=shift_image, onvalue=1, offvalue=0, command=shift_image_selection)
label.pack()
depth_check.pack()
stanford_check.pack()
include_top_check.pack()
shift_image_check.pack()
select_button.pack()
run_button.pack()
select_button.bind('<Button-1>', select_Image)
run_button.bind('<Button-1>', run_Image)
window.mainloop()
\ No newline at end of file
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QGroupBox, QCheckBox, QMessageBox, QPushButton,
QProgressBar)
from PyQt6.QtCore import Qt, QThread, pyqtSignal
import os
import sys
# Import utilities from debug_tool
from debug_tool.utils.qt_widgets import (create_group_with_text, create_button_layout,
create_info_group, create_preview_group)
from debug_tool.utils.file_handlers import select_file, clean_directory, copy_file, run_command
from debug_tool.utils.image_handlers import update_preview
# Import existing module implementations
from debug_tool.tabs.shifter_tab import ShifterTab
from debug_tool.tabs.depth_tab import DepthTab
from debug_tool.tabs.material_tab import MaterialTab
from debug_tool.tabs.edge_net_tab import EdgeNetTab
class PipelineWorker(QThread):
progress = pyqtSignal(str)
finished = pyqtSignal(bool, str)
def __init__(self, tab_instance):
super().__init__()
self.tab = tab_instance
def run(self):
try:
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.run_depth_estimation()
print("Completed depth_estimation") # Debug print
def run_material_recognition(self):
print("Starting material_recognition")
self.progress.emit("Running material recognition...")
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")
self.progress.emit("Running EdgeNet enhance360.py and infer360.py...")
try:
self.tab.edge_net.include_top = self.tab.include_top_check.isChecked()
self.tab.edge_net._run_edge_net_process()
print("Completed edge_net")
except Exception as e:
print(f"EdgeNet failed: {str(e)}")
raise
def run_post_processing(self):
self.progress.emit("Running post-processing...")
self.tab.edge_net._run_mesh_split_process()
self.progress.emit("Completed mesh split (replace.py)")
self.tab.edge_net._run_blender_flip_process()
self.progress.emit("Completed blender flip (blenderFlip.py)")
self.progress.emit("Post-processing completed!")
def run_pipeline(self):
self.clean_temp_files()
self.copy_file()
self.shift_image()
self.run_depth_estimation()
self.run_material_recognition()
self.run_edge_net()
self.run_post_processing()
self.progress.emit("Pipeline completed!")
class SimpleTab(QWidget):
def __init__(self, config_reader):
super().__init__()
self.config_reader = config_reader
self.input_path = None
self.pipeline_thread = None
# Initialize module instances
self.shifter = ShifterTab(self.config_reader)
self.depth = DepthTab(self.config_reader)
self.material = MaterialTab(self.config_reader)
self.edge_net = EdgeNetTab(self.config_reader)
# Hide their UIs as we'll use our own
self.shifter.hide()
self.depth.hide()
self.material.hide()
self.edge_net.hide()
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Controls section
controls_group = QGroupBox("Pipeline Controls")
controls_layout = QVBoxLayout(controls_group)
# Info display
info_rows = [
("Input Image:", "No file selected"),
("Status:", "Ready")
]
self.info_group, self.info_labels = create_info_group("Information", info_rows)
controls_layout.addWidget(self.info_group)
# Options
options_layout = QHBoxLayout()
self.include_top_check = QCheckBox("Include Top in Mesh")
options_layout.addWidget(self.include_top_check)
self.shift_image_check = QCheckBox("Shift Input Image")
options_layout.addWidget(self.shift_image_check)
controls_layout.addLayout(options_layout)
# Progress Bar
self.progress_bar = QProgressBar()
self.progress_bar.setMinimum(0)
self.progress_bar.setMaximum(0) # Makes it an indefinite progress bar
self.progress_bar.hide() # Hidden by default
controls_layout.addWidget(self.progress_bar)
# Buttons
self.run_pipeline_btn = QPushButton("Run Pipeline")
self.run_pipeline_btn.clicked.connect(self.run_full_pipeline)
self.run_pipeline_btn.setEnabled(False) # Disabled by default
buttons_layout = QHBoxLayout()
select_btn = QPushButton("Select Input Image")
select_btn.clicked.connect(self.handle_file_select)
buttons_layout.addWidget(select_btn)
buttons_layout.addWidget(self.run_pipeline_btn)
controls_layout.addLayout(buttons_layout)
layout.addWidget(controls_group)
# Status section
status_group, self.status_text = create_group_with_text("Pipeline Status", 150)
layout.addWidget(status_group)
# Preview section
preview_group = QGroupBox("Preview")
preview_layout = QHBoxLayout(preview_group)
input_group, self.input_preview = create_preview_group("Input Image")
output_group, self.output_preview = create_preview_group("Current Output")
preview_layout.addWidget(input_group)
preview_layout.addWidget(output_group)
layout.addWidget(preview_group)
def handle_file_select(self):
file_path = select_file(
self,
"Select Input Image",
"Images (*.png *.jpg *.jpeg)",
initial_dir=self.config_reader.directories['edgeNetDir'] + '/Data'
)
if file_path:
self.input_path = file_path
self.info_labels["Input Image:"].setText(os.path.basename(file_path))
self.update_status(f"Selected input file: {file_path}")
update_preview(self.input_preview, file_path,
error_callback=self.update_status)
# Enable the run pipeline button
self.run_pipeline_btn.setEnabled(True)
# Provide input path to all modules
self.shifter.input_file_path = file_path
self.depth.depth_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:
QMessageBox.warning(self, "Warning", "Please select an input file first")
return
if self.pipeline_thread and self.pipeline_thread.isRunning():
QMessageBox.warning(self, "Warning", "Pipeline is already running")
return
# Show progress bar and update status
self.progress_bar.show()
self.run_pipeline_btn.setEnabled(False)
self.pipeline_thread = PipelineWorker(self)
# Connect signals
self.pipeline_thread.progress.connect(self.update_status)
self.pipeline_thread.finished.connect(self.pipeline_completed)
# Disable controls while running
self.setEnabled(False)
self.progress_bar.setEnabled(True) # Keep progress bar enabled
# Start the pipeline
self.pipeline_thread.start()
def pipeline_completed(self, success, message):
self.setEnabled(True)
self.progress_bar.hide()
self.run_pipeline_btn.setEnabled(True)
self.update_status(message)
if success:
QMessageBox.information(self, "Success", "Pipeline completed successfully!")
else:
QMessageBox.critical(self, "Error", f"Pipeline failed: {message}")
def update_status(self, message):
self.status_text.append(message)
self.info_labels["Status:"].setText(message.split("...")[-1] if "..." in message else message)
# Scroll to bottom
scrollbar = self.status_text.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment