diff --git a/app.py b/app.py deleted file mode 100644 index e6de4ace411a3d6ca7ac97f1f3e1ac105bfb112b..0000000000000000000000000000000000000000 --- a/app.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -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 -from PyQt5.QtWidgets import QApplication -from utils.gui.pyqt.main_window.MainWindow import MainWindow - -if __name__ == "__main__": - app = QApplication(sys.argv) - window = MainWindow() - window.show() - app.exec() \ No newline at end of file diff --git a/main.py b/main.py index a01401a8bda980565990a4acb424b672c7e65641..e6de4ace411a3d6ca7ac97f1f3e1ac105bfb112b 100644 --- a/main.py +++ b/main.py @@ -1,61 +1,16 @@ -from utils.data_processing.data_processing import get_discrete_data, get_raw_data -from utils.files import output -from utils.files.input import ScannedObject -from utils.math.position_manipulation import verticalise -import time +""" +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 +from PyQt5.QtWidgets import QApplication +from utils.gui.pyqt.main_window.MainWindow import MainWindow -def main(): - # Create an object from the given file - total_time = time.time() - print("Loading file...") - t = time.time() - obj = ScannedObject.from_obj_file("datasets/Barette/1 - BARETTE.obj") - print("File loaded in {} seconds".format(time.time()-t)) - t = time.time() - print("Verticalising object...") - verticalise(obj) - print("Object verticalised in {} seconds".format(time.time()-t)) - t = time.time() - print("Normalising object...") - obj.normalise() - print("Object normalised in {} seconds".format(time.time()-t)) - - # Calculate raw data and save it in a file - t = time.time() - data = get_raw_data(obj, 6,2) - print("Raw data calculated in {} seconds".format(time.time()-t)) - t = time.time() - print("Saving data...") - output.save_output_file('analyse_brute.txt', - output.format_data(data, - '\t', - ["X (en mm)", - "Y (en mm)", - "Z (en mm)", - "teta (en rad)", - "rayon (en mm)", - "Xi-Xmoy", - "Yi-Ymoy"] )) - print("Data saved in {} seconds".format(time.time()-t)) - - # Calculate discrete data and save it in a file - t = time.time() - print("Calculating discrete data...") - data = get_discrete_data(obj, 6,2) - print("Discrete data calculated in {} seconds".format(time.time()-t)) - t = time.time() - print("Saving data...") - output.save_output_file('analyse_rayon.txt', - output.format_data(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)"] )) - print("Data saved in {} seconds".format(time.time()-t)) - print("Total time : {} seconds".format(time.time()-total_time)) - -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + app = QApplication(sys.argv) + window = MainWindow() + window.show() + app.exec() \ No newline at end of file diff --git a/test.py b/test.py deleted file mode 100644 index 2eac71a56c113f7177182a9973cf566ae0a9aba3..0000000000000000000000000000000000000000 --- a/test.py +++ /dev/null @@ -1,38 +0,0 @@ -from utils.files.input import ScannedObject -from integration_tests import data_test - -def test_differences(): - eps = 0.000001 - obj = ScannedObject.from_xyz_file("datasets/Barette/4 - BARETTE v1.xyz", - "datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt", normalised='z') - - data_test.test_get_raw_data(obj, - "datasets/Barette/BARETTE_Delta 1,0_analyse brute.txt", - eps=eps) - - data_test.test_get_discrete_data(obj, - "datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt", - eps=eps) - - -def show_diff_two_obj(): - obj1 = ScannedObject.from_obj_file( - "datasets/Barette/3 - BARETTE v1.obj", normalised='z') - obj2 = ScannedObject.from_xyz_file( - "datasets/Barette/4 - BARETTE v1.xyz", normalised='z') - obj2verts = obj2.get_vertices(sort=True) - for count, values in enumerate(obj1.get_vertices(sort=True)): - L = [abs(values[i] - obj2verts[count][i]) for i in range(len(values))] - print(*L, sep="\t") - - -def count_elements_in_discrete_array(): - obj = ScannedObject.from_xyz_file("datasets/Barette/4 - BARETTE v1.xyz", - "datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt", normalised='z') - cpt = 0 - for i in obj.bruteforce_discretization(): - print(f"nb of element in z{cpt} to z{cpt+1}:", len(i)) - cpt += 1 - -if __name__ == "__main__": - test() \ No newline at end of file diff --git a/utils/graph3D/visplot_render.py b/utils/graph3D/visplot_render.py index 72f8e1e14da05d9a1836506734c738d213836b94..35751578241c6c39200108a15cfaa4df5ec52bd2 100644 --- a/utils/graph3D/visplot_render.py +++ b/utils/graph3D/visplot_render.py @@ -29,6 +29,7 @@ def render3D(obj:ScannedObject,show:bool=True)->scene.SceneCanvas|None: view = canvas.central_widget.add_view() view.camera = 'arcball' view.camera.depth_value = 1e3 + view.camera.distance = 10 color = (0.3, 0.5, 0.8) mesh = Mesh(vertices, faces, color=color) view.add(mesh) diff --git a/utils/gui/pyqt/main_window/MainWindow.py b/utils/gui/pyqt/main_window/MainWindow.py index 4d2d60eeae19a7d6790cfd9ddf18d82eb6329595..2658cc19420fe1b7c0ad107779b8b7aefb39a326 100644 --- a/utils/gui/pyqt/main_window/MainWindow.py +++ b/utils/gui/pyqt/main_window/MainWindow.py @@ -50,10 +50,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.raw_data= None self.discrete_data = None - self.completed = 0 - self.total = 2 + self.completed_tasks = 0 + self.total_tasks = 2 - self.comboBoxes = [ + self.combo_boxes = [ self.slot0ComboBox, self.slot1ComboBox, self.slot2ComboBox, @@ -67,8 +67,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.slot10ComboBox ] - for cb in self.comboBoxes: - cb.addItems(self.graphType) + for combo_box in self.combo_boxes: + combo_box.addItems(self.graphType) + combo_box.currentIndexChanged.connect(self.graph_type_changed) self.slots = [ [self.slot0,"Aucun"], @@ -86,11 +87,15 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): for slot_nb,slot in enumerate(self.slots): slot[1] = SettingManager.get_instance().get_last_graph(slot_nb) - self.comboBoxes[slot_nb].setCurrentText(slot[1]) + self.combo_boxes[slot_nb].setCurrentText(slot[1]) + + self.graph_nb =0 + self.graph_type_changed() self.settings_window = Settings() - self.threads = [] + self.has_changed = True + self.old_discretisation_value = None ############################################################################### # # @@ -106,12 +111,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): file = QFileDialog.getOpenFileName()[0] self.input_file_path.setPlainText(file) self.output_file_prefix.setText(os.path.splitext(os.path.basename(file))[0]) + if self.output_folder_path.toPlainText() is None or self.output_folder_path.toPlainText() == "": + self.output_folder_path.setPlainText(os.path.dirname(file)) + self.has_changed = True def select_folder(self): """ Open a file dialog to select the output folder """ self.output_folder_path.setPlainText(QFileDialog.getExistingDirectory()) + self.has_changed = True def check_input_file(self): """ @@ -147,14 +156,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): return if not self.check_output_folder(): return - - settings = SettingManager.get_instance() - for count,_ in enumerate(self.slots): - self.slots[count][1] = self.comboBoxes[count].currentText() - settings.set_last_graph(count,self.slots[count][1]) self.clear_graphs() - self.completed = 0 + self.completed_tasks = 0 + if not self.has_changed and self.old_discretisation_value == self.discretisation_value_selector.value(): + self.completed_tasks = self.total_tasks -1 + self.finish_analyse() + return + self.has_changed = False + self.old_discretisation_value = self.discretisation_value_selector.value() + # Create the thread to run the analyse self.preprocess_thread = QThread() self.preprocess_worker = PreProcessWorker("PreProcessWorker",self.input_file_path.toPlainText()) @@ -288,8 +299,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): :param raw_data: The raw data :param discrete_data: The discrete data """ + # Clear the graphs if not self.show_graph_checkbox.isChecked(): return + self.set_status("Rendering graphs... this may take a moment") for slot in self.slots: current_slot = slot[0] graph_type = slot[1] @@ -315,6 +328,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): "Z (en mm)", "Rayon moyen (en mm)\n", False).native) + self.set_status("Graphs rendered!") def clear_graphs(self): """ @@ -326,7 +340,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): for i in reversed(range(slot.count())): slot.itemAt(i).widget().setParent(None) - ############################################################################### # # # # @@ -339,8 +352,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): """ Finish the analyse """ - self.completed += 1 - if self.completed == self.total: + self.completed_tasks += 1 + if self.completed_tasks == self.total_tasks: self.status_text.setText("Done") self.analyse_progress_bar.setValue(100) self.renderGraphs(self.obj,self.raw_data,self.discrete_data) @@ -362,4 +375,19 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): """ Show the settings window """ - self.settings_window.show() \ No newline at end of file + self.settings_window.show() + + def graph_type_changed(self): + """ + Update the number of graphs + """ + self.graph_nb = 0 + for combo_box in self.combo_boxes: + if combo_box.currentIndex() != 0: + self.graph_nb += 1 + self.graph_nb_spinbox.setValue(self.graph_nb) + + settings = SettingManager.get_instance() + for count,_ in enumerate(self.slots): + self.slots[count][1] = self.combo_boxes[count].currentText() + settings.set_last_graph(count,self.slots[count][1]) \ No newline at end of file diff --git a/utils/gui/pyqt/main_window/MainWindow.ui b/utils/gui/pyqt/main_window/MainWindow.ui index a2ac7d8795c1ef62783639d627c6c53be53665ae..7ed1eebd10e26e7026f35d77ba2d82e80713ec35 100644 --- a/utils/gui/pyqt/main_window/MainWindow.ui +++ b/utils/gui/pyqt/main_window/MainWindow.ui @@ -11,7 +11,7 @@ </rect> </property> <property name="windowTitle"> - <string>MainWindow</string> + <string>Analyse Morphologique</string> </property> <widget class="QWidget" name="centralwidget"> <layout class="QGridLayout" name="gridLayout"> @@ -117,15 +117,39 @@ </property> </widget> </item> - <item alignment="Qt::AlignHCenter"> - <widget class="QCheckBox" name="show_graph_checkbox"> - <property name="text"> - <string>afficher les graphes</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> + <item> + <layout class="QHBoxLayout" name="graphs_params_layout"> + <item> + <widget class="QCheckBox" name="show_graph_checkbox"> + <property name="text"> + <string>afficher les graphes</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Nombre de graphes :</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="graph_nb_spinbox"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + </widget> + </item> + </layout> </item> <item> <widget class="QPushButton" name="start_analyse_button"> diff --git a/utils/gui/pyqt/main_window/UI_MainWindow.py b/utils/gui/pyqt/main_window/UI_MainWindow.py index 16c3f08fa05478f70da98f183ad4fdb01afb806e..c719d0fead63df7475786b7b78a31622980ce1f5 100644 --- a/utils/gui/pyqt/main_window/UI_MainWindow.py +++ b/utils/gui/pyqt/main_window/UI_MainWindow.py @@ -75,10 +75,22 @@ class Ui_MainWindow(object): self.analyse_progress_bar.setProperty("value", 0) self.analyse_progress_bar.setObjectName("analyse_progress_bar") self.MainSettingsLayout.addWidget(self.analyse_progress_bar) + self.graphs_params_layout = QtWidgets.QHBoxLayout() + self.graphs_params_layout.setObjectName("graphs_params_layout") 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.graphs_params_layout.addWidget(self.show_graph_checkbox) + self.label = QtWidgets.QLabel(self.MainSettings) + self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label.setObjectName("label") + self.graphs_params_layout.addWidget(self.label) + self.graph_nb_spinbox = QtWidgets.QSpinBox(self.MainSettings) + self.graph_nb_spinbox.setReadOnly(True) + self.graph_nb_spinbox.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) + self.graph_nb_spinbox.setObjectName("graph_nb_spinbox") + self.graphs_params_layout.addWidget(self.graph_nb_spinbox) + self.MainSettingsLayout.addLayout(self.graphs_params_layout) self.start_analyse_button = QtWidgets.QPushButton(self.MainSettings) self.start_analyse_button.setObjectName("start_analyse_button") self.MainSettingsLayout.addWidget(self.start_analyse_button) @@ -299,7 +311,7 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate - MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + MainWindow.setWindowTitle(_translate("MainWindow", "Analyse Morphologique")) self.input_file_label.setText(_translate("MainWindow", "Chemin du fichier .obj")) self.input_file_choose_btn.setText(_translate("MainWindow", "Choisir le fichier")) self.output_folder_label.setText(_translate("MainWindow", "Repertoire de sortie")) @@ -307,6 +319,7 @@ class Ui_MainWindow(object): self.output_file_prefix_label.setText(_translate("MainWindow", "Préfix du fichier de sortie")) self.discretisation_label.setText(_translate("MainWindow", "Discretisation (en mm)")) self.show_graph_checkbox.setText(_translate("MainWindow", "afficher les graphes")) + self.label.setText(_translate("MainWindow", "Nombre de 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")) diff --git a/utils/settings/SettingManager.py b/utils/settings/SettingManager.py index 5d4d83af32bf549f165b5b3f743d430788368c98..1dd93d41835558ce061a8297039f29ad6afc313a 100644 --- a/utils/settings/SettingManager.py +++ b/utils/settings/SettingManager.py @@ -19,11 +19,15 @@ class SettingManager: :ivar instance: The instance of the class """ instance = None + version = "1.1.1" def __init__(self): try: with open('config.yml', 'r') as f: - self.settings = load(f.read(), Loader=Loader) + self.settings = load(f.read(), Loader=Loader) + if self.settings['version'] != self.version: + self.settings['version'] = self.version + self.save() except FileNotFoundError: self.settings = {} self.createInitialSettings() @@ -48,7 +52,7 @@ class SettingManager: f.write(dump(self.settings, Dumper=Dumper)) def createInitialSettings(self): - self.settings['version'] = "1.0.0" + self.settings['version'] = self.version self.settings['name'] = 'Analyse Morphologique' self.settings['authors'] = 'Alexis Doghmane <alexis@doghmane.fr>, Djalim Simaila <djalim.simaila@inrae.fr>' self.settings['description'] = 'Analyse Morphologique'