finished graphs
This commit is contained in:
		
							parent
							
								
									bbe7a04d2c
								
							
						
					
					
						commit
						d3136a12b6
					
				
							
								
								
									
										2
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.py
									
									
									
									
									
								
							@ -51,7 +51,7 @@ def main():
 | 
			
		||||
                                                ["X moy (en mm)",
 | 
			
		||||
                                                "Y moy (en mm)",
 | 
			
		||||
                                                "Z moy (en mm)",
 | 
			
		||||
                                                "Delta z(en mm)",
 | 
			
		||||
                                                "Discretisation(en mm)",
 | 
			
		||||
                                                "Rayon moyen (en mm)",
 | 
			
		||||
                                                "Rayon ecart type (en mm)"] ))
 | 
			
		||||
    print("Data saved in {} seconds".format(time.time()-t))
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ def get_discrete_data(obj:ScannedObject, ndigits:int, delta_z:float=1, update_pr
 | 
			
		||||
        - Rayon moyen (en mm)       : list of mean radius values
 | 
			
		||||
        - Rayon ecart type (en mm)  : list of radius standard deviation values
 | 
			
		||||
    """
 | 
			
		||||
    colones = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Delta z(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"]
 | 
			
		||||
    colones = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Discretisation(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"]
 | 
			
		||||
    data = {}
 | 
			
		||||
    for colone in colones:
 | 
			
		||||
        data[colone] = []
 | 
			
		||||
@ -67,7 +67,7 @@ def get_discrete_data(obj:ScannedObject, ndigits:int, delta_z:float=1, update_pr
 | 
			
		||||
        data["Z moy (en mm)"].append(round(z, ndigits))
 | 
			
		||||
        first = discrete_values[0]
 | 
			
		||||
        last = discrete_values[-1]
 | 
			
		||||
        data["Delta z(en mm)"].append(round(last[2]-first[2],ndigits))
 | 
			
		||||
        data["Discretisation(en mm)"].append(round(last[2]-first[2],ndigits))
 | 
			
		||||
        data["Rayon moyen (en mm)"].append(round(data_extraction.get_mean_radius(discrete_values), ndigits))
 | 
			
		||||
        data["Rayon ecart type (en mm)"].append(round(data_extraction.get_radius_std(discrete_values), ndigits))
 | 
			
		||||
        update_progress_bar(int(progress/len(discrete_vertices)*100))
 | 
			
		||||
 | 
			
		||||
@ -97,9 +97,11 @@ class ScannedObject:
 | 
			
		||||
                if line.startswith('f'):
 | 
			
		||||
                    if "//" in line:
 | 
			
		||||
                        triangles.append([int(line.split()[1].split("//")[0])-1, int(line.split()[2].split("//")[0])-1, int(line.split()[3].split("//")[0])-1])
 | 
			
		||||
                    elif "/" in line:
 | 
			
		||||
                        triangles.append([int(line.split()[1].split("/")[0])-1, int(line.split()[2].split("/")[0])-1, int(line.split()[3].split("/")[0])-1])
 | 
			
		||||
                    else:
 | 
			
		||||
                        triangles.append([int(line.split()[1])-1, int(line.split()[2])-1, int(line.split()[3])-1])
 | 
			
		||||
                elif line.startswith('v'):
 | 
			
		||||
                elif line.startswith('v '):
 | 
			
		||||
                    x.append(float(line.split()[1]) * ratio)
 | 
			
		||||
                    y.append(float(line.split()[2]) * ratio)
 | 
			
		||||
                    z.append(float(line.split()[3]) * ratio)
 | 
			
		||||
 | 
			
		||||
@ -1,28 +1,33 @@
 | 
			
		||||
import vispy.plot as vp
 | 
			
		||||
import numpy as np
 | 
			
		||||
 | 
			
		||||
def render2D(values:list):
 | 
			
		||||
def render2D(values:list,title:str,show:bool=True):
 | 
			
		||||
    """
 | 
			
		||||
    Render a 2D plot using vispy
 | 
			
		||||
    :param values: A list with the values
 | 
			
		||||
    """
 | 
			
		||||
    fig = vp.Fig(size=(600, 500), show=False)
 | 
			
		||||
    plotwidget = fig[0, 0]
 | 
			
		||||
    fig.title = "bollu"
 | 
			
		||||
    plotwidget.plot(values)
 | 
			
		||||
    plotwidget.colorbar(position="top", cmap="autumn")
 | 
			
		||||
    fig.show(run=True)
 | 
			
		||||
    fig.title = title
 | 
			
		||||
    plotwidget.plot(values,marker_size=0, width=2,title=title)
 | 
			
		||||
    if show:
 | 
			
		||||
        fig.show(run=True)
 | 
			
		||||
    else:
 | 
			
		||||
        return fig
 | 
			
		||||
 | 
			
		||||
def cross_section(x_values:list, y_values:list):
 | 
			
		||||
def cross_section(x_values:list, y_values:list,title:str, show:bool=True  ):
 | 
			
		||||
    """
 | 
			
		||||
    Render a 2D cross section using vispy
 | 
			
		||||
    :param x: A list with the x values
 | 
			
		||||
    :param y: A list with the y values
 | 
			
		||||
    """
 | 
			
		||||
    color = (0.3, 0.5, 0.8)
 | 
			
		||||
    color = (0.3, 0.5, 0.8,.8)
 | 
			
		||||
    fig = vp.Fig(show=False)
 | 
			
		||||
    line = fig[0:4, 0:4].plot(np.column_stack((x_values,y_values)), symbol='o', width=0,
 | 
			
		||||
                            face_color=color + (0.02,), edge_color=None,
 | 
			
		||||
                            marker_size=8)
 | 
			
		||||
    line = fig[0:4, 0:4].plot(np.column_stack((x_values,y_values)), symbol='disc', width=0,
 | 
			
		||||
                            face_color=color, edge_color=None,
 | 
			
		||||
                            marker_size=8,title=title)
 | 
			
		||||
    line.set_gl_state(depth_test=False)
 | 
			
		||||
    fig.show(run=True)
 | 
			
		||||
    if show:
 | 
			
		||||
        fig.show(run=True)
 | 
			
		||||
    else:
 | 
			
		||||
        return fig
 | 
			
		||||
@ -5,7 +5,7 @@ from vispy.visuals.filters import ShadingFilter, WireframeFilter
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def render3D(obj:ScannedObject):
 | 
			
		||||
def render3D(obj:ScannedObject,show:bool=True):
 | 
			
		||||
    """
 | 
			
		||||
    Render a 3D model using vispy
 | 
			
		||||
    :param obj: A ScannedObject to be rendered
 | 
			
		||||
@ -16,7 +16,8 @@ def render3D(obj:ScannedObject):
 | 
			
		||||
    view = canvas.central_widget.add_view()
 | 
			
		||||
    view.camera = 'arcball'
 | 
			
		||||
    view.camera.depth_value = 1e3
 | 
			
		||||
    mesh = Mesh(vertices, faces, color=(.5, .7, .5, 1))
 | 
			
		||||
    color = (0.3, 0.5, 0.8)
 | 
			
		||||
    mesh = Mesh(vertices, faces, color=color)
 | 
			
		||||
    view.add(mesh)
 | 
			
		||||
    wireframe_filter = WireframeFilter(width=0)
 | 
			
		||||
    shading_filter = ShadingFilter(shininess=0)
 | 
			
		||||
@ -32,5 +33,8 @@ def render3D(obj:ScannedObject):
 | 
			
		||||
            transform = view.camera.transform
 | 
			
		||||
            shading_filter.light_dir = transform.map(initial_light_dir)[:3]
 | 
			
		||||
    attach_headlight(view)
 | 
			
		||||
    canvas.show()
 | 
			
		||||
    app.run()
 | 
			
		||||
    if show:
 | 
			
		||||
        canvas.show()
 | 
			
		||||
        app.run()
 | 
			
		||||
    else:
 | 
			
		||||
        return canvas
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
import vispy.plot as vp
 | 
			
		||||
import numpy as np
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CrossSection2DCanvas:
 | 
			
		||||
    def __init__(self,x_values:list, y_values:list,title:str):
 | 
			
		||||
        color = (0.3, 0.5, 0.8)
 | 
			
		||||
        self.canvas = vp.Fig(show=False,size=(500, 500))
 | 
			
		||||
        line = self.canvas[0,0].plot(np.column_stack((x_values,y_values)), symbol='o', width=0,
 | 
			
		||||
                                face_color=color + (0.02,), edge_color=None,
 | 
			
		||||
                                marker_size=8,title=title)
 | 
			
		||||
        line.set_gl_state(depth_test=False)
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
from vispy import scene
 | 
			
		||||
from vispy.scene.visuals import Mesh
 | 
			
		||||
from vispy.visuals.filters import ShadingFilter, WireframeFilter
 | 
			
		||||
from vispy.scene import SceneCanvas
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
import numpy as np
 | 
			
		||||
 | 
			
		||||
class Mesh3DCanvas:
 | 
			
		||||
    def __init__(self,obj:ScannedObject):
 | 
			
		||||
        vertices = np.asarray(obj.get_vertices())
 | 
			
		||||
        faces = np.asarray(obj.get_faces())
 | 
			
		||||
        self.canvas = scene.SceneCanvas(keys='interactive', bgcolor='white',size=(400, 400))
 | 
			
		||||
        view = self.canvas.central_widget.add_view()
 | 
			
		||||
        view.camera = 'arcball'
 | 
			
		||||
        view.camera.depth_value = 1e3
 | 
			
		||||
        mesh = Mesh(vertices, faces, color=(.5, .7, .5, 1))
 | 
			
		||||
        view.add(mesh)
 | 
			
		||||
        wireframe_filter = WireframeFilter(width=0)
 | 
			
		||||
        shading_filter = ShadingFilter(shininess=0)
 | 
			
		||||
        mesh.attach(wireframe_filter)
 | 
			
		||||
        mesh.attach(shading_filter)
 | 
			
		||||
        def attach_headlight(view):
 | 
			
		||||
            light_dir = (0, 1, 0, 0)
 | 
			
		||||
            shading_filter.light_dir = light_dir[:3]
 | 
			
		||||
            initial_light_dir = view.camera.transform.imap(light_dir)
 | 
			
		||||
            @view.scene.transform.changed.connect
 | 
			
		||||
            def on_transform_change(event):
 | 
			
		||||
                transform = view.camera.transform
 | 
			
		||||
                shading_filter.light_dir = transform.map(initial_light_dir)[:3]
 | 
			
		||||
        attach_headlight(view)
 | 
			
		||||
@ -1,12 +1,14 @@
 | 
			
		||||
import os
 | 
			
		||||
from PyQt5 import QtWidgets
 | 
			
		||||
from PyQt5.QtCore import QThread, pyqtSignal, QObject
 | 
			
		||||
from PyQt5.QtWidgets import QFileDialog
 | 
			
		||||
from PyQt5.QtCore import QThread
 | 
			
		||||
from PyQt5.QtWidgets import QFileDialog, QWidget
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
from utils.graph2D.visplot_render import cross_section, render2D
 | 
			
		||||
from utils.graph3D.visplot_render import render3D
 | 
			
		||||
from utils.gui.pyqt.main_window.UI_MainWindow import Ui_MainWindow
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.AnalyseWorker import AnalyseWorker
 | 
			
		||||
from utils.gui.pyqt.main_window.Canvas.Mesh3DCanvas import Mesh3DCanvas
 | 
			
		||||
from utils.gui.pyqt.main_window.Canvas.CrossSection2DCanvas import CrossSection2DCanvas
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.DiscreteDataWorker import DiscreteDataProcessWorker
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.PreProcessWorker import PreProcessWorker
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.RawDataWorker import RawDataProcessWorker
 | 
			
		||||
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 | 
			
		||||
    """
 | 
			
		||||
    Main window of the application
 | 
			
		||||
@ -17,12 +19,61 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 | 
			
		||||
        # Retrieve the UI
 | 
			
		||||
        self.setupUi(self)
 | 
			
		||||
        # Setup buttons listeners
 | 
			
		||||
        self.start_analyse_button.clicked.connect(self.start_analyse)
 | 
			
		||||
        self.start_analyse_button.clicked.connect(self.start_preprocess)
 | 
			
		||||
        self.input_file_choose_btn.clicked.connect(self.select_file)
 | 
			
		||||
        self.output_folder_choose_btn.clicked.connect(self.select_folder)
 | 
			
		||||
        #CanvasWrapper(ScannedObject.from_obj_file("/Users/djalim/Documents/DevStuff/AnalyseMorphologique/datasets/Barette/1 - BARETTE.obj")).canvas.native
 | 
			
		||||
        self.completed = 0
 | 
			
		||||
        self.show_graph_checkbox.stateChanged.connect(self.toggle_graphs)
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        self.graphType = [
 | 
			
		||||
            "Aucun",
 | 
			
		||||
            "Mesh3D",
 | 
			
		||||
            "CoupeXZ",
 | 
			
		||||
            "CoupeYZ",
 | 
			
		||||
            "EvolutionRayon",
 | 
			
		||||
        ]
 | 
			
		||||
        
 | 
			
		||||
        self.obj = None
 | 
			
		||||
        self.raw_data= None
 | 
			
		||||
        self.discrete_data = None
 | 
			
		||||
 | 
			
		||||
        self.completed = 0
 | 
			
		||||
        self.total = 2
 | 
			
		||||
 | 
			
		||||
        self.comboBoxes = [
 | 
			
		||||
            self.slot0ComboBox,
 | 
			
		||||
            self.slot1ComboBox,
 | 
			
		||||
            self.slot2ComboBox,
 | 
			
		||||
            self.slot3ComboBox,
 | 
			
		||||
            self.slot4ComboBox,
 | 
			
		||||
            self.slot5ComboBox,
 | 
			
		||||
            self.slot6ComboBox,
 | 
			
		||||
            self.slot7ComboBox
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        for cb in self.comboBoxes:
 | 
			
		||||
            cb.addItems(self.graphType)
 | 
			
		||||
 | 
			
		||||
        self.slots = [
 | 
			
		||||
                    [self.slot0,None],
 | 
			
		||||
                    [self.slot1,None],
 | 
			
		||||
                    [self.slot2,None],
 | 
			
		||||
                    [self.slot3,None],
 | 
			
		||||
                    [self.slot4,None],
 | 
			
		||||
                    [self.slot5,None],
 | 
			
		||||
                    [self.slot6,None],
 | 
			
		||||
                    [self.slot7,None]
 | 
			
		||||
                    ]
 | 
			
		||||
    
 | 
			
		||||
        self.threads = []
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                           Input/Setting Management                          #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
###############################################################################
 | 
			
		||||
    def select_file(self):
 | 
			
		||||
        """
 | 
			
		||||
        Open a file dialog to select the input file
 | 
			
		||||
@ -35,67 +86,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 | 
			
		||||
        """
 | 
			
		||||
        Open a file dialog to select the output folder
 | 
			
		||||
        """
 | 
			
		||||
        self.output_folder_path.setPlainText(
 | 
			
		||||
            QFileDialog.getExistingDirectory())
 | 
			
		||||
 | 
			
		||||
    def start_analyse(self):
 | 
			
		||||
        """
 | 
			
		||||
        Start the analyse
 | 
			
		||||
        """
 | 
			
		||||
        if not self.check_input_file():
 | 
			
		||||
            self.input_file_path.setPlainText("Invalid file path")
 | 
			
		||||
            return
 | 
			
		||||
        if not self.check_output_folder():
 | 
			
		||||
            self.output_folder_path.setPlainText("Invalid folder path")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        # Create the thread to run the analyse
 | 
			
		||||
        self.thread = QThread()
 | 
			
		||||
        self.worker = AnalyseWorker(self.input_file_path.toPlainText(),
 | 
			
		||||
                             self.output_folder_path.toPlainText(),
 | 
			
		||||
                             self.output_file_prefix.text(),
 | 
			
		||||
                             self.discretisation_value_selector.value())
 | 
			
		||||
        self.worker.moveToThread(self.thread)
 | 
			
		||||
 | 
			
		||||
        # Connect the signals
 | 
			
		||||
        # Start
 | 
			
		||||
        self.thread.started.connect(self.worker.run)
 | 
			
		||||
        # Progress
 | 
			
		||||
        self.worker.status.connect(self.set_status)
 | 
			
		||||
        self.worker.progress.connect(self.update_progress_bar)
 | 
			
		||||
        self.worker.render.connect(self.show_graph)
 | 
			
		||||
        # Finished
 | 
			
		||||
        self.worker.finished.connect(self.finish_analyse)
 | 
			
		||||
        self.worker.finished.connect(self.thread.quit)
 | 
			
		||||
        self.worker.finished.connect(self.worker.deleteLater)
 | 
			
		||||
        self.thread.finished.connect(self.thread.deleteLater)
 | 
			
		||||
 | 
			
		||||
        # Start the thread
 | 
			
		||||
        self.thread.start()
 | 
			
		||||
        self.start_analyse_button.setEnabled(False)
 | 
			
		||||
 | 
			
		||||
    def set_status(self, status:str):
 | 
			
		||||
        """
 | 
			
		||||
        Set the status of the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.status_text.setText(status)
 | 
			
		||||
 | 
			
		||||
    def show_graph(self, obj:ScannedObject):
 | 
			
		||||
        """
 | 
			
		||||
        Show the graph
 | 
			
		||||
        """
 | 
			
		||||
        if not self.show_graph_checkbox.checked:
 | 
			
		||||
            return
 | 
			
		||||
        self.slot0.addWidget(Mesh3DCanvas(obj).canvas.native)
 | 
			
		||||
        self.slot1.addWidget(CrossSection2DCanvas(obj.get_x(),obj.get_z(),"Coupe X").canvas.native)
 | 
			
		||||
        self.slot2.addWidget(CrossSection2DCanvas(obj.get_y(),obj.get_z(),"Coupe Y").canvas.native)
 | 
			
		||||
 | 
			
		||||
    def finish_analyse(self):
 | 
			
		||||
        """
 | 
			
		||||
        Finish the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.start_analyse_button.setEnabled(True)
 | 
			
		||||
 | 
			
		||||
        self.output_folder_path.setPlainText(QFileDialog.getExistingDirectory())
 | 
			
		||||
 | 
			
		||||
    def check_input_file(self):
 | 
			
		||||
        """
 | 
			
		||||
@ -111,8 +102,180 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 | 
			
		||||
        if os.path.isdir(self.output_folder_path.toPlainText()):
 | 
			
		||||
            return True
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                              Data Processing                                #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
    def start_preprocess(self):
 | 
			
		||||
        """
 | 
			
		||||
        Start the analyse
 | 
			
		||||
        """
 | 
			
		||||
        if not self.check_input_file():
 | 
			
		||||
            self.input_file_path.setPlainText("Invalid file path")
 | 
			
		||||
            return
 | 
			
		||||
        if not self.check_output_folder():
 | 
			
		||||
            self.output_folder_path.setPlainText("Invalid folder path")
 | 
			
		||||
            return
 | 
			
		||||
        
 | 
			
		||||
        for count,_ in enumerate(self.slots):
 | 
			
		||||
            self.slots[count][1] = self.comboBoxes[count].currentText()
 | 
			
		||||
            
 | 
			
		||||
        self.clear_graphs()
 | 
			
		||||
        self.completed = 0
 | 
			
		||||
        # Create the thread to run the analyse
 | 
			
		||||
        self.preprocess_thread = QThread()
 | 
			
		||||
        self.preprocess_worker = PreProcessWorker("PreProcessWorker",self.input_file_path.toPlainText())
 | 
			
		||||
        self.preprocess_worker.moveToThread(self.preprocess_thread)
 | 
			
		||||
 | 
			
		||||
        # Connect the signals
 | 
			
		||||
        # Start
 | 
			
		||||
        self.preprocess_thread.started.connect(self.preprocess_worker.run)
 | 
			
		||||
        # Progress
 | 
			
		||||
        self.preprocess_worker.status.connect(self.set_status)
 | 
			
		||||
        self.preprocess_worker.progress.connect(self.update_progress_bar)
 | 
			
		||||
        self.preprocess_worker.processed_obj.connect(self.set_obj)
 | 
			
		||||
        self.preprocess_worker.processed_obj.connect(self.process_raw_data)
 | 
			
		||||
        self.preprocess_worker.processed_obj.connect(self.process_discrete_data)
 | 
			
		||||
        # Finished
 | 
			
		||||
        self.preprocess_worker.finished.connect(self.preprocess_thread.quit)
 | 
			
		||||
        self.preprocess_worker.finished.connect(self.preprocess_worker.deleteLater)
 | 
			
		||||
        self.preprocess_thread.finished.connect(self.preprocess_thread.deleteLater)
 | 
			
		||||
 | 
			
		||||
        # Start the thread
 | 
			
		||||
        self.preprocess_thread.start()
 | 
			
		||||
        self.start_analyse_button.setEnabled(False)
 | 
			
		||||
 | 
			
		||||
    def process_raw_data(self, obj:ScannedObject):
 | 
			
		||||
        self.processrawdata_thread = QThread()
 | 
			
		||||
        self.processraw_worker = RawDataProcessWorker("RawDataProcessWorker",
 | 
			
		||||
                                                      obj,
 | 
			
		||||
                                                      self.output_folder_path.toPlainText(),
 | 
			
		||||
                                                      self.output_file_prefix.text(),
 | 
			
		||||
                                                      self.discretisation_value_selector.value())
 | 
			
		||||
        self.processraw_worker.moveToThread(self.processrawdata_thread)
 | 
			
		||||
        # Connect the signals
 | 
			
		||||
        # Start
 | 
			
		||||
        self.processrawdata_thread.started.connect(self.processraw_worker.run)
 | 
			
		||||
        # Progress
 | 
			
		||||
        self.processraw_worker.status.connect(self.set_status)
 | 
			
		||||
        self.processraw_worker.progress.connect(self.update_progress_bar)
 | 
			
		||||
        self.processraw_worker.processedData.connect(self.set_raw_data)
 | 
			
		||||
        # Finished
 | 
			
		||||
        self.processraw_worker.finished.connect(self.finish_analyse)
 | 
			
		||||
        self.processraw_worker.finished.connect(self.processrawdata_thread.quit)
 | 
			
		||||
        self.processraw_worker.finished.connect(self.processraw_worker.deleteLater)
 | 
			
		||||
        self.processrawdata_thread.finished.connect(self.processrawdata_thread.deleteLater)
 | 
			
		||||
 | 
			
		||||
        # Start the thread
 | 
			
		||||
        self.processrawdata_thread.start()
 | 
			
		||||
 | 
			
		||||
    def process_discrete_data(self, obj:ScannedObject):
 | 
			
		||||
        self.processdiscrete_thread = QThread()
 | 
			
		||||
        self.processdiscrete_worker = DiscreteDataProcessWorker("DiscreteDataProcessWorker",
 | 
			
		||||
                                                                obj,
 | 
			
		||||
                                                                self.output_folder_path.toPlainText(),
 | 
			
		||||
                                                                self.output_file_prefix.text(),
 | 
			
		||||
                                                                self.discretisation_value_selector.value())
 | 
			
		||||
        self.processdiscrete_worker.moveToThread(self.processdiscrete_thread)
 | 
			
		||||
        # Connect the signals
 | 
			
		||||
        # Start
 | 
			
		||||
        self.processdiscrete_thread.started.connect(self.processdiscrete_worker.run)
 | 
			
		||||
        # Progress
 | 
			
		||||
        self.processdiscrete_worker.status.connect(self.set_status)
 | 
			
		||||
        self.processdiscrete_worker.progress.connect(self.update_progress_bar)
 | 
			
		||||
        self.processdiscrete_worker.processedData.connect(self.set_discrete_data)
 | 
			
		||||
        # Finished
 | 
			
		||||
        self.processdiscrete_worker.finished.connect(self.finish_analyse)
 | 
			
		||||
        self.processdiscrete_worker.finished.connect(self.processdiscrete_thread.quit)
 | 
			
		||||
        self.processdiscrete_worker.finished.connect(self.processdiscrete_worker.deleteLater)
 | 
			
		||||
        self.processdiscrete_thread.finished.connect(self.processdiscrete_thread.deleteLater)
 | 
			
		||||
        
 | 
			
		||||
        # Start the thread
 | 
			
		||||
        self.processdiscrete_thread.start()
 | 
			
		||||
 | 
			
		||||
    def set_obj(self,obj:ScannedObject):
 | 
			
		||||
        self.obj = obj
 | 
			
		||||
 | 
			
		||||
    def set_discrete_data(self,discrete_data:dict):
 | 
			
		||||
        self.discrete_data = discrete_data
 | 
			
		||||
 | 
			
		||||
    def set_raw_data(self,raw_data:dict):
 | 
			
		||||
        self.raw_data = raw_data 
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                              Graphs management                              #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
    def toggle_graphs(self):
 | 
			
		||||
        """
 | 
			
		||||
        Show or hide the graphs
 | 
			
		||||
        """
 | 
			
		||||
        if self.show_graph_checkbox.isChecked():
 | 
			
		||||
            self.Graphs.show()
 | 
			
		||||
        else:
 | 
			
		||||
            self.Graphs.hide()
 | 
			
		||||
 | 
			
		||||
    def renderGraphs(self,obj:ScannedObject,raw_data:dict,discrete_data:dict):
 | 
			
		||||
        if not self.show_graph_checkbox.isChecked():
 | 
			
		||||
            return
 | 
			
		||||
        for slot in self.slots:
 | 
			
		||||
            current_slot = slot[0]
 | 
			
		||||
            graph_type = slot[1]
 | 
			
		||||
            if graph_type == "Mesh3D":
 | 
			
		||||
                current_slot.addWidget(render3D(obj,False).native)
 | 
			
		||||
            if graph_type == "CoupeX":
 | 
			
		||||
                current_slot.addWidget(cross_section(obj.get_x(),obj.get_z(),"Coupe X",False).native)
 | 
			
		||||
            if graph_type == "CoupeY":
 | 
			
		||||
                current_slot.addWidget(cross_section(obj.get_y(),obj.get_z(),"Coupe Y",False).native)
 | 
			
		||||
            if graph_type == "EvolutionRayon":
 | 
			
		||||
                current_slot.addWidget(render2D(list(zip(discrete_data['Z moy (en mm)'],discrete_data['Rayon moyen (en mm)'])),"Evolution du rayon moyen",False).native)
 | 
			
		||||
 | 
			
		||||
    def clear_graphs(self):
 | 
			
		||||
        """
 | 
			
		||||
        Clear the graphs
 | 
			
		||||
        """
 | 
			
		||||
        if not self.show_graph_checkbox.isChecked():
 | 
			
		||||
            return
 | 
			
		||||
        for slot,_ in self.slots:
 | 
			
		||||
            for i in reversed(range(slot.count())):
 | 
			
		||||
                slot.itemAt(i).widget().setParent(None)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                            User interface updates                           #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
    def finish_analyse(self):
 | 
			
		||||
        """
 | 
			
		||||
        Finish the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.completed += 1
 | 
			
		||||
        if self.completed == self.total:
 | 
			
		||||
            self.status_text.setText("Done")
 | 
			
		||||
            self.analyse_progress_bar.setValue(100)
 | 
			
		||||
            self.renderGraphs(self.obj,self.raw_data,self.discrete_data)
 | 
			
		||||
            self.start_analyse_button.setEnabled(True)
 | 
			
		||||
 | 
			
		||||
    def update_progress_bar(self, value):
 | 
			
		||||
        """
 | 
			
		||||
        Update the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.analyse_progress_bar.setValue(value)
 | 
			
		||||
        self.analyse_progress_bar.setValue(value)
 | 
			
		||||
 | 
			
		||||
    def set_status(self, status:str):
 | 
			
		||||
        """
 | 
			
		||||
        Set the status of the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.status_text.setText(status)
 | 
			
		||||
 | 
			
		||||
@ -122,6 +122,9 @@
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>afficher les graphes</string>
 | 
			
		||||
             </property>
 | 
			
		||||
             <property name="checked">
 | 
			
		||||
              <bool>true</bool>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
@ -145,6 +148,9 @@
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QWidget" name="Graphs" native="true">
 | 
			
		||||
        <property name="enabled">
 | 
			
		||||
         <bool>true</bool>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="minimumSize">
 | 
			
		||||
         <size>
 | 
			
		||||
          <width>700</width>
 | 
			
		||||
@ -153,20 +159,175 @@
 | 
			
		||||
        </property>
 | 
			
		||||
        <layout class="QGridLayout" name="gridLayout_3">
 | 
			
		||||
         <item row="0" column="0">
 | 
			
		||||
          <layout class="QGridLayout" name="GraphsLayout">
 | 
			
		||||
           <item row="0" column="0">
 | 
			
		||||
            <layout class="QGridLayout" name="slot0"/>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item row="2" column="0">
 | 
			
		||||
            <layout class="QGridLayout" name="slot2"/>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item row="0" column="1">
 | 
			
		||||
            <layout class="QGridLayout" name="slot1"/>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item row="2" column="1">
 | 
			
		||||
            <layout class="QGridLayout" name="solt3"/>
 | 
			
		||||
           </item>
 | 
			
		||||
          </layout>
 | 
			
		||||
          <widget class="QTabWidget" name="tabWidget">
 | 
			
		||||
           <property name="enabled">
 | 
			
		||||
            <bool>true</bool>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="currentIndex">
 | 
			
		||||
            <number>0</number>
 | 
			
		||||
           </property>
 | 
			
		||||
           <widget class="QWidget" name="tab">
 | 
			
		||||
            <property name="enabled">
 | 
			
		||||
             <bool>true</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
            <attribute name="title">
 | 
			
		||||
             <string>1</string>
 | 
			
		||||
            </attribute>
 | 
			
		||||
            <layout class="QGridLayout" name="gridLayout_5">
 | 
			
		||||
             <item row="0" column="1">
 | 
			
		||||
              <widget class="QFrame" name="slot1_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_10">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot1"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot1ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="1" column="0">
 | 
			
		||||
              <widget class="QFrame" name="slot2_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_11">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot2"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot2ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="1" column="1">
 | 
			
		||||
              <widget class="QFrame" name="slot3_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_12">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot3"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot3ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="0" column="0">
 | 
			
		||||
              <widget class="QFrame" name="slot0_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_8">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot0"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot0ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </widget>
 | 
			
		||||
           <widget class="QWidget" name="tab_2">
 | 
			
		||||
            <attribute name="title">
 | 
			
		||||
             <string>2</string>
 | 
			
		||||
            </attribute>
 | 
			
		||||
            <layout class="QGridLayout" name="gridLayout_13">
 | 
			
		||||
             <item row="0" column="1">
 | 
			
		||||
              <widget class="QFrame" name="slot5_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_18">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot5"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot5ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="0" column="0">
 | 
			
		||||
              <widget class="QFrame" name="slot4_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_17">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot4"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot4ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="1" column="0">
 | 
			
		||||
              <widget class="QFrame" name="slot6_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_19">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot6"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot6ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="1" column="1">
 | 
			
		||||
              <widget class="QFrame" name="slot7_frame">
 | 
			
		||||
               <property name="frameShape">
 | 
			
		||||
                <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="frameShadow">
 | 
			
		||||
                <enum>QFrame::Raised</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <layout class="QGridLayout" name="gridLayout_20">
 | 
			
		||||
                <item row="1" column="0">
 | 
			
		||||
                 <layout class="QGridLayout" name="slot7"/>
 | 
			
		||||
                </item>
 | 
			
		||||
                <item row="0" column="0">
 | 
			
		||||
                 <widget class="QComboBox" name="slot7ComboBox"/>
 | 
			
		||||
                </item>
 | 
			
		||||
               </layout>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
 | 
			
		||||
@ -76,6 +76,7 @@ class Ui_MainWindow(object):
 | 
			
		||||
        self.analyse_progress_bar.setObjectName("analyse_progress_bar")
 | 
			
		||||
        self.MainSettingsLayout.addWidget(self.analyse_progress_bar)
 | 
			
		||||
        self.show_graph_checkbox = QtWidgets.QCheckBox(self.MainSettings)
 | 
			
		||||
        self.show_graph_checkbox.setChecked(True)
 | 
			
		||||
        self.show_graph_checkbox.setObjectName("show_graph_checkbox")
 | 
			
		||||
        self.MainSettingsLayout.addWidget(self.show_graph_checkbox, 0, QtCore.Qt.AlignHCenter)
 | 
			
		||||
        self.start_analyse_button = QtWidgets.QPushButton(self.MainSettings)
 | 
			
		||||
@ -88,30 +89,136 @@ class Ui_MainWindow(object):
 | 
			
		||||
        self.gridLayout_2.addLayout(self.MainSettingsLayout, 0, 0, 1, 1)
 | 
			
		||||
        self.horizontalLayout_4.addWidget(self.MainSettings)
 | 
			
		||||
        self.Graphs = QtWidgets.QWidget(self.centralwidget)
 | 
			
		||||
        self.Graphs.setEnabled(True)
 | 
			
		||||
        self.Graphs.setMinimumSize(QtCore.QSize(700, 0))
 | 
			
		||||
        self.Graphs.setObjectName("Graphs")
 | 
			
		||||
        self.gridLayout_3 = QtWidgets.QGridLayout(self.Graphs)
 | 
			
		||||
        self.gridLayout_3.setObjectName("gridLayout_3")
 | 
			
		||||
        self.GraphsLayout = QtWidgets.QGridLayout()
 | 
			
		||||
        self.GraphsLayout.setObjectName("GraphsLayout")
 | 
			
		||||
        self.slot0 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot0.setObjectName("slot0")
 | 
			
		||||
        self.GraphsLayout.addLayout(self.slot0, 0, 0, 1, 1)
 | 
			
		||||
        self.slot2 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot2.setObjectName("slot2")
 | 
			
		||||
        self.GraphsLayout.addLayout(self.slot2, 2, 0, 1, 1)
 | 
			
		||||
        self.tabWidget = QtWidgets.QTabWidget(self.Graphs)
 | 
			
		||||
        self.tabWidget.setEnabled(True)
 | 
			
		||||
        self.tabWidget.setObjectName("tabWidget")
 | 
			
		||||
        self.tab = QtWidgets.QWidget()
 | 
			
		||||
        self.tab.setEnabled(True)
 | 
			
		||||
        self.tab.setObjectName("tab")
 | 
			
		||||
        self.gridLayout_5 = QtWidgets.QGridLayout(self.tab)
 | 
			
		||||
        self.gridLayout_5.setObjectName("gridLayout_5")
 | 
			
		||||
        self.slot1_frame = QtWidgets.QFrame(self.tab)
 | 
			
		||||
        self.slot1_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot1_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot1_frame.setObjectName("slot1_frame")
 | 
			
		||||
        self.gridLayout_10 = QtWidgets.QGridLayout(self.slot1_frame)
 | 
			
		||||
        self.gridLayout_10.setObjectName("gridLayout_10")
 | 
			
		||||
        self.slot1 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot1.setObjectName("slot1")
 | 
			
		||||
        self.GraphsLayout.addLayout(self.slot1, 0, 1, 1, 1)
 | 
			
		||||
        self.solt3 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.solt3.setObjectName("solt3")
 | 
			
		||||
        self.GraphsLayout.addLayout(self.solt3, 2, 1, 1, 1)
 | 
			
		||||
        self.gridLayout_3.addLayout(self.GraphsLayout, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_10.addLayout(self.slot1, 1, 0, 1, 1)
 | 
			
		||||
        self.slot1ComboBox = QtWidgets.QComboBox(self.slot1_frame)
 | 
			
		||||
        self.slot1ComboBox.setObjectName("slot1ComboBox")
 | 
			
		||||
        self.gridLayout_10.addWidget(self.slot1ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_5.addWidget(self.slot1_frame, 0, 1, 1, 1)
 | 
			
		||||
        self.slot2_frame = QtWidgets.QFrame(self.tab)
 | 
			
		||||
        self.slot2_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot2_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot2_frame.setObjectName("slot2_frame")
 | 
			
		||||
        self.gridLayout_11 = QtWidgets.QGridLayout(self.slot2_frame)
 | 
			
		||||
        self.gridLayout_11.setObjectName("gridLayout_11")
 | 
			
		||||
        self.slot2 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot2.setObjectName("slot2")
 | 
			
		||||
        self.gridLayout_11.addLayout(self.slot2, 1, 0, 1, 1)
 | 
			
		||||
        self.slot2ComboBox = QtWidgets.QComboBox(self.slot2_frame)
 | 
			
		||||
        self.slot2ComboBox.setObjectName("slot2ComboBox")
 | 
			
		||||
        self.gridLayout_11.addWidget(self.slot2ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_5.addWidget(self.slot2_frame, 1, 0, 1, 1)
 | 
			
		||||
        self.slot3_frame = QtWidgets.QFrame(self.tab)
 | 
			
		||||
        self.slot3_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot3_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot3_frame.setObjectName("slot3_frame")
 | 
			
		||||
        self.gridLayout_12 = QtWidgets.QGridLayout(self.slot3_frame)
 | 
			
		||||
        self.gridLayout_12.setObjectName("gridLayout_12")
 | 
			
		||||
        self.slot3 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot3.setObjectName("slot3")
 | 
			
		||||
        self.gridLayout_12.addLayout(self.slot3, 1, 0, 1, 1)
 | 
			
		||||
        self.slot3ComboBox = QtWidgets.QComboBox(self.slot3_frame)
 | 
			
		||||
        self.slot3ComboBox.setObjectName("slot3ComboBox")
 | 
			
		||||
        self.gridLayout_12.addWidget(self.slot3ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_5.addWidget(self.slot3_frame, 1, 1, 1, 1)
 | 
			
		||||
        self.slot0_frame = QtWidgets.QFrame(self.tab)
 | 
			
		||||
        self.slot0_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot0_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot0_frame.setObjectName("slot0_frame")
 | 
			
		||||
        self.gridLayout_8 = QtWidgets.QGridLayout(self.slot0_frame)
 | 
			
		||||
        self.gridLayout_8.setObjectName("gridLayout_8")
 | 
			
		||||
        self.slot0 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot0.setObjectName("slot0")
 | 
			
		||||
        self.gridLayout_8.addLayout(self.slot0, 1, 0, 1, 1)
 | 
			
		||||
        self.slot0ComboBox = QtWidgets.QComboBox(self.slot0_frame)
 | 
			
		||||
        self.slot0ComboBox.setObjectName("slot0ComboBox")
 | 
			
		||||
        self.gridLayout_8.addWidget(self.slot0ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_5.addWidget(self.slot0_frame, 0, 0, 1, 1)
 | 
			
		||||
        self.tabWidget.addTab(self.tab, "")
 | 
			
		||||
        self.tab_2 = QtWidgets.QWidget()
 | 
			
		||||
        self.tab_2.setObjectName("tab_2")
 | 
			
		||||
        self.gridLayout_13 = QtWidgets.QGridLayout(self.tab_2)
 | 
			
		||||
        self.gridLayout_13.setObjectName("gridLayout_13")
 | 
			
		||||
        self.slot5_frame = QtWidgets.QFrame(self.tab_2)
 | 
			
		||||
        self.slot5_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot5_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot5_frame.setObjectName("slot5_frame")
 | 
			
		||||
        self.gridLayout_18 = QtWidgets.QGridLayout(self.slot5_frame)
 | 
			
		||||
        self.gridLayout_18.setObjectName("gridLayout_18")
 | 
			
		||||
        self.slot5 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot5.setObjectName("slot5")
 | 
			
		||||
        self.gridLayout_18.addLayout(self.slot5, 1, 0, 1, 1)
 | 
			
		||||
        self.slot5ComboBox = QtWidgets.QComboBox(self.slot5_frame)
 | 
			
		||||
        self.slot5ComboBox.setObjectName("slot5ComboBox")
 | 
			
		||||
        self.gridLayout_18.addWidget(self.slot5ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_13.addWidget(self.slot5_frame, 0, 1, 1, 1)
 | 
			
		||||
        self.slot4_frame = QtWidgets.QFrame(self.tab_2)
 | 
			
		||||
        self.slot4_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot4_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot4_frame.setObjectName("slot4_frame")
 | 
			
		||||
        self.gridLayout_17 = QtWidgets.QGridLayout(self.slot4_frame)
 | 
			
		||||
        self.gridLayout_17.setObjectName("gridLayout_17")
 | 
			
		||||
        self.slot4 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot4.setObjectName("slot4")
 | 
			
		||||
        self.gridLayout_17.addLayout(self.slot4, 1, 0, 1, 1)
 | 
			
		||||
        self.slot4ComboBox = QtWidgets.QComboBox(self.slot4_frame)
 | 
			
		||||
        self.slot4ComboBox.setObjectName("slot4ComboBox")
 | 
			
		||||
        self.gridLayout_17.addWidget(self.slot4ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_13.addWidget(self.slot4_frame, 0, 0, 1, 1)
 | 
			
		||||
        self.slot6_frame = QtWidgets.QFrame(self.tab_2)
 | 
			
		||||
        self.slot6_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot6_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot6_frame.setObjectName("slot6_frame")
 | 
			
		||||
        self.gridLayout_19 = QtWidgets.QGridLayout(self.slot6_frame)
 | 
			
		||||
        self.gridLayout_19.setObjectName("gridLayout_19")
 | 
			
		||||
        self.slot6 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot6.setObjectName("slot6")
 | 
			
		||||
        self.gridLayout_19.addLayout(self.slot6, 1, 0, 1, 1)
 | 
			
		||||
        self.slot6ComboBox = QtWidgets.QComboBox(self.slot6_frame)
 | 
			
		||||
        self.slot6ComboBox.setObjectName("slot6ComboBox")
 | 
			
		||||
        self.gridLayout_19.addWidget(self.slot6ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_13.addWidget(self.slot6_frame, 1, 0, 1, 1)
 | 
			
		||||
        self.slot7_frame = QtWidgets.QFrame(self.tab_2)
 | 
			
		||||
        self.slot7_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 | 
			
		||||
        self.slot7_frame.setFrameShadow(QtWidgets.QFrame.Raised)
 | 
			
		||||
        self.slot7_frame.setObjectName("slot7_frame")
 | 
			
		||||
        self.gridLayout_20 = QtWidgets.QGridLayout(self.slot7_frame)
 | 
			
		||||
        self.gridLayout_20.setObjectName("gridLayout_20")
 | 
			
		||||
        self.slot7 = QtWidgets.QGridLayout()
 | 
			
		||||
        self.slot7.setObjectName("slot7")
 | 
			
		||||
        self.gridLayout_20.addLayout(self.slot7, 1, 0, 1, 1)
 | 
			
		||||
        self.slot7ComboBox = QtWidgets.QComboBox(self.slot7_frame)
 | 
			
		||||
        self.slot7ComboBox.setObjectName("slot7ComboBox")
 | 
			
		||||
        self.gridLayout_20.addWidget(self.slot7ComboBox, 0, 0, 1, 1)
 | 
			
		||||
        self.gridLayout_13.addWidget(self.slot7_frame, 1, 1, 1, 1)
 | 
			
		||||
        self.tabWidget.addTab(self.tab_2, "")
 | 
			
		||||
        self.gridLayout_3.addWidget(self.tabWidget, 0, 0, 1, 1)
 | 
			
		||||
        self.horizontalLayout_4.addWidget(self.Graphs)
 | 
			
		||||
        self.gridLayout.addLayout(self.horizontalLayout_4, 1, 0, 1, 1)
 | 
			
		||||
        MainWindow.setCentralWidget(self.centralwidget)
 | 
			
		||||
 | 
			
		||||
        self.retranslateUi(MainWindow)
 | 
			
		||||
        self.tabWidget.setCurrentIndex(0)
 | 
			
		||||
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 | 
			
		||||
 | 
			
		||||
    def retranslateUi(self, MainWindow):
 | 
			
		||||
@ -125,3 +232,5 @@ class Ui_MainWindow(object):
 | 
			
		||||
        self.discretisation_label.setText(_translate("MainWindow", "Discretisation (en mm)"))
 | 
			
		||||
        self.show_graph_checkbox.setText(_translate("MainWindow", "afficher les graphes"))
 | 
			
		||||
        self.start_analyse_button.setText(_translate("MainWindow", "Analyser le fichier"))
 | 
			
		||||
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "1"))
 | 
			
		||||
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "2"))
 | 
			
		||||
 | 
			
		||||
@ -1,92 +0,0 @@
 | 
			
		||||
from PyQt5.QtCore import pyqtSignal, QObject
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
from utils.files.output import save_output_file, format_data
 | 
			
		||||
from utils.math.position_manipulation import verticalise
 | 
			
		||||
from utils.data_processing.data_processing import get_discrete_data, get_raw_data
 | 
			
		||||
 | 
			
		||||
class AnalyseWorker(QObject):
 | 
			
		||||
    """
 | 
			
		||||
    Worker to run the analyse in a thread
 | 
			
		||||
    """
 | 
			
		||||
    finished = pyqtSignal()
 | 
			
		||||
    render = pyqtSignal(ScannedObject)
 | 
			
		||||
    progress = pyqtSignal(int)
 | 
			
		||||
    status = pyqtSignal(str)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, objpath,output_path,output_file_prefix,delta_z):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.objpath = objpath
 | 
			
		||||
        self.delta_z = delta_z
 | 
			
		||||
        self.output_path = output_path
 | 
			
		||||
        self.output_file_prefix = output_file_prefix
 | 
			
		||||
        self.progress_value = 0
 | 
			
		||||
        self.progress_weight = 100
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        """
 | 
			
		||||
        Run the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.set_status("Loading file...")
 | 
			
		||||
        obj = ScannedObject.from_obj_file(self.objpath)
 | 
			
		||||
        self.update_progress(5)
 | 
			
		||||
 | 
			
		||||
        self.set_status("Verticalising object...")
 | 
			
		||||
        verticalise(obj)
 | 
			
		||||
        self.update_progress(5)
 | 
			
		||||
 | 
			
		||||
        self.set_status("Normalising object...")
 | 
			
		||||
        obj.normalise()
 | 
			
		||||
        self.update_progress(5)
 | 
			
		||||
        self.render.emit(obj)
 | 
			
		||||
        self.set_weight(70)
 | 
			
		||||
 | 
			
		||||
        self.set_status("Calculating raw data...")
 | 
			
		||||
        raw_data = get_raw_data(obj, 6,self.delta_z,self.update_progress)
 | 
			
		||||
        self.set_status("Calculating discrete data...")
 | 
			
		||||
        discrete_data = get_discrete_data(obj, 6,self.delta_z,self.update_progress)
 | 
			
		||||
 | 
			
		||||
        self.set_weight(100)
 | 
			
		||||
        self.set_status("Saving data...")
 | 
			
		||||
        save_output_file(f'{self.output_path}/{self.output_file_prefix}_delta_{self.delta_z}_analyse_brute.txt',
 | 
			
		||||
                                    format_data(raw_data,
 | 
			
		||||
                                                '\t',
 | 
			
		||||
                                                ["X (en mm)",
 | 
			
		||||
                                                "Y (en mm)",
 | 
			
		||||
                                                "Z (en mm)",
 | 
			
		||||
                                                "teta (en rad)",
 | 
			
		||||
                                                "rayon (en mm)",
 | 
			
		||||
                                                "Xi-Xmoy",
 | 
			
		||||
                                                "Yi-Ymoy"] ))
 | 
			
		||||
 | 
			
		||||
        self.update_progress(10)
 | 
			
		||||
        save_output_file(f'{self.output_path}/{self.output_file_prefix}_delta_{self.delta_z}_analyse_rayon.txt',
 | 
			
		||||
                                    format_data(discrete_data,
 | 
			
		||||
                                            '\t',
 | 
			
		||||
                                            ["X moy (en mm)",
 | 
			
		||||
                                            "Y moy (en mm)",
 | 
			
		||||
                                            "Z moy (en mm)",
 | 
			
		||||
                                            "Delta z(en mm)",
 | 
			
		||||
                                            "Rayon moyen (en mm)",
 | 
			
		||||
                                            "Rayon ecart type (en mm)"] ))
 | 
			
		||||
        self.update_progress(100)
 | 
			
		||||
        self.set_status("Done !")
 | 
			
		||||
        self.finished.emit()
 | 
			
		||||
 | 
			
		||||
    def set_status(self, status:str):
 | 
			
		||||
        """
 | 
			
		||||
        Set the weight of the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.status.emit(status)
 | 
			
		||||
 | 
			
		||||
    def set_weight(self, weight):
 | 
			
		||||
        """
 | 
			
		||||
        Set the weight of the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.progress_weight = weight
 | 
			
		||||
 | 
			
		||||
    def update_progress(self, percent):
 | 
			
		||||
        """
 | 
			
		||||
        Update the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.progress_value += int(percent/100*self.progress_weight)
 | 
			
		||||
        self.progress.emit(self.progress_value)
 | 
			
		||||
							
								
								
									
										41
									
								
								utils/gui/pyqt/main_window/Workers/DiscreteDataWorker.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								utils/gui/pyqt/main_window/Workers/DiscreteDataWorker.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
from PyQt5.QtCore import pyqtSignal
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
from utils.files.output import save_output_file, format_data
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.Worker import Worker
 | 
			
		||||
from utils.data_processing.data_processing import get_discrete_data
 | 
			
		||||
 | 
			
		||||
class DiscreteDataProcessWorker(Worker):
 | 
			
		||||
    """
 | 
			
		||||
    Worker to run the analyse in a thread
 | 
			
		||||
    """
 | 
			
		||||
    processedData = pyqtSignal(dict)
 | 
			
		||||
 | 
			
		||||
    def __init__(self,name:str, obj:ScannedObject,output_path:str,output_file_prefix:str,delta_z:float):
 | 
			
		||||
        super().__init__(name)
 | 
			
		||||
        self.obj = obj
 | 
			
		||||
        self.delta_z = delta_z
 | 
			
		||||
        self.output_path = output_path
 | 
			
		||||
        self.output_file_prefix = output_file_prefix
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        """
 | 
			
		||||
        Run the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.set_status("Calculating discrete data...")
 | 
			
		||||
        discrete_data = get_discrete_data(self.obj, 6,self.delta_z,self.update_progress)
 | 
			
		||||
        self.processedData.emit(discrete_data)
 | 
			
		||||
        self.set_weight(100)
 | 
			
		||||
        self.set_status("Saving data...")
 | 
			
		||||
        self.update_progress(10)
 | 
			
		||||
        save_output_file(f'{self.output_path}/{self.output_file_prefix}_delta_{self.delta_z}_analyse_rayon.txt',
 | 
			
		||||
                                    format_data(discrete_data,
 | 
			
		||||
                                            '\t',
 | 
			
		||||
                                            ["X moy (en mm)",
 | 
			
		||||
                                            "Y moy (en mm)",
 | 
			
		||||
                                            "Z moy (en mm)",
 | 
			
		||||
                                            "Discretisation(en mm)",
 | 
			
		||||
                                            "Rayon moyen (en mm)",
 | 
			
		||||
                                            "Rayon ecart type (en mm)"] ))
 | 
			
		||||
        self.set_status("Done !")
 | 
			
		||||
        self.finished.emit()
 | 
			
		||||
							
								
								
									
										35
									
								
								utils/gui/pyqt/main_window/Workers/PreProcessWorker.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								utils/gui/pyqt/main_window/Workers/PreProcessWorker.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.Worker import Worker
 | 
			
		||||
from PyQt5.QtCore import pyqtSignal
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
from utils.math.position_manipulation import verticalise
 | 
			
		||||
 | 
			
		||||
class PreProcessWorker(Worker):
 | 
			
		||||
    """
 | 
			
		||||
    Worker to run the analyse in a thread
 | 
			
		||||
    """
 | 
			
		||||
    processed_obj = pyqtSignal(ScannedObject)
 | 
			
		||||
 | 
			
		||||
    def __init__(self,name:str, objpath:str):
 | 
			
		||||
        super().__init__(name)
 | 
			
		||||
        self.objpath = objpath
 | 
			
		||||
        self.progress_value = 0
 | 
			
		||||
        self.progress_weight = 100
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        """
 | 
			
		||||
        Run the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.set_status("Loading file...")
 | 
			
		||||
        obj = ScannedObject.from_obj_file(self.objpath)
 | 
			
		||||
        self.update_progress(5)
 | 
			
		||||
 | 
			
		||||
        self.set_status("Verticalising object...")
 | 
			
		||||
        verticalise(obj)
 | 
			
		||||
        self.update_progress(5)
 | 
			
		||||
 | 
			
		||||
        self.set_status("Normalising object...")
 | 
			
		||||
        obj.normalise()
 | 
			
		||||
        self.update_progress(5)
 | 
			
		||||
 | 
			
		||||
        self.processed_obj.emit(obj)
 | 
			
		||||
        self.finished.emit()
 | 
			
		||||
							
								
								
									
										40
									
								
								utils/gui/pyqt/main_window/Workers/RawDataWorker.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								utils/gui/pyqt/main_window/Workers/RawDataWorker.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
from PyQt5.QtCore import pyqtSignal
 | 
			
		||||
from utils.files.input import ScannedObject
 | 
			
		||||
from utils.files.output import save_output_file, format_data
 | 
			
		||||
from utils.gui.pyqt.main_window.Workers.Worker import Worker
 | 
			
		||||
from utils.data_processing.data_processing import get_raw_data
 | 
			
		||||
 | 
			
		||||
class RawDataProcessWorker(Worker):
 | 
			
		||||
    """
 | 
			
		||||
    Worker to run the analyse in a thread
 | 
			
		||||
    """
 | 
			
		||||
    processedData = pyqtSignal(dict)
 | 
			
		||||
 | 
			
		||||
    def __init__(self,name:str, obj:ScannedObject,output_path:str,output_file_prefix:str,delta_z:float):
 | 
			
		||||
        super().__init__(name)
 | 
			
		||||
        self.obj = obj
 | 
			
		||||
        self.delta_z = delta_z
 | 
			
		||||
        self.output_path = output_path
 | 
			
		||||
        self.output_file_prefix = output_file_prefix
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        """
 | 
			
		||||
        Run the analyse
 | 
			
		||||
        """
 | 
			
		||||
        self.set_status("Calculating raw data...")
 | 
			
		||||
        raw_data = get_raw_data(self.obj, 6,self.delta_z,self.update_progress)
 | 
			
		||||
        self.processedData.emit(raw_data)
 | 
			
		||||
        self.set_weight(100)
 | 
			
		||||
        self.set_status("Saving data...")
 | 
			
		||||
        save_output_file(f'{self.output_path}/{self.output_file_prefix}_delta_{self.delta_z}_analyse_brute.txt',
 | 
			
		||||
                                    format_data(raw_data,
 | 
			
		||||
                                                '\t',
 | 
			
		||||
                                                ["X (en mm)",
 | 
			
		||||
                                                "Y (en mm)",
 | 
			
		||||
                                                "Z (en mm)",
 | 
			
		||||
                                                "teta (en rad)",
 | 
			
		||||
                                                "rayon (en mm)",
 | 
			
		||||
                                                "Xi-Xmoy",
 | 
			
		||||
                                                "Yi-Ymoy"] ))
 | 
			
		||||
        self.set_status("Done !")
 | 
			
		||||
        self.finished.emit()
 | 
			
		||||
							
								
								
									
										31
									
								
								utils/gui/pyqt/main_window/Workers/Worker.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								utils/gui/pyqt/main_window/Workers/Worker.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
from PyQt5.QtCore import pyqtSignal, QObject
 | 
			
		||||
 | 
			
		||||
class Worker(QObject):
 | 
			
		||||
    finished = pyqtSignal()
 | 
			
		||||
    progress = pyqtSignal(int)
 | 
			
		||||
    status = pyqtSignal(str)
 | 
			
		||||
 | 
			
		||||
    def __init__(self,name:str):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.progress_value = 0
 | 
			
		||||
        self.progress_weight = 100
 | 
			
		||||
 | 
			
		||||
    def set_status(self, status:str):
 | 
			
		||||
        """
 | 
			
		||||
        Set the weight of the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.status.emit(f"[{self.name}]: {status}")
 | 
			
		||||
 | 
			
		||||
    def set_weight(self, weight):
 | 
			
		||||
        """
 | 
			
		||||
        Set the weight of the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.progress_weight = weight
 | 
			
		||||
 | 
			
		||||
    def update_progress(self, percent):
 | 
			
		||||
        """
 | 
			
		||||
        Update the progress bar
 | 
			
		||||
        """
 | 
			
		||||
        self.progress_value += int(percent/100*self.progress_weight)
 | 
			
		||||
        self.progress.emit(self.progress_value)
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user