added more docstrings
This commit is contained in:
parent
d2e3a43571
commit
d03d6500a0
7
app.py
7
app.py
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: app.py
|
||||||
|
@desc: Main file for the application
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
import sys
|
import sys
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
from utils.gui.pyqt.main_window.MainWindow import MainWindow
|
from utils.gui.pyqt.main_window.MainWindow import MainWindow
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Mon Apr 24 2023
|
||||||
|
@name: data_processing.py
|
||||||
|
@desc: A module to process the data
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from utils.math import data_extraction
|
from utils.math import data_extraction
|
||||||
from utils.files.input import ScannedObject
|
from utils.files.input import ScannedObject
|
||||||
from utils.settings.SettingManager import SettingManager
|
from utils.settings.SettingManager import SettingManager
|
||||||
@ -13,6 +20,8 @@ def get_raw_data(obj:ScannedObject, ndigits:int,delta_z:float=1,update_progress_
|
|||||||
|
|
||||||
:param obj: Object to analyse
|
:param obj: Object to analyse
|
||||||
:param ndigits: Number of digits to keep after the comma
|
:param ndigits: Number of digits to keep after the comma
|
||||||
|
:param delta_z: Delta z to use for the discretisation
|
||||||
|
:param update_progress_bar: Function to update the progress bar
|
||||||
:return: dict(str:list) with the following keys:
|
:return: dict(str:list) with the following keys:
|
||||||
- X (en mm) : list of x values
|
- X (en mm) : list of x values
|
||||||
- Y (en mm) : list of y values
|
- Y (en mm) : list of y values
|
||||||
@ -22,18 +31,24 @@ def get_raw_data(obj:ScannedObject, ndigits:int,delta_z:float=1,update_progress_
|
|||||||
- Xi-Xmoy : list of Xi-Xmoy values
|
- Xi-Xmoy : list of Xi-Xmoy values
|
||||||
- Yi-Ymoy : list of Yi-Ymoy values
|
- Yi-Ymoy : list of Yi-Ymoy values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Create the data dict
|
||||||
colones = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"]
|
colones = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"]
|
||||||
data = {}
|
data = {}
|
||||||
for colone in colones:
|
for colone in colones:
|
||||||
data[colone] = []
|
data[colone] = []
|
||||||
|
|
||||||
|
# Select the discretisation method from the settings
|
||||||
if SettingManager.get_instance().get_setting("discretisation_method") == "Z0-Zi < DeltaZ":
|
if SettingManager.get_instance().get_setting("discretisation_method") == "Z0-Zi < DeltaZ":
|
||||||
get_discrete_vertices = obj.get_discrete_vertices
|
get_discrete_vertices = obj.get_discrete_vertices
|
||||||
else:
|
else:
|
||||||
get_discrete_vertices = obj.get_discrete_vertices3
|
get_discrete_vertices = obj.get_discrete_vertices3
|
||||||
|
|
||||||
|
# Get the discrete vertices
|
||||||
discrete_vertices = get_discrete_vertices(delta_z)
|
discrete_vertices = get_discrete_vertices(delta_z)
|
||||||
progress = 0
|
progress = 0
|
||||||
|
|
||||||
|
# Calculate the data for each discrete vertex
|
||||||
for discrete_values in discrete_vertices:
|
for discrete_values in discrete_vertices:
|
||||||
mean_x ,mean_y, mean_z = data_extraction.get_x_y_z_mean(discrete_values)
|
mean_x ,mean_y, mean_z = data_extraction.get_x_y_z_mean(discrete_values)
|
||||||
for x,y,z in discrete_values:
|
for x,y,z in discrete_values:
|
||||||
@ -54,6 +69,8 @@ def get_discrete_data(obj:ScannedObject, ndigits:int, delta_z:float=1, update_pr
|
|||||||
|
|
||||||
:param obj: Object to analyse
|
:param obj: Object to analyse
|
||||||
:param ndigits: Number of digits to keep after the comma
|
:param ndigits: Number of digits to keep after the comma
|
||||||
|
:param delta_z: Delta z to use for the discretisation
|
||||||
|
:param update_progress_bar: Function to update the progress bar
|
||||||
:return: dict(str:list) with the following keys:
|
:return: dict(str:list) with the following keys:
|
||||||
- X moy (en mm) : list of x mean values
|
- X moy (en mm) : list of x mean values
|
||||||
- Y moy (en mm) : list of y mean values
|
- Y moy (en mm) : list of y mean values
|
||||||
@ -61,15 +78,19 @@ def get_discrete_data(obj:ScannedObject, ndigits:int, delta_z:float=1, update_pr
|
|||||||
- Rayon moyen (en mm) : list of mean radius values
|
- Rayon moyen (en mm) : list of mean radius values
|
||||||
- Rayon ecart type (en mm) : list of radius standard deviation values
|
- Rayon ecart type (en mm) : list of radius standard deviation values
|
||||||
"""
|
"""
|
||||||
|
# Create the data dict
|
||||||
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)"]
|
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 = {}
|
data = {}
|
||||||
for colone in colones:
|
for colone in colones:
|
||||||
data[colone] = []
|
data[colone] = []
|
||||||
|
|
||||||
|
# Select the discretisation method from the settings
|
||||||
if SettingManager.get_instance().get_setting("discretisation_method") == "Z0-Zi < DeltaZ":
|
if SettingManager.get_instance().get_setting("discretisation_method") == "Z0-Zi < DeltaZ":
|
||||||
get_discrete_vertices = obj.get_discrete_vertices
|
get_discrete_vertices = obj.get_discrete_vertices
|
||||||
else:
|
else:
|
||||||
get_discrete_vertices = obj.get_discrete_vertices3
|
get_discrete_vertices = obj.get_discrete_vertices3
|
||||||
|
|
||||||
|
# Get the discrete vertices
|
||||||
discrete_vertices = get_discrete_vertices(delta_z)
|
discrete_vertices = get_discrete_vertices(delta_z)
|
||||||
progress = 0
|
progress = 0
|
||||||
for discrete_values in discrete_vertices:
|
for discrete_values in discrete_vertices:
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
This module contains the functions to parse the input files, and create a ScannedObject.
|
Created on Thu Apr 20 2023
|
||||||
|
@name: input.py
|
||||||
|
@desc: This module contains the functions to parse the input files, and create a ScannedObject.
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
"""
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from utils.files.output import save_output_file
|
from utils.files.output import save_output_file
|
||||||
@ -64,15 +68,12 @@ class ScannedObject:
|
|||||||
[(0, 1, 2), (0, 2, 3), (4, 5, 6), (4, 6, 7), (0, 1, 5), (0, 4, 5), (1, 2, 6), (1, 5, 6), (2, 3, 7), (2, 6, 7), (3, 0, 4), (3, 7, 4)]
|
[(0, 1, 2), (0, 2, 3), (4, 5, 6), (4, 6, 7), (0, 1, 5), (0, 4, 5), (1, 2, 6), (1, 5, 6), (2, 3, 7), (2, 6, 7), (3, 0, 4), (3, 7, 4)]
|
||||||
>>> obj.get_discrete_vertices()
|
>>> obj.get_discrete_vertices()
|
||||||
[[(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)]],[ (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)]]
|
[[(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)]],[ (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)]]
|
||||||
#TODO Add and test exemples
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, vertices, faces=None, result_file_path=None):
|
def __init__(self, vertices, faces=None, result_file_path=None):
|
||||||
self.vertices = np.asarray(vertices)
|
self.vertices = np.asarray(vertices)
|
||||||
self.faces = np.asarray(faces)
|
self.faces = np.asarray(faces)
|
||||||
# Deprecated
|
self.result_file_path = result_file_path # Deprecated
|
||||||
self.result_file_path = result_file_path
|
self.bruteforce_discretization_result = None # Deprecated
|
||||||
self.bruteforce_discretization_result = None
|
|
||||||
#
|
|
||||||
self.x = np.asarray([vertex[0] for vertex in vertices])
|
self.x = np.asarray([vertex[0] for vertex in vertices])
|
||||||
self.y = np.asarray([vertex[1] for vertex in vertices])
|
self.y = np.asarray([vertex[1] for vertex in vertices])
|
||||||
self.z = np.asarray([vertex[2] for vertex in vertices])
|
self.z = np.asarray([vertex[2] for vertex in vertices])
|
||||||
@ -95,6 +96,7 @@ class ScannedObject:
|
|||||||
data = f.readlines()
|
data = f.readlines()
|
||||||
for line in data :
|
for line in data :
|
||||||
if line.startswith('f'):
|
if line.startswith('f'):
|
||||||
|
# Ignore the normals and textures
|
||||||
if "//" in line:
|
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])
|
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:
|
elif "/" in line:
|
||||||
@ -179,19 +181,22 @@ class ScannedObject:
|
|||||||
"""
|
"""
|
||||||
return self.z
|
return self.z
|
||||||
|
|
||||||
def get_vertices(self, sort:bool = False):
|
def get_vertices(self, sort:bool = False)->list:
|
||||||
"""
|
"""
|
||||||
Get the vertices of the object.
|
Get the vertices of the object.
|
||||||
:param sort: Sort the vertices by z coordinate
|
:param sort: Sort the vertices by z coordinate
|
||||||
|
|
||||||
:return: vertices
|
:return: vertices
|
||||||
"""
|
"""
|
||||||
|
|
||||||
vertices = self.vertices if not sort else sorted(self.vertices, key=lambda vertex: vertex[2])
|
vertices = self.vertices if not sort else sorted(self.vertices, key=lambda vertex: vertex[2])
|
||||||
return vertices
|
return vertices
|
||||||
|
|
||||||
def get_discrete_vertices(self, step:float = 1):
|
def get_discrete_vertices(self, step:float = 1)->list:
|
||||||
"""
|
"""
|
||||||
Discretize the vertices of the object.
|
Discretize the vertices of the object using a split method.
|
||||||
|
This implementation will split the object at every step interval.
|
||||||
|
|
||||||
:param step: Step of the discretization
|
:param step: Step of the discretization
|
||||||
:return: Discretized vertices
|
:return: Discretized vertices
|
||||||
"""
|
"""
|
||||||
@ -219,24 +224,30 @@ class ScannedObject:
|
|||||||
L.append([])
|
L.append([])
|
||||||
return L
|
return L
|
||||||
|
|
||||||
def get_discrete_vertices3(self, step:float = 1):
|
def get_discrete_vertices3(self, step:float = 1)->list:
|
||||||
"""
|
"""
|
||||||
Deprecated
|
Discretize the vertices of the object using a lenght method.
|
||||||
|
This implementation will split the object when difference between the
|
||||||
|
first and last point of a slice is greater or equal then the step interval.
|
||||||
|
|
||||||
|
:param step: Step of the discretization
|
||||||
|
:return: Discretized vertices
|
||||||
"""
|
"""
|
||||||
cpt = 0
|
cpt = 0
|
||||||
L = [[]]
|
L = [[]]
|
||||||
z = min(self.get_z())
|
z = min(self.get_z())
|
||||||
sorted = self.get_vertices(sort=True)
|
sorted_vertices = self.get_vertices(sort=True)
|
||||||
for index in range(len(sorted)):
|
for index,_ in enumerate(sorted_vertices):
|
||||||
L[-1].append(sorted[index])
|
L[-1].append(sorted_vertices[index])
|
||||||
if sorted[index][2] - z > step:
|
if sorted_vertices[index][2] - z > step:
|
||||||
z = sorted[index+1][2]
|
z = sorted_vertices[index+1][2]
|
||||||
L.append([])
|
L.append([])
|
||||||
return L
|
return L
|
||||||
|
|
||||||
def get_faces(self,resolved:bool = False)->list:
|
def get_faces(self,resolved:bool = False)->list:
|
||||||
"""
|
"""
|
||||||
Get the faces of the object.
|
Get the faces of the object.
|
||||||
|
|
||||||
:return: faces
|
:return: faces
|
||||||
"""
|
"""
|
||||||
if self.faces is None:
|
if self.faces is None:
|
||||||
@ -248,6 +259,7 @@ class ScannedObject:
|
|||||||
def update_from_faces(self,faces:list):
|
def update_from_faces(self,faces:list):
|
||||||
"""
|
"""
|
||||||
Update the object from the faces.
|
Update the object from the faces.
|
||||||
|
|
||||||
:param faces: Faces to update the object from
|
:param faces: Faces to update the object from
|
||||||
"""
|
"""
|
||||||
cpt = 0
|
cpt = 0
|
||||||
@ -274,6 +286,7 @@ class ScannedObject:
|
|||||||
def normalise(self, axis:str = 'z'):
|
def normalise(self, axis:str = 'z'):
|
||||||
"""
|
"""
|
||||||
Normalise the object.
|
Normalise the object.
|
||||||
|
|
||||||
:param axis: Axis to normalise
|
:param axis: Axis to normalise
|
||||||
"""
|
"""
|
||||||
if 'x' in axis:
|
if 'x' in axis:
|
||||||
@ -287,6 +300,7 @@ class ScannedObject:
|
|||||||
def get_data(self)->dict:
|
def get_data(self)->dict:
|
||||||
"""
|
"""
|
||||||
Get the data of the object.
|
Get the data of the object.
|
||||||
|
|
||||||
:return: Data of the object
|
:return: Data of the object
|
||||||
"""
|
"""
|
||||||
return {'verticies': self.vertices, 'faces': self.faces, 'x': self.x, 'y': self.y, 'z': self.z}
|
return {'verticies': self.vertices, 'faces': self.faces, 'x': self.x, 'y': self.y, 'z': self.z}
|
||||||
@ -329,6 +343,7 @@ class ScannedObject:
|
|||||||
def export_xyz(self, file_path:str,separator:str="\t"):
|
def export_xyz(self, file_path:str,separator:str="\t"):
|
||||||
"""
|
"""
|
||||||
Export the object in a file.
|
Export the object in a file.
|
||||||
|
|
||||||
:param file_path: Path of the file
|
:param file_path: Path of the file
|
||||||
:param separator: chars used to separate the values
|
:param separator: chars used to separate the values
|
||||||
"""
|
"""
|
||||||
@ -344,6 +359,7 @@ class ScannedObject:
|
|||||||
def export_obj(self,file_path):
|
def export_obj(self,file_path):
|
||||||
"""
|
"""
|
||||||
Export the object in a file.
|
Export the object in a file.
|
||||||
|
|
||||||
:param file_path: Path of the file
|
:param file_path: Path of the file
|
||||||
"""
|
"""
|
||||||
string = ''
|
string = ''
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
Deprecated
|
Created on Fri Apr 14 2023
|
||||||
|
@name: input.py
|
||||||
|
@desc: x,y,z input cleaning (Deprecated)
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def denormalizeXYZ(filePath:str, output:str):
|
def denormalizeXYZ(filePath:str, output:str):
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
This module is used to manage the output files of the program.
|
Created on Mon Apr 17 2023
|
||||||
|
@name: output.py
|
||||||
|
@desc: Output file formatting and saving
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from utils.settings.SettingManager import SettingManager
|
from utils.settings.SettingManager import SettingManager
|
||||||
@ -10,7 +14,7 @@ def format_data(data:dict, separator:str, selected_columns:list = None) -> str:
|
|||||||
Format the data to be saved in the output file.
|
Format the data to be saved in the output file.
|
||||||
|
|
||||||
:param data: Data to be formatted
|
:param data: Data to be formatted
|
||||||
:param selected_columns: Columns to be saved
|
:param selected_columns: Columns to be saved (in the specified order)
|
||||||
:param separator: Separator of the columns
|
:param separator: Separator of the columns
|
||||||
:return: Formatted data
|
:return: Formatted data
|
||||||
|
|
||||||
@ -27,19 +31,24 @@ def format_data(data:dict, separator:str, selected_columns:list = None) -> str:
|
|||||||
3 ;6 ;9
|
3 ;6 ;9
|
||||||
'
|
'
|
||||||
"""
|
"""
|
||||||
isPrettier = SettingManager.get_instance().get_setting('pretiffy_output_file')
|
# Get the setting for the output file
|
||||||
|
is_prettier = SettingManager.get_instance().get_setting('pretiffy_output_file')
|
||||||
output = ''
|
output = ''
|
||||||
|
# If the columns are not specified, we take all the columns from dict
|
||||||
if selected_columns is None:
|
if selected_columns is None:
|
||||||
selected_columns = list(data.keys())
|
selected_columns = list(data.keys())
|
||||||
|
|
||||||
|
# Write the columns headers
|
||||||
for column_name in selected_columns:
|
for column_name in selected_columns:
|
||||||
if isPrettier:
|
if is_prettier:
|
||||||
output += column_name.ljust(len(column_name) if len(column_name) > 8 else 9 ) + separator
|
output += column_name.ljust(len(column_name) if len(column_name) > 8 else 9 ) + separator
|
||||||
else:
|
else:
|
||||||
output += column_name + separator
|
output += column_name + separator
|
||||||
output += '\n'
|
output += '\n'
|
||||||
|
# Write the columns values
|
||||||
for i in range(len(data[selected_columns[0]])):
|
for i in range(len(data[selected_columns[0]])):
|
||||||
for column in selected_columns:
|
for column in selected_columns:
|
||||||
if isPrettier:
|
if is_prettier:
|
||||||
output += str(data[column][i]).ljust(len(column) if len(column) > 8 else 9 ) + separator
|
output += str(data[column][i]).ljust(len(column) if len(column) > 8 else 9 ) + separator
|
||||||
else:
|
else:
|
||||||
output += str(data[column][i]) + separator
|
output += str(data[column][i]) + separator
|
||||||
|
|||||||
@ -1,8 +1,17 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: mpl_render.py
|
||||||
|
@desc: A module to render a 2D data using matplotlib
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
def render2D(values:list):
|
def render2D(values:list):
|
||||||
"""
|
"""
|
||||||
Render a 2D model using matplotlib
|
Render a 2D model using matplotlib
|
||||||
|
|
||||||
:param values: A list with the values
|
:param values: A list with the values
|
||||||
"""
|
"""
|
||||||
fig = plt.figure()
|
fig = plt.figure()
|
||||||
@ -13,6 +22,7 @@ def render2D(values:list):
|
|||||||
def cross_section(x_values:list, y_values:list):
|
def cross_section(x_values:list, y_values:list):
|
||||||
"""
|
"""
|
||||||
Render a 2D cross section using matplotlib
|
Render a 2D cross section using matplotlib
|
||||||
|
|
||||||
:param x: A list with the x values
|
:param x: A list with the x values
|
||||||
:param y: A list with the y values
|
:param y: A list with the y values
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,10 +1,22 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: visplot_render.py
|
||||||
|
@desc: A module to render a 2D data using vispy
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
import vispy.plot as vp
|
import vispy.plot as vp
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
def render2D(values:list,title:str,xlabel="",ylabel="",show:bool=True):
|
def render2D(values:list,title:str,xlabel="",ylabel="",show:bool=True)->vp.Fig|None:
|
||||||
"""
|
"""
|
||||||
Render a 2D plot using vispy
|
Render a 2D plot using vispy
|
||||||
|
|
||||||
:param values: A list with the values
|
:param values: A list with the values
|
||||||
|
:param title: Title of the plot
|
||||||
|
:param xlabel: Label of the x axis
|
||||||
|
:param ylabel: Label of the y axis
|
||||||
|
:param show: If True, show the plot, else return the canvas
|
||||||
"""
|
"""
|
||||||
fig = vp.Fig(size=(600, 500), show=False)
|
fig = vp.Fig(size=(600, 500), show=False)
|
||||||
plotwidget = fig[0, 0]
|
plotwidget = fig[0, 0]
|
||||||
@ -20,11 +32,16 @@ def render2D(values:list,title:str,xlabel="",ylabel="",show:bool=True):
|
|||||||
else:
|
else:
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
def cross_section(x_values:list, y_values:list,title:str,xlabel="",ylabel="",show:bool=True ):
|
def cross_section(x_values:list, y_values:list,title:str,xlabel="",ylabel="",show:bool=True)->vp.Fig|None:
|
||||||
"""
|
"""
|
||||||
Render a 2D cross section using vispy
|
Render a 2D cross section using vispy
|
||||||
|
|
||||||
:param x: A list with the x values
|
:param x: A list with the x values
|
||||||
:param y: A list with the y values
|
:param y: A list with the y values
|
||||||
|
:param title: Title of the plot
|
||||||
|
:param xlabel: Label of the x axis
|
||||||
|
:param ylabel: Label of the y axis
|
||||||
|
:param show: If True, show the plot, else return the canvas
|
||||||
"""
|
"""
|
||||||
color = (0.3, 0.5, 0.8,.8)
|
color = (0.3, 0.5, 0.8,.8)
|
||||||
fig = vp.Fig(show=False)
|
fig = vp.Fig(show=False)
|
||||||
|
|||||||
@ -1,3 +1,11 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: mpl_render.py
|
||||||
|
@desc: A module to render a 3D data using matplotlib
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
|
|
||||||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -6,6 +14,7 @@ from utils.files.input import ScannedObject
|
|||||||
def render3D(obj:ScannedObject):
|
def render3D(obj:ScannedObject):
|
||||||
"""
|
"""
|
||||||
Render a 3D model using matplotlib's Poly3dcollection
|
Render a 3D model using matplotlib's Poly3dcollection
|
||||||
|
|
||||||
:param obj: A ScannedObject to be rendered
|
:param obj: A ScannedObject to be rendered
|
||||||
"""
|
"""
|
||||||
fig = plt.figure()
|
fig = plt.figure()
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: visplot_render.py
|
||||||
|
@desc: A module to render a 3D data using vispy
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from vispy import app, scene
|
from vispy import app, scene
|
||||||
from vispy.scene.visuals import Mesh
|
from vispy.scene.visuals import Mesh
|
||||||
@ -5,20 +12,27 @@ from vispy.visuals.filters import ShadingFilter, WireframeFilter
|
|||||||
from utils.files.input import ScannedObject
|
from utils.files.input import ScannedObject
|
||||||
|
|
||||||
|
|
||||||
def render3D(obj:ScannedObject,show:bool=True):
|
def render3D(obj:ScannedObject,show:bool=True)->scene.SceneCanvas|None:
|
||||||
"""
|
"""
|
||||||
Render a 3D model using vispy
|
Render a 3D model mesh using vispy
|
||||||
|
|
||||||
:param obj: A ScannedObject to be rendered
|
:param obj: A ScannedObject to be rendered
|
||||||
|
:param show: If True, show the plot, else return the canvas
|
||||||
|
:return: A canvas with the rendered object
|
||||||
"""
|
"""
|
||||||
|
# Extract the vertices and faces from the object
|
||||||
vertices = np.asarray(obj.get_vertices())
|
vertices = np.asarray(obj.get_vertices())
|
||||||
faces = np.asarray(obj.get_faces())
|
faces = np.asarray(obj.get_faces())
|
||||||
|
# Create the canvas
|
||||||
canvas = scene.SceneCanvas(keys='interactive', bgcolor='white')
|
canvas = scene.SceneCanvas(keys='interactive', bgcolor='white')
|
||||||
|
# Create a viewbox to display the mesh in
|
||||||
view = canvas.central_widget.add_view()
|
view = canvas.central_widget.add_view()
|
||||||
view.camera = 'arcball'
|
view.camera = 'arcball'
|
||||||
view.camera.depth_value = 1e3
|
view.camera.depth_value = 1e3
|
||||||
color = (0.3, 0.5, 0.8)
|
color = (0.3, 0.5, 0.8)
|
||||||
mesh = Mesh(vertices, faces, color=color)
|
mesh = Mesh(vertices, faces, color=color)
|
||||||
view.add(mesh)
|
view.add(mesh)
|
||||||
|
# Add filters to the mesh
|
||||||
wireframe_filter = WireframeFilter(width=0)
|
wireframe_filter = WireframeFilter(width=0)
|
||||||
shading_filter = ShadingFilter(shininess=0)
|
shading_filter = ShadingFilter(shininess=0)
|
||||||
mesh.attach(wireframe_filter)
|
mesh.attach(wireframe_filter)
|
||||||
|
|||||||
@ -1,7 +1,28 @@
|
|||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
"""
|
||||||
|
Created on Wed Apr 28 2023
|
||||||
|
@name: ErrorPopup.py
|
||||||
|
@desc: A class to show a popup with an error message
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
|
|
||||||
class ErrorPopup(object):
|
class ErrorPopup(object):
|
||||||
|
"""
|
||||||
|
A class to show a popup with an error message
|
||||||
|
|
||||||
|
:param error_text: The error message
|
||||||
|
:param details: The details of the error
|
||||||
|
:param button_label: The label of the button
|
||||||
|
:param button_callback: The callback of the button
|
||||||
|
|
||||||
|
:ivar error_text: The error message
|
||||||
|
:ivar details: The details of the error
|
||||||
|
:ivar button_label: The label of the button
|
||||||
|
:ivar button_callback: The callback of the button
|
||||||
|
|
||||||
|
:method show_popup: Show the popup
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self,error_text,details = None,button_label = None,button_callback=None):
|
def __init__(self,error_text,details = None,button_label = None,button_callback=None):
|
||||||
self.error_text = error_text
|
self.error_text = error_text
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Mon Apr 24 2023
|
||||||
|
@name: MainWindow.py
|
||||||
|
@desc: Main window of the application
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
from PyQt5 import QtWidgets
|
from PyQt5 import QtWidgets
|
||||||
from PyQt5.QtCore import QThread
|
from PyQt5.QtCore import QThread
|
||||||
@ -14,7 +21,8 @@ from utils.gui.pyqt.main_window.Workers.RawDataWorker import RawDataProcessWorke
|
|||||||
from utils.gui.pyqt.error_popup.ErrorPopup import ErrorPopup
|
from utils.gui.pyqt.error_popup.ErrorPopup import ErrorPopup
|
||||||
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||||
"""
|
"""
|
||||||
Main window of the application
|
Main window of the application, it contains all the UI elements
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -133,7 +141,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def start_preprocess(self):
|
def start_preprocess(self):
|
||||||
"""
|
"""
|
||||||
Start the analyse
|
Start the analyse, create the thread and connect the signals.
|
||||||
"""
|
"""
|
||||||
if not self.check_input_file():
|
if not self.check_input_file():
|
||||||
return
|
return
|
||||||
@ -171,6 +179,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.start_analyse_button.setEnabled(False)
|
self.start_analyse_button.setEnabled(False)
|
||||||
|
|
||||||
def process_raw_data(self, obj:ScannedObject):
|
def process_raw_data(self, obj:ScannedObject):
|
||||||
|
"""
|
||||||
|
Start the analyse, create the thread and connect the signals.
|
||||||
|
"""
|
||||||
self.processrawdata_thread = QThread()
|
self.processrawdata_thread = QThread()
|
||||||
self.processraw_worker = RawDataProcessWorker("RawDataProcessWorker",
|
self.processraw_worker = RawDataProcessWorker("RawDataProcessWorker",
|
||||||
obj,
|
obj,
|
||||||
@ -195,6 +206,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.processrawdata_thread.start()
|
self.processrawdata_thread.start()
|
||||||
|
|
||||||
def process_discrete_data(self, obj:ScannedObject):
|
def process_discrete_data(self, obj:ScannedObject):
|
||||||
|
"""
|
||||||
|
Start the analyse, create the thread and connect the signals.
|
||||||
|
"""
|
||||||
self.processdiscrete_thread = QThread()
|
self.processdiscrete_thread = QThread()
|
||||||
self.processdiscrete_worker = DiscreteDataProcessWorker("DiscreteDataProcessWorker",
|
self.processdiscrete_worker = DiscreteDataProcessWorker("DiscreteDataProcessWorker",
|
||||||
obj,
|
obj,
|
||||||
@ -219,15 +233,27 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.processdiscrete_thread.start()
|
self.processdiscrete_thread.start()
|
||||||
|
|
||||||
def set_obj(self,obj:ScannedObject):
|
def set_obj(self,obj:ScannedObject):
|
||||||
|
"""
|
||||||
|
Set the obj to the main window
|
||||||
|
"""
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
|
|
||||||
def set_discrete_data(self,discrete_data:dict):
|
def set_discrete_data(self,discrete_data:dict):
|
||||||
|
"""
|
||||||
|
Set the discrete data to the main window
|
||||||
|
"""
|
||||||
self.discrete_data = discrete_data
|
self.discrete_data = discrete_data
|
||||||
|
|
||||||
def set_raw_data(self,raw_data:dict):
|
def set_raw_data(self,raw_data:dict):
|
||||||
|
"""
|
||||||
|
Set the raw data to the main window
|
||||||
|
"""
|
||||||
self.raw_data = raw_data
|
self.raw_data = raw_data
|
||||||
|
|
||||||
def save_model(self):
|
def save_model(self):
|
||||||
|
"""
|
||||||
|
Save the model to a file
|
||||||
|
"""
|
||||||
if self.obj is None:
|
if self.obj is None:
|
||||||
ErrorPopup("Aucune analyse effectuée. Aucun modèle à sauvegarder").show_popup()
|
ErrorPopup("Aucune analyse effectuée. Aucun modèle à sauvegarder").show_popup()
|
||||||
return
|
return
|
||||||
@ -255,6 +281,13 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.Graphs.hide()
|
self.Graphs.hide()
|
||||||
|
|
||||||
def renderGraphs(self,obj:ScannedObject,raw_data:dict,discrete_data:dict):
|
def renderGraphs(self,obj:ScannedObject,raw_data:dict,discrete_data:dict):
|
||||||
|
"""
|
||||||
|
Render the graphs
|
||||||
|
|
||||||
|
:param obj: The scanned object
|
||||||
|
:param raw_data: The raw data
|
||||||
|
:param discrete_data: The discrete data
|
||||||
|
"""
|
||||||
if not self.show_graph_checkbox.isChecked():
|
if not self.show_graph_checkbox.isChecked():
|
||||||
return
|
return
|
||||||
for slot in self.slots:
|
for slot in self.slots:
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Wed Apr 26 2023
|
||||||
|
@name: DiscreteDataWorker.py
|
||||||
|
@desc: A module to process discrete data in a thread
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
from utils.files.input import ScannedObject
|
from utils.files.input import ScannedObject
|
||||||
from utils.files.output import save_output_file, format_data
|
from utils.files.output import save_output_file, format_data
|
||||||
@ -7,7 +14,19 @@ from utils.settings.SettingManager import SettingManager
|
|||||||
|
|
||||||
class DiscreteDataProcessWorker(Worker):
|
class DiscreteDataProcessWorker(Worker):
|
||||||
"""
|
"""
|
||||||
Worker to run the analyse in a thread
|
Worker to calculate the discrete data in a thread
|
||||||
|
|
||||||
|
:param name: The name of the worker
|
||||||
|
:param obj: The scanned object
|
||||||
|
:param output_path: The path to save the output file
|
||||||
|
:param output_file_prefix: The prefix of the output file
|
||||||
|
:param delta_z: The delta z
|
||||||
|
|
||||||
|
:ivar obj: The scanned object
|
||||||
|
:ivar delta_z: The delta z
|
||||||
|
:ivar output_path: The path to save the output file
|
||||||
|
:ivar output_file_prefix: The prefix of the output file
|
||||||
|
:ivar processedData: The signal to emit the result
|
||||||
"""
|
"""
|
||||||
processedData = pyqtSignal(dict)
|
processedData = pyqtSignal(dict)
|
||||||
|
|
||||||
@ -24,11 +43,14 @@ class DiscreteDataProcessWorker(Worker):
|
|||||||
Run the analyse
|
Run the analyse
|
||||||
"""
|
"""
|
||||||
self.set_status("Calculating discrete data...")
|
self.set_status("Calculating discrete data...")
|
||||||
|
# Execute the analyse
|
||||||
discrete_data = get_discrete_data(self.obj, 6,self.delta_z,self.update_progress)
|
discrete_data = get_discrete_data(self.obj, 6,self.delta_z,self.update_progress)
|
||||||
|
# Emit the result
|
||||||
self.processedData.emit(discrete_data)
|
self.processedData.emit(discrete_data)
|
||||||
self.set_weight(100)
|
self.set_weight(100)
|
||||||
self.set_status("Saving data...")
|
self.set_status("Saving data...")
|
||||||
self.update_progress(10)
|
self.update_progress(10)
|
||||||
|
# Save the result
|
||||||
suffix = SettingManager.get_instance().get_setting('discrete_data_suffix').replace('{delta_z}',str(self.delta_z))
|
suffix = SettingManager.get_instance().get_setting('discrete_data_suffix').replace('{delta_z}',str(self.delta_z))
|
||||||
extension = SettingManager.get_instance().get_setting('output_file_extension')
|
extension = SettingManager.get_instance().get_setting('output_file_extension')
|
||||||
separator = SettingManager.get_instance().get_setting('output_file_separator')
|
separator = SettingManager.get_instance().get_setting('output_file_separator')
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Wed Apr 26 2023
|
||||||
|
@name: PreProcessWorker.py
|
||||||
|
@desc: A module to pre process the 3d object in a thread
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from utils.gui.pyqt.main_window.Workers.Worker import Worker
|
from utils.gui.pyqt.main_window.Workers.Worker import Worker
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
from utils.files.input import ScannedObject
|
from utils.files.input import ScannedObject
|
||||||
@ -5,7 +12,17 @@ from utils.math.position_manipulation import verticalise
|
|||||||
|
|
||||||
class PreProcessWorker(Worker):
|
class PreProcessWorker(Worker):
|
||||||
"""
|
"""
|
||||||
Worker to run the analyse in a thread
|
Worker to pre process the 3d object in a thread
|
||||||
|
|
||||||
|
:param name: The name of the worker
|
||||||
|
:param objpath: The path to the 3d object
|
||||||
|
|
||||||
|
:ivar objpath: The path to the 3d object
|
||||||
|
:ivar progress_value: The current progress value
|
||||||
|
:ivar progress_weight: The weight of the progress bar
|
||||||
|
:ivar processed_obj: The signal to emit the processed object
|
||||||
|
|
||||||
|
:method run: Pre process the object, read the file, verticalise it and normalise it
|
||||||
"""
|
"""
|
||||||
processed_obj = pyqtSignal(ScannedObject)
|
processed_obj = pyqtSignal(ScannedObject)
|
||||||
|
|
||||||
@ -17,19 +34,24 @@ class PreProcessWorker(Worker):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""
|
"""
|
||||||
Run the analyse
|
Pre process the object, read the file, verticalise it and normalise it
|
||||||
|
Emit the processed object in the processed_obj signal
|
||||||
"""
|
"""
|
||||||
|
# Read the file
|
||||||
self.set_status("Loading file...")
|
self.set_status("Loading file...")
|
||||||
obj = ScannedObject.from_obj_file(self.objpath)
|
obj = ScannedObject.from_obj_file(self.objpath)
|
||||||
self.update_progress(5)
|
self.update_progress(5)
|
||||||
|
|
||||||
|
# Verticalise the object
|
||||||
self.set_status("Verticalising object...")
|
self.set_status("Verticalising object...")
|
||||||
verticalise(obj)
|
verticalise(obj)
|
||||||
self.update_progress(5)
|
self.update_progress(5)
|
||||||
|
|
||||||
|
# Normalise the object
|
||||||
self.set_status("Normalising object...")
|
self.set_status("Normalising object...")
|
||||||
obj.normalise()
|
obj.normalise()
|
||||||
self.update_progress(5)
|
self.update_progress(5)
|
||||||
|
|
||||||
|
# Emit the processed object
|
||||||
self.processed_obj.emit(obj)
|
self.processed_obj.emit(obj)
|
||||||
self.finished.emit()
|
self.finished.emit()
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Wed Apr 26 2023
|
||||||
|
@name: RawDataWorker.py
|
||||||
|
@desc: A module to process the raw data in a thread
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
from utils.files.input import ScannedObject
|
from utils.files.input import ScannedObject
|
||||||
from utils.files.output import save_output_file, format_data
|
from utils.files.output import save_output_file, format_data
|
||||||
@ -7,7 +14,19 @@ from utils.settings.SettingManager import SettingManager
|
|||||||
|
|
||||||
class RawDataProcessWorker(Worker):
|
class RawDataProcessWorker(Worker):
|
||||||
"""
|
"""
|
||||||
Worker to run the analyse in a thread
|
Worker to calculate the raw data in a thread
|
||||||
|
|
||||||
|
:param name: The name of the worker
|
||||||
|
:param obj: The scanned object
|
||||||
|
:param output_path: The path to save the output file
|
||||||
|
:param output_file_prefix: The prefix of the output file
|
||||||
|
:param delta_z: The delta z
|
||||||
|
|
||||||
|
:ivar obj: The scanned object
|
||||||
|
:ivar delta_z: The delta z
|
||||||
|
:ivar output_path: The path to save the output file
|
||||||
|
:ivar output_file_prefix: The prefix of the output file
|
||||||
|
:ivar processedData: The signal to emit the result
|
||||||
"""
|
"""
|
||||||
processedData = pyqtSignal(dict)
|
processedData = pyqtSignal(dict)
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,25 @@
|
|||||||
|
"""
|
||||||
|
Created on Wed Apr 26 2023
|
||||||
|
@name: Worker.py
|
||||||
|
@desc: Base class for the workers
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from PyQt5.QtCore import pyqtSignal, QObject
|
from PyQt5.QtCore import pyqtSignal, QObject
|
||||||
|
|
||||||
class Worker(QObject):
|
class Worker(QObject):
|
||||||
|
"""
|
||||||
|
Base class for the workers
|
||||||
|
|
||||||
|
:param name: The name of the worker
|
||||||
|
|
||||||
|
:ivar name: The name of the worker
|
||||||
|
:ivar progress_value: The current progress value
|
||||||
|
:ivar progress_weight: The weight of the progress bar
|
||||||
|
:ivar finished: The signal to emit when the worker is finished
|
||||||
|
:ivar progress: The signal to emit the progress value
|
||||||
|
:ivar status: The signal to emit the status of the worker
|
||||||
|
"""
|
||||||
finished = pyqtSignal()
|
finished = pyqtSignal()
|
||||||
progress = pyqtSignal(int)
|
progress = pyqtSignal(int)
|
||||||
status = pyqtSignal(str)
|
status = pyqtSignal(str)
|
||||||
|
|||||||
@ -1,11 +1,19 @@
|
|||||||
|
"""
|
||||||
|
Created on Thu Apr 27 2023
|
||||||
|
@name: Settings.py
|
||||||
|
@desc: Settings window
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
from PyQt5 import QtWidgets
|
from PyQt5 import QtWidgets
|
||||||
from PyQt5.QtWidgets import QWidget
|
|
||||||
from utils.files.input import ScannedObject
|
|
||||||
from utils.gui.pyqt.settings.UI_Settings import Ui_Settings
|
from utils.gui.pyqt.settings.UI_Settings import Ui_Settings
|
||||||
from utils.settings.SettingManager import SettingManager
|
from utils.settings.SettingManager import SettingManager
|
||||||
|
|
||||||
class Settings(QtWidgets.QMainWindow,Ui_Settings):
|
class Settings(QtWidgets.QMainWindow,Ui_Settings):
|
||||||
|
"""
|
||||||
|
Settings window
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
This module contains some utility functions for math operations.
|
Created on Mon Apr 17 2023
|
||||||
|
@name: data_extraction.py
|
||||||
|
@desc: This module contains some utility functions for math operations.
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
"""
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: position_manipulation.py
|
||||||
|
@desc: This module contains some utility functions for position manipulation.
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from utils.files.input import ScannedObject
|
from utils.files.input import ScannedObject
|
||||||
from utils.math.data_extraction import get_mean
|
from utils.math.data_extraction import get_mean
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Created on Fri Apr 21 2023
|
||||||
|
@name: SettingManager.py
|
||||||
|
@desc: A module to manage the settings
|
||||||
|
@auth: Djalim Simaila
|
||||||
|
@e-mail: djalim.simaila@inrae.fr
|
||||||
|
"""
|
||||||
from yaml import load, dump
|
from yaml import load, dump
|
||||||
try:
|
try:
|
||||||
from yaml import CLoader as Loader, CDumper as Dumper
|
from yaml import CLoader as Loader, CDumper as Dumper
|
||||||
@ -5,6 +12,12 @@ except ImportError:
|
|||||||
from yaml import Loader, Dumper
|
from yaml import Loader, Dumper
|
||||||
|
|
||||||
class SettingManager:
|
class SettingManager:
|
||||||
|
"""
|
||||||
|
A class to manage the settings
|
||||||
|
|
||||||
|
:ivar settings: The settings
|
||||||
|
:ivar instance: The instance of the class
|
||||||
|
"""
|
||||||
instance = None
|
instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -16,13 +29,21 @@ class SettingManager:
|
|||||||
self.createInitialSettings()
|
self.createInitialSettings()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_instance():
|
def get_instance()->'SettingManager':
|
||||||
|
"""
|
||||||
|
Get the instance of the class
|
||||||
|
|
||||||
|
:return: The instance of the class
|
||||||
|
"""
|
||||||
if SettingManager.instance is None:
|
if SettingManager.instance is None:
|
||||||
SettingManager.instance = SettingManager()
|
SettingManager.instance = SettingManager()
|
||||||
return SettingManager.instance
|
return SettingManager.instance
|
||||||
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
"""
|
||||||
|
Save the settings to the config file
|
||||||
|
"""
|
||||||
with open('config.yml', 'w') as f:
|
with open('config.yml', 'w') as f:
|
||||||
f.write(dump(self.settings, Dumper=Dumper))
|
f.write(dump(self.settings, Dumper=Dumper))
|
||||||
|
|
||||||
@ -42,19 +63,45 @@ class SettingManager:
|
|||||||
self.settings['pretiffy_output_file'] = True
|
self.settings['pretiffy_output_file'] = True
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_last_graph(self, graph_number):
|
def get_last_graph(self, graph_number)->str:
|
||||||
|
"""
|
||||||
|
Get the last graph name for the specified slot
|
||||||
|
"""
|
||||||
return self.settings['lastGraph'][graph_number]
|
return self.settings['lastGraph'][graph_number]
|
||||||
|
|
||||||
def set_last_graph(self, graph_number, graph_name):
|
def set_last_graph(self, graph_number, graph_name):
|
||||||
|
"""
|
||||||
|
Set the last graph name for the specified slot
|
||||||
|
|
||||||
|
:param graph_number: The slot number
|
||||||
|
:param graph_name: The graph name
|
||||||
|
"""
|
||||||
self.settings['lastGraph'][graph_number] = graph_name
|
self.settings['lastGraph'][graph_number] = graph_name
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_setting(self, setting_name):
|
def get_setting(self, setting_name)->any:
|
||||||
|
"""
|
||||||
|
Get the value of the specified setting
|
||||||
|
|
||||||
|
:param setting_name: The name of the setting
|
||||||
|
:return: The value of the setting
|
||||||
|
"""
|
||||||
return self.settings[setting_name]
|
return self.settings[setting_name]
|
||||||
|
|
||||||
def get_settings(self):
|
def get_settings(self)->dict:
|
||||||
|
"""
|
||||||
|
Get the settings
|
||||||
|
|
||||||
|
:return: The settings
|
||||||
|
"""
|
||||||
return self.settings
|
return self.settings
|
||||||
|
|
||||||
def set_setting(self, setting_name, setting_value):
|
def set_setting(self, setting_name, setting_value):
|
||||||
|
"""
|
||||||
|
Set the value of the specified setting
|
||||||
|
|
||||||
|
:param setting_name: The name of the setting
|
||||||
|
:param setting_value: The value of the setting
|
||||||
|
"""
|
||||||
self.settings[setting_name] = setting_value
|
self.settings[setting_name] = setting_value
|
||||||
self.save()
|
self.save()
|
||||||
Loading…
Reference in New Issue
Block a user