def on_ok(self): """ Tries to convert the current case to 2D mode while saving the 3D mode data. """ try: self.stored_y_value = float(self.y2_pos_input.text()) except ValueError: error_dialog(__("The Y position that was inserted is not valid.")) self.accept()
def check_and_filter(self): """ Filters the executable removing those not matching the correct application. Returns whether or not all of them were correctly set. """ execs_correct: bool = True execs_to_check = { "gencase": self.gencase, "dualsphysics": self.dsphysics, "partvtk": self.partvtk, "floatinginfo": self.floatinginfo, "computeforces": self.computeforces, "measuretool": self.measuretool, "isosurface": self.isosurface, "boundaryvtk": self.boundaryvtk, "flowtool": self.flowtool } bad_executables: list = list() for word, executable in execs_to_check.items(): if not executable_contains_string(executable, word): debug("Executable {} does not contain the word {}".format( executable, word)) execs_correct = False bad_executables.append(executable) if not execs_correct: error_dialog( "One or more of the executables set on the configuration is not correct. Please see the details below.", "These executables do not correspond to their appropriate tool or don't have execution permissions:\n\n{}" .format(LINE_END.join(bad_executables))) self.persist() return execs_correct
def on_dsph_sim_finished(exit_code): """ Simulation finish handler. Defines what happens when the process finishes.""" # Reads output and completes the progress bar output = str(process.readAllStandardOutput().data(), encoding='utf-8') run_dialog.set_detail_text(str(output)) run_dialog.run_complete() run_fs_watcher.removePath(Case.the().path + "/" + Case.the().name + "_out/") if exit_code == 0: # Simulation went correctly Case.the().info.is_simulation_done = True Case.the().info.needs_to_run_gencase = False self.simulation_complete.emit(True) else: # In case of an error Case.the().info.needs_to_run_gencase = True if "exception" in str(output).lower(): log("There was an error on the execution. Opening an error dialog for that.") run_dialog.hide() self.simulation_complete.emit(False) error_dialog(__("An error occurred during execution. Make sure that parameters exist and are properly defined. " "You can also check your execution device (update the driver of your GPU). Read the details for more information."), str(output)) save_case(Case.the().path, Case.the())
def on_save(self): """ Link linearspring save button behaviour""" target_linearspring = self.case.chrono.get_link_linearspring_for_id( self.link_linearspring_id) target_linearspring.idbody1 = str( self.body_one_line_edit.currentText()) target_linearspring.idbody2 = str( self.body_two_line_edit.currentText()) target_linearspring.point_fb1 = [ float(self.point_b1_x_line_edit.text()), float(self.point_b1_y_line_edit.text()), float(self.point_b1_z_line_edit.text()) ] target_linearspring.point_fb2 = [ float(self.point_b2_x_line_edit.text()), float(self.point_b2_y_line_edit.text()), float(self.point_b2_z_line_edit.text()) ] target_linearspring.stiffness = float(self.stiffness_line_edit.text()) target_linearspring.damping = float(self.damping_line_edit.text()) target_linearspring.rest_length = float(self.rest_line_edit.text()) target_linearspring.number_of_sections = int( self.vtk_nside_line_edit.text()) target_linearspring.spring_radius = float( self.vtk_radius_line_edit.text()) target_linearspring.revolution_length = float( self.vtk_length_line_edit.text()) if target_linearspring.idbody1 and target_linearspring.idbody2: LinkLinearspringEdit.accept(self) else: error_dialog( "You need to select an option for each one of the bodies.")
def on_export_finished(exit_code): """ Closes and displays info/error about the process. """ post_processing_widget.adapt_to_export_finished() export_dialog.accept() detailed_text = "The executed command line was: {} {}\n\n{}".format( case.executable_paths.partvtk, " ".join(executable_parameters), case.info.current_output) if not exit_code: info_dialog(info_text=__("PartVTK finished successfully"), detailed_text=detailed_text) else: error_dialog(__( "There was an error on the post-processing. Show details to view the errors." ), detailed_text=detailed_text) if options["open_paraview"]: subprocess.Popen([ case.executable_paths.paraview, "--data={}\\{}\\{}_..{}".format( case.get_out_folder_path(), options["file_name"], options["file_name"], save_extension) ], stdout=subprocess.PIPE)
def on_ok(self): """ Saves damping zone data to the data structure. """ self.case.get_damping_zone(self.object_key).enabled = self.enabled_checkbox.isChecked() self.case.get_damping_zone(self.object_key).overlimit = float(self.overlimit_input.text()) self.case.get_damping_zone(self.object_key).redumax = float(self.redumax_input.text()) damping_group = FreeCAD.ActiveDocument.getObject(self.object_key) damping_group.OutList[0].Start = (float(self.limitmin_input_x.text()) * DIVIDER, float(self.limitmin_input_y.text()) * DIVIDER, float(self.limitmin_input_z.text()) * DIVIDER) damping_group.OutList[0].End = (float(self.limitmax_input_x.text()) * DIVIDER, float(self.limitmax_input_y.text()) * DIVIDER, float(self.limitmax_input_z.text()) * DIVIDER) damping_group.OutList[1].Start = damping_group.OutList[0].End overlimit_vector = FreeCAD.Vector(*damping_group.OutList[0].End) - FreeCAD.Vector(*damping_group.OutList[0].Start) try: overlimit_vector.normalize() except FreeCAD.Base.FreeCADError: error_dialog(__("The vector between minimum and maximum limit must have length.")) overlimit_vector = overlimit_vector * (self.case.get_damping_zone(self.object_key).overlimit * DIVIDER) overlimit_vector = overlimit_vector + FreeCAD.Vector(*damping_group.OutList[0].End) damping_group.OutList[1].End = (overlimit_vector.x, overlimit_vector.y, overlimit_vector.z) FreeCAD.ActiveDocument.recompute() self.accept()
def load_case(load_path: str) -> "Case": """ Loads a case from the given folder and returns its Case data. """ refocus_cwd() project_folder_path = path.dirname(load_path) freecad_document_file_path = path.abspath("{}/DSPH_Case.FCStd".format(project_folder_path)) if not path.isfile(freecad_document_file_path): error_dialog(__("DSPH_Case.FCStd file could not be found. Please check if the project was moved or the file was renamed.")) return None if document_count() and not prompt_close_all_documents(): return None FreeCAD.open(project_folder_path + "/DSPH_Case.FCStd") with open(load_path, "rb") as load_picklefile: try: loaded_data = pickle.load(load_picklefile) if not loaded_data.version: warning_dialog(__("The case data you're trying to load is older than version 0.6 and cannot be loaded.")) prompt_close_all_documents(prompt=False) return None if loaded_data.version < VERSION: warning_dialog(__("The case data you are loading is from a previous version ({}) of this software. They may be missing features or errors.").format(loaded_data.version)) elif loaded_data.version > VERSION: warning_dialog(__("You're loading a case data from a future version ({}) of this software. You should upgrade DesignSPHysics as they may be errors using this file.").format(loaded_data.version)) return loaded_data except AttributeError: error_dialog(__("There was an error opening the case. Case Data file seems to be corrupted.")) return None
def on_save(self): """ Link pointline save button behaviour""" link_pointline = self.case.chrono.get_link_pointline_for_id( self.link_pointline_id) link_pointline.idbody1 = str(self.body_one_line_edit.currentText()) link_pointline.slidingvector = [ float(self.sliding_vector_x_line_edit.text()), float(self.sliding_vector_y_line_edit.text()), float(self.sliding_vector_z_line_edit.text()) ] link_pointline.rotpoint = [ float(self.rotpoint_x_line_edit.text()), float(self.rotpoint_y_line_edit.text()), float(self.rotpoint_z_line_edit.text()) ] link_pointline.rotvector = [ float(self.rotvector_x_line_edit.text()), float(self.rotvector_y_line_edit.text()), float(self.rotvector_z_line_edit.text()) ] link_pointline.rotvector2 = [ float(self.rotvector2_x_line_edit.text()), float(self.rotvector2_y_line_edit.text()), float(self.rotvector2_z_line_edit.text()) ] link_pointline.stiffness = float(self.stiffness_line_edit.text()) link_pointline.damping = float(self.damping_line_edit.text()) if link_pointline.idbody1: LinkPointlineEdit.accept(self) else: error_dialog("You need to select an option for the body to use.")
def on_execute_gencase(self): """ Saves data into disk and uses GenCase to generate the case files.""" self.on_save_case() if not Case.the().executable_paths.gencase: warning_dialog(__("GenCase executable is not set.")) return gencase_full_path = path.abspath(Case.the().executable_paths.gencase) arguments = [ "{path}/{name}_Def".format(path=Case.the().path, name=Case.the().name), "{path}/{name}_out/{name}".format(path=Case.the().path, name=Case.the().name), "-save:+all" ] cmd_string = "{} {}".format(gencase_full_path, " ".join(arguments)) refocus_cwd() process = QtCore.QProcess(get_fc_main_window()) process.setWorkingDirectory(Case.the().path) ensure_process_is_executable_or_fail(gencase_full_path) process.start(gencase_full_path, arguments) debug("Executing -> {}".format(cmd_string)) process.waitForFinished() try: output = str(process.readAllStandardOutput().data(), encoding='utf-8') except UnicodeDecodeError: output = str(process.readAllStandardOutput().data(), encoding='latin1') if process.exitCode(): Case.the().info.is_gencase_done = False error_dialog( __("Error executing GenCase. Did you add objects to the case?. Another reason could be memory issues. View details for more info." ), output) else: try: total_particles_text = output[ output.index("Total particles: "):output.index(" (bound=")] total_particles = int( total_particles_text[total_particles_text.index(": ") + 2:]) Case.the().info.particle_number = total_particles GencaseCompletedDialog(particle_count=total_particles, detail_text=output, cmd_string=cmd_string, parent=get_fc_main_window()).show() Case.the().info.is_gencase_done = True self.on_save_case() Case.the().info.needs_to_run_gencase = False except ValueError: print_exc() Case.the().info.is_gencase_done = False Case.the().info.needs_to_run_gencase = True # Refresh widget enable/disable status as GenCase finishes self.gencase_completed.emit(Case.the().info.is_gencase_done)
def on_mtool_export(self): """ Export button behaviour.""" export_parameters = dict() export_parameters["save_mode"] = self.outformat_combobox.currentIndex() export_parameters["save_vars"] = "-all" if self.mtool_types_chk_all.isChecked(): export_parameters["save_vars"] = "+all" else: if self.mtool_types_chk_vel.isChecked(): export_parameters["save_vars"] += ",+vel" if self.mtool_types_chk_rhop.isChecked(): export_parameters["save_vars"] += ",+rhop" if self.mtool_types_chk_press.isChecked(): export_parameters["save_vars"] += ",+press" if self.mtool_types_chk_mass.isChecked(): export_parameters["save_vars"] += ",+mass" if self.mtool_types_chk_vol.isChecked(): export_parameters["save_vars"] += ",+vol" if self.mtool_types_chk_idp.isChecked(): export_parameters["save_vars"] += ",+idp" if self.mtool_types_chk_ace.isChecked(): export_parameters["save_vars"] += ",+ace" if self.mtool_types_chk_vor.isChecked(): export_parameters["save_vars"] += ",+vor" if self.mtool_types_chk_kcorr.isChecked(): export_parameters["save_vars"] += ",+kcorr" if export_parameters[ "save_vars"] == "-all" and not self.mtool_calculate_elevation.isChecked( ): export_parameters["save_vars"] = "+all" export_parameters[ "calculate_water_elevation"] = self.mtool_calculate_elevation.isChecked( ) if self.mtool_file_name_text.text(): export_parameters["filename"] = self.mtool_file_name_text.text() else: export_parameters["filename"] = "MeasurePart" if self.mtool_parameters_text.text(): export_parameters[ "additional_parameters"] = self.mtool_parameters_text.text() else: export_parameters["additional_parameters"] = "" if not Case.the().info.measuretool_points and not Case.the( ).info.measuretool_grid: error_dialog( __("No points or grid are defined to execute MeasureTool"), __("Please define either list of points or a grid of points to continue. MeasureTool won't be executed." )) else: measuretool_export(export_parameters, Case.the(), self.post_processing_widget) self.accept()
def on_export_finished(exit_code): """ Closes and displays info/error about the process. """ post_processing_widget.adapt_to_export_finished() export_dialog.accept() detailed_text = "The executed command line was: {} {}\n\n{}".format(case.executable_paths.flowtool, " ".join(executable_parameters), case.info.current_output) if not exit_code: info_dialog(info_text=__("FlowTool finished successfully"), detailed_text=detailed_text) else: error_dialog(__("There was an error on the post-processing. Show details to view the errors."), detailed_text=detailed_text)
def on_load_button(self): """ Defines load case button behaviour. This is made so errors can be detected and handled. """ try: self.on_load_case() except ImportError: error_dialog( __("There was an error loading the case"), __("The case you are trying to load has some data that DesignSPHysics could not load.\n\nDid you make the case in a previous version?" )) self.on_new_case(prompt=False)
def check_compatibility(): """ Ensures the current version of FreeCAD is compatible with the macro. Spawns an error dialog and throws exception to halt the execution if its not. """ if not is_compatible_version(): error_dialog( __("This FreeCAD version is not compatible. Please update FreeCAD to version {} or higher." ).format(FREECAD_MIN_VERSION)) raise EnvironmentError( __("This FreeCAD version is not compatible. Please update FreeCAD to version {} or higher." ).format(FREECAD_MIN_VERSION))
def on_save(self): """ Link Spheric save button behaviour""" link_spheric = self.case.chrono.get_link_spheric_for_id(self.link_spheric_id) link_spheric.idbody1 = str(self.body_one_line_edit.currentText()) link_spheric.idbody2 = str(self.body_two_line_edit.currentText()) link_spheric.rotpoint = [float(self.point_x_line_edit.text()), float(self.point_y_line_edit.text()), float(self.point_z_line_edit.text())] link_spheric.stiffness = float(self.stiffness_line_edit.text()) link_spheric.damping = float(self.damping_line_edit.text()) if link_spheric.idbody1: LinkSphericEdit.accept(self) else: error_dialog("You need to select an option for the body to use.")
def on_open_paraview_menu(self, action): """ Tries to open Paraview with the selected option. """ try: subprocess.Popen([ Case.the().executable_paths.paraview, "--data={}\\{}".format( Case.the().path + "\\" + Case.the().name + "_out", action.text()) ], stdout=subprocess.PIPE) self.accept() except FileNotFoundError: error_dialog( "There was an error executing paraview. Make sure the path for the paraview executable is set in the DesignSPHyisics configuration and that the executable is a correct paraview one." )
def browse(self, app_name, input_prop) -> None: """ Opens a file browser to check for the provided app name. """ file_name, _ = QtGui.QFileDialog().getOpenFileName(self, __("Select {} path").format(app_name), Case.the().info.last_used_directory) Case.the().info.update_last_used_directory(file_name) self.ok_button.setFocus() if not file_name: return if executable_contains_string(file_name, app_name): input_prop.setText(file_name) else: error_dialog(__("Can't recognize {} in the selected executable.").format(app_name))
def on_apply(self): """ Applies the currently introduced MLPiston2D configuration to the data structure. """ self.temp_mlpiston2d.incz = float(self.incz_input.text()) self.temp_mlpiston2d.smoothz = int(self.smooth_z.text()) self.temp_mlpiston2d.smoothy = int(self.smooth_y.text()) list_posy = self.veldata_posy_input.text().split(",") list_timedataini = self.veldata_timedataini_input.text().split(",") if len(list_posy) != len(list_timedataini) or len( self.temp_mlpiston2d.veldata) != len(list_posy) or len( self.temp_mlpiston2d.veldata) != len(list_timedataini): error_dialog( __("Wrong number of Y positions or Time offsets. Introduce {} of them separated by commas" ).format(len(self.temp_mlpiston2d.veldata))) return for index, _ in enumerate(self.temp_mlpiston2d.veldata): self.temp_mlpiston2d.veldata[index].posy = list_posy[index] self.temp_mlpiston2d.veldata[index].timedataini = list_timedataini[ index] self.mlpiston2d = self.temp_mlpiston2d self.accept()
def geo_ok_clicked(self): """ Defines ok button behaviour""" for geo_scaling_edit in [ self.geo_scaling_x_e, self.geo_scaling_y_e, self.geo_scaling_z_e ]: geo_scaling_edit.setText(geo_scaling_edit.text().replace(",", ".")) try: import_geo(filename=str(self.geo_file_path.text()), scale_x=float(self.geo_scaling_x_e.text()), scale_y=float(self.geo_scaling_y_e.text()), scale_z=float(self.geo_scaling_z_e.text()), name=str(self.geo_objname_text.text()), autofill=self.geo_autofill_chck.isChecked(), case=Case.the()) self.accept() except ValueError: error_dialog( __("There was an error. Are you sure you wrote correct float values in the sacaling factor?" ))
def on_save(self): """ Link hinge save button behaviour""" link_hinge = self.case.chrono.get_link_hinge_for_id(self.link_hinge_id) link_hinge.idbody1 = str(self.body_one_line_edit.currentText()) link_hinge.idbody2 = str(self.body_two_line_edit.currentText()) link_hinge.rotpoint = [ float(self.rotpoints_x_line_edit.text()), float(self.rotpoints_y_line_edit.text()), float(self.rotpoints_z_line_edit.text()) ] link_hinge.rotvector = [ float(self.rotvector_x_line_edit.text()), float(self.rotvector_y_line_edit.text()), float(self.rotvector_z_line_edit.text()) ] link_hinge.stiffness = float(self.stiffness_line_edit.text()) link_hinge.damping = float(self.damping_line_edit.text()) if link_hinge.idbody1 and link_hinge.idbody2: LinkHingeEdit.accept(self) else: error_dialog( "You need to select an option for each one of the bodies.")
def on_load_case(self): """Defines loading case mechanism. Load points to a dsphdata custom file, that stores all the relevant info. If FCStd file is not found the project is considered corrupt.""" load_path, _ = QtGui.QFileDialog.getOpenFileName( self, __("Load Case"), Case.the().info.last_used_directory, "casedata.dsphdata") Case.the().info.update_last_used_directory(load_path) if load_path == "": return disk_data: Case = load_case(load_path) if not disk_data: return try: Case.update_from_disk(disk_data) self.update_dp.emit() except (EOFError, ValueError): error_dialog( __("There was an error importing the case You probably need to set them again.\n\n" "This could be caused due to file corruption, caused by operating system based line endings or ends-of-file, or other related aspects." )) # User may have changed the name of the folder/project Case.the().path = path.dirname(load_path) Case.the().name = Case.the().path.split("/")[-1] # Adapt widget state to case info self.case_created.emit() self.gencase_completed.emit(Case.the().info.is_gencase_done) self.simulation_completed.emit(Case.the().info.is_simulation_done) self.need_refresh.emit() Case.the().executable_paths.check_and_filter() Case.the().info.update_last_used_directory(load_path)
def on_save(self): """ Link pulley save button behaviour""" link_pulley = self.case.chrono.get_link_pulley_for_id( self.link_pulley_id) link_pulley.idbody1 = str(self.body_one_line_edit.currentText()) link_pulley.idbody2 = str(self.body_two_line_edit.currentText()) link_pulley.rotpoint = [ float(self.rotpoints_x_line_edit.text()), float(self.rotpoints_y_line_edit.text()), float(self.rotpoints_z_line_edit.text()) ] link_pulley.rotvector = [ float(self.rotvector_x_line_edit.text()), float(self.rotvector_y_line_edit.text()), float(self.rotvector_z_line_edit.text()) ] link_pulley.radius = float(self.radius_line_edit.text()) link_pulley.radius2 = float(self.radius2_line_edit.text()) if link_pulley.idbody1 and link_pulley.idbody2: LinkPulleyEdit.accept(self) else: error_dialog( "You need to select an option for each one of the bodies.")
def _on_configure_moordyn_parameters(self) -> None: """ Opens up the MoorDyn configuration parameters dialog. """ new_selected_bodies: list = list() for row_num in range(0, self.floating_selection_table.rowCount()): target_widget: MooringsCompatibleFloatingWidget = self.floating_selection_table.cellWidget( row_num, 0) if target_widget.use_checkbox.isChecked(): list_of_matching_bodies: list = list( filter(lambda body: body.ref == target_widget.mkbound, self.moordyn_parameters_data.bodies)) new_body: MoorDynBody = list_of_matching_bodies[ 0] if list_of_matching_bodies else MoorDynBody( target_widget.mkbound) new_selected_bodies.append(new_body) self.moordyn_parameters_data.bodies = list(new_selected_bodies) if not self.moordyn_parameters_data.bodies: error_dialog( __("You must at least select one floating body to configure MoorDyn" )) return MoorDynParametersDialog(self.moordyn_parameters_data)
def __init__(self, box_id, parent=None): super().__init__(parent=parent) self.box_id = box_id self.box_edit_layout = QtGui.QVBoxLayout() # Find the box for which the button was pressed target_box = None for box in Case.the().flowtool_boxes: if box.id == self.box_id: target_box = box # This should not happen but if no box is found with reference id, it spawns an error. if target_box is None: error_dialog("There was an error opening the box to edit") return self.box_edit_name_layout = QtGui.QHBoxLayout() self.box_edit_name_label = QtGui.QLabel(__("Box Name")) self.box_edit_name_input = QtGui.QLineEdit(target_box.name) self.box_edit_name_layout.addWidget(self.box_edit_name_label) self.box_edit_name_layout.addWidget(self.box_edit_name_input) self.box_edit_description = QtGui.QLabel( __("Using multiple boxes with the same name will produce only one volume to measure.\n" "Use that to create prisms and complex forms. " "All points are specified in meters.")) self.box_edit_description.setAlignment(QtCore.Qt.AlignCenter) # Reference image self.box_edit_image = QtGui.QLabel() self.box_edit_image.setPixmap( get_icon("flowtool_template.jpg", return_only_path=True)) self.box_edit_image.setAlignment(QtCore.Qt.AlignCenter) # Point coords inputs self.box_edit_points_layout = QtGui.QVBoxLayout() self.box_edit_point_a_layout = QtGui.QHBoxLayout() self.box_edit_point_a_label = QtGui.QLabel(__("Point A (X, Y, Z)")) self.box_edit_point_a_x = QtGui.QLineEdit(str(target_box.point1[0])) self.box_edit_point_a_y = QtGui.QLineEdit(str(target_box.point1[1])) self.box_edit_point_a_z = QtGui.QLineEdit(str(target_box.point1[2])) self.box_edit_point_a_layout.addWidget(self.box_edit_point_a_label) self.box_edit_point_a_layout.addWidget(self.box_edit_point_a_x) self.box_edit_point_a_layout.addWidget(self.box_edit_point_a_y) self.box_edit_point_a_layout.addWidget(self.box_edit_point_a_z) self.box_edit_point_b_layout = QtGui.QHBoxLayout() self.box_edit_point_b_label = QtGui.QLabel(__("Point B (X, Y, Z)")) self.box_edit_point_b_x = QtGui.QLineEdit(str(target_box.point2[0])) self.box_edit_point_b_y = QtGui.QLineEdit(str(target_box.point2[1])) self.box_edit_point_b_z = QtGui.QLineEdit(str(target_box.point2[2])) self.box_edit_point_b_layout.addWidget(self.box_edit_point_b_label) self.box_edit_point_b_layout.addWidget(self.box_edit_point_b_x) self.box_edit_point_b_layout.addWidget(self.box_edit_point_b_y) self.box_edit_point_b_layout.addWidget(self.box_edit_point_b_z) self.box_edit_point_c_layout = QtGui.QHBoxLayout() self.box_edit_point_c_label = QtGui.QLabel(__("Point C (X, Y, Z)")) self.box_edit_point_c_x = QtGui.QLineEdit(str(target_box.point3[0])) self.box_edit_point_c_y = QtGui.QLineEdit(str(target_box.point3[1])) self.box_edit_point_c_z = QtGui.QLineEdit(str(target_box.point3[2])) self.box_edit_point_c_layout.addWidget(self.box_edit_point_c_label) self.box_edit_point_c_layout.addWidget(self.box_edit_point_c_x) self.box_edit_point_c_layout.addWidget(self.box_edit_point_c_y) self.box_edit_point_c_layout.addWidget(self.box_edit_point_c_z) self.box_edit_point_d_layout = QtGui.QHBoxLayout() self.box_edit_point_d_label = QtGui.QLabel(__("Point D (X, Y, Z)")) self.box_edit_point_d_x = QtGui.QLineEdit(str(target_box.point4[0])) self.box_edit_point_d_y = QtGui.QLineEdit(str(target_box.point4[1])) self.box_edit_point_d_z = QtGui.QLineEdit(str(target_box.point4[2])) self.box_edit_point_d_layout.addWidget(self.box_edit_point_d_label) self.box_edit_point_d_layout.addWidget(self.box_edit_point_d_x) self.box_edit_point_d_layout.addWidget(self.box_edit_point_d_y) self.box_edit_point_d_layout.addWidget(self.box_edit_point_d_z) self.box_edit_point_e_layout = QtGui.QHBoxLayout() self.box_edit_point_e_label = QtGui.QLabel(__("Point E (X, Y, Z)")) self.box_edit_point_e_x = QtGui.QLineEdit(str(target_box.point5[0])) self.box_edit_point_e_y = QtGui.QLineEdit(str(target_box.point5[1])) self.box_edit_point_e_z = QtGui.QLineEdit(str(target_box.point5[2])) self.box_edit_point_e_layout.addWidget(self.box_edit_point_e_label) self.box_edit_point_e_layout.addWidget(self.box_edit_point_e_x) self.box_edit_point_e_layout.addWidget(self.box_edit_point_e_y) self.box_edit_point_e_layout.addWidget(self.box_edit_point_e_z) self.box_edit_point_f_layout = QtGui.QHBoxLayout() self.box_edit_point_f_label = QtGui.QLabel(__("Point F (X, Y, Z)")) self.box_edit_point_f_x = QtGui.QLineEdit(str(target_box.point6[0])) self.box_edit_point_f_y = QtGui.QLineEdit(str(target_box.point6[1])) self.box_edit_point_f_z = QtGui.QLineEdit(str(target_box.point6[2])) self.box_edit_point_f_layout.addWidget(self.box_edit_point_f_label) self.box_edit_point_f_layout.addWidget(self.box_edit_point_f_x) self.box_edit_point_f_layout.addWidget(self.box_edit_point_f_y) self.box_edit_point_f_layout.addWidget(self.box_edit_point_f_z) self.box_edit_point_g_layout = QtGui.QHBoxLayout() self.box_edit_point_g_label = QtGui.QLabel(__("Point G (X, Y, Z)")) self.box_edit_point_g_x = QtGui.QLineEdit(str(target_box.point7[0])) self.box_edit_point_g_y = QtGui.QLineEdit(str(target_box.point7[1])) self.box_edit_point_g_z = QtGui.QLineEdit(str(target_box.point7[2])) self.box_edit_point_g_layout.addWidget(self.box_edit_point_g_label) self.box_edit_point_g_layout.addWidget(self.box_edit_point_g_x) self.box_edit_point_g_layout.addWidget(self.box_edit_point_g_y) self.box_edit_point_g_layout.addWidget(self.box_edit_point_g_z) self.box_edit_point_h_layout = QtGui.QHBoxLayout() self.box_edit_point_h_label = QtGui.QLabel(__("Point H (X, Y, Z)")) self.box_edit_point_h_x = QtGui.QLineEdit(str(target_box.point8[0])) self.box_edit_point_h_y = QtGui.QLineEdit(str(target_box.point8[1])) self.box_edit_point_h_z = QtGui.QLineEdit(str(target_box.point8[2])) self.box_edit_point_h_layout.addWidget(self.box_edit_point_h_label) self.box_edit_point_h_layout.addWidget(self.box_edit_point_h_x) self.box_edit_point_h_layout.addWidget(self.box_edit_point_h_y) self.box_edit_point_h_layout.addWidget(self.box_edit_point_h_z) self.box_edit_points_layout.addLayout(self.box_edit_point_a_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_b_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_c_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_d_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_e_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_f_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_g_layout) self.box_edit_points_layout.addLayout(self.box_edit_point_h_layout) # Ok and cancel buttons self.box_edit_button_layout = QtGui.QHBoxLayout() self.box_edit_button_ok = QtGui.QPushButton(__("OK")) self.box_edit_button_cancel = QtGui.QPushButton(__("Cancel")) self.box_edit_button_layout.addStretch(1) self.box_edit_button_layout.addWidget(self.box_edit_button_ok) self.box_edit_button_layout.addWidget(self.box_edit_button_cancel) self.box_edit_layout.addLayout(self.box_edit_name_layout) self.box_edit_layout.addWidget(self.box_edit_description) self.box_edit_layout.addWidget(self.box_edit_image) self.box_edit_layout.addStretch(1) self.box_edit_layout.addLayout(self.box_edit_points_layout) self.box_edit_layout.addLayout(self.box_edit_button_layout) self.setLayout(self.box_edit_layout) self.box_edit_button_ok.clicked.connect(self.on_ok) self.box_edit_button_cancel.clicked.connect(self.on_cancel) self.exec_()
def __init__(self, link_linearspring_id, bodies_widgets, parent=None): super().__init__(parent=parent) self.case = Case.the() self.link_linearspring_id = link_linearspring_id # Title self.setWindowTitle(__("Link linearspring configuration")) self.link_linearspring_edit_layout = QtGui.QVBoxLayout() # Find the link linearspring for which the button was pressed target_link_linearspring = None for link_linearspring in self.case.chrono.link_linearspring: if link_linearspring.id == self.link_linearspring_id: target_link_linearspring = link_linearspring # This should not happen but if no link linearspring is found with reference id, it spawns an error. if target_link_linearspring is None: error_dialog( "There was an error opnening the link linearspring to edit") return # Elements that interact self.body_layout = QtGui.QHBoxLayout() self.body_one_label = QtGui.QLabel(__("Body 1: ")) self.body_one_line_edit = QtGui.QComboBox() self.body_one_line_edit.insertItems( 0, [str(target_link_linearspring.idbody1)]) for body in bodies_widgets: if body.object_check.isChecked() and body.object_name != str( target_link_linearspring.idbody1): self.body_one_line_edit.insertItems(0, [body.object_name]) self.body_two_label = QtGui.QLabel(__("Body 2: ")) self.body_two_line_edit = QtGui.QComboBox() self.body_two_line_edit.insertItems( 0, [str(target_link_linearspring.idbody2)]) for body in bodies_widgets: if body.object_check.isChecked() and body.object_name != str( target_link_linearspring.idbody2): self.body_two_line_edit.insertItems(0, [body.object_name]) self.body_to_body_label = QtGui.QLabel(__("to")) self.body_layout.addWidget(self.body_one_label) self.body_layout.addWidget(self.body_one_line_edit) self.body_layout.addWidget(self.body_to_body_label) self.body_layout.addWidget(self.body_two_label) self.body_layout.addWidget(self.body_two_line_edit) self.body_layout.addStretch(1) self.link_linearspring_edit_layout.addLayout(self.body_layout) # Points where the elements interact in body 1 self.points_b1_layout = QtGui.QHBoxLayout() self.points_b1_label = QtGui.QLabel(__("Points in body 1: ")) self.point_b1_x_label = QtGui.QLabel(__("X")) self.point_b1_x_line_edit = QtGui.QLineEdit( str(target_link_linearspring.point_fb1[0])) self.point_b1_y_label = QtGui.QLabel(__("Y")) self.point_b1_y_line_edit = QtGui.QLineEdit( str(target_link_linearspring.point_fb1[1])) self.point_b1_z_label = QtGui.QLabel(__("Z")) self.point_b1_z_line_edit = QtGui.QLineEdit( str(target_link_linearspring.point_fb1[2])) self.points_b1_layout.addWidget(self.points_b1_label) self.points_b1_layout.addWidget(self.point_b1_x_label) self.points_b1_layout.addWidget(self.point_b1_x_line_edit) self.points_b1_layout.addWidget(self.point_b1_y_label) self.points_b1_layout.addWidget(self.point_b1_y_line_edit) self.points_b1_layout.addWidget(self.point_b1_z_label) self.points_b1_layout.addWidget(self.point_b1_z_line_edit) self.link_linearspring_edit_layout.addLayout(self.points_b1_layout) # Points where the elements interact in body 2 self.points_b2_layout = QtGui.QHBoxLayout() self.points_b2_label = QtGui.QLabel(__("Points in body 2: ")) self.point_b2_x_label = QtGui.QLabel(__("X")) self.point_b2_x_line_edit = QtGui.QLineEdit( str(target_link_linearspring.point_fb2[0])) self.point_b2_y_label = QtGui.QLabel(__("Y")) self.point_b2_y_line_edit = QtGui.QLineEdit( str(target_link_linearspring.point_fb2[1])) self.point_b2_z_label = QtGui.QLabel(__("Z")) self.point_b2_z_line_edit = QtGui.QLineEdit( str(target_link_linearspring.point_fb2[2])) self.points_b2_layout.addWidget(self.points_b2_label) self.points_b2_layout.addWidget(self.point_b2_x_label) self.points_b2_layout.addWidget(self.point_b2_x_line_edit) self.points_b2_layout.addWidget(self.point_b2_y_label) self.points_b2_layout.addWidget(self.point_b2_y_line_edit) self.points_b2_layout.addWidget(self.point_b2_z_label) self.points_b2_layout.addWidget(self.point_b2_z_line_edit) self.link_linearspring_edit_layout.addLayout(self.points_b2_layout) # Torsion options self.torsion_stiffness_layout = QtGui.QHBoxLayout() self.torsion_damping_layout = QtGui.QHBoxLayout() self.stiffness_label = QtGui.QLabel(__("Stiffness (N/m):")) self.stiffness_line_edit = QtGui.QLineEdit( str(target_link_linearspring.stiffness)) self.damping_label = QtGui.QLabel(__("Damping (Ns/m):")) self.damping_line_edit = QtGui.QLineEdit( str(target_link_linearspring.damping)) self.torsion_stiffness_layout.addWidget(self.stiffness_label) self.torsion_stiffness_layout.addWidget(self.stiffness_line_edit) self.torsion_damping_layout.addWidget(self.damping_label) self.torsion_damping_layout.addWidget(self.damping_line_edit) self.link_linearspring_edit_layout.addLayout( self.torsion_stiffness_layout) self.link_linearspring_edit_layout.addLayout( self.torsion_damping_layout) # Spring equilibrium length self.rest_layout = QtGui.QHBoxLayout() self.rest_label = QtGui.QLabel(__("Rest length (m):")) self.rest_line_edit = QtGui.QLineEdit( str(target_link_linearspring.rest_length)) self.rest_layout.addWidget(self.rest_label) self.rest_layout.addWidget(self.rest_line_edit) self.link_linearspring_edit_layout.addLayout(self.rest_layout) # vtk self.visualization_options_groupbox = QtGui.QGroupBox( __("Visualization Options")) self.vtk_layout = QtGui.QHBoxLayout() self.vtk_nside_label = QtGui.QLabel(__("Number of sections: ")) self.vtk_nside_line_edit = QtGui.QLineEdit( str(target_link_linearspring.number_of_sections)) self.vtk_radius_label = QtGui.QLabel(__("Spring radius: ")) self.vtk_radius_line_edit = QtGui.QLineEdit( str(target_link_linearspring.spring_radius)) self.vtk_length_label = QtGui.QLabel(__("Length for revolution: ")) self.vtk_length_line_edit = QtGui.QLineEdit( str(target_link_linearspring.revolution_length)) self.vtk_layout.addWidget(self.vtk_nside_label) self.vtk_layout.addWidget(self.vtk_nside_line_edit) self.vtk_layout.addWidget(self.vtk_radius_label) self.vtk_layout.addWidget(self.vtk_radius_line_edit) self.vtk_layout.addWidget(self.vtk_length_label) self.vtk_layout.addWidget(self.vtk_length_line_edit) self.visualization_options_groupbox.setLayout(self.vtk_layout) self.link_linearspring_edit_layout.addWidget( self.visualization_options_groupbox) # Buttons self.ok_button = QtGui.QPushButton("Save") self.ok_button.clicked.connect(self.on_save) self.cancel_button = QtGui.QPushButton("Cancel") self.cancel_button.clicked.connect(self.on_cancel) self.button_layout = QtGui.QHBoxLayout() self.button_layout.addStretch(1) self.button_layout.addWidget(self.ok_button) self.button_layout.addWidget(self.cancel_button) self.link_linearspring_edit_layout.addLayout(self.button_layout) # Add the elements to the window self.setLayout(self.link_linearspring_edit_layout) self.exec_()
def on_ex_simulate(self): """ Defines what happens on simulation button press. It shows the run window and starts a background process with dualsphysics running. Updates the window with useful info.""" refocus_cwd() if Case.the().info.needs_to_run_gencase: # Warning window about save_case warning_dialog("You should run GenCase again. Otherwise, the obtained results may not be as expected") static_params_exe = [Case.the().get_out_xml_file_path(), Case.the().get_out_folder_path(), "-{device}".format(device=self.device_selector.currentText().lower()), "-svres"] additional_parameters = list() if Case.the().info.run_additional_parameters: additional_parameters = Case.the().info.run_additional_parameters.split(" ") final_params_ex = static_params_exe + additional_parameters cmd_string = "{} {}".format(Case.the().executable_paths.dsphysics, " ".join(final_params_ex)) run_dialog = RunDialog(case_name=Case.the().name, processor=self.device_selector.currentText(), number_of_particles=Case.the().info.particle_number, cmd_string=cmd_string, parent=get_fc_main_window()) run_dialog.set_value(0) run_dialog.run_update(0, 0, None) Case.the().info.is_simulation_done = False run_fs_watcher = QtCore.QFileSystemWatcher() self.simulation_started.emit() # Cancel button handler def on_cancel(): log(__("Stopping simulation")) if process: process.kill() run_dialog.hide_all() Case.the().info.is_simulation_done = True self.simulation_cancelled.emit() run_dialog.cancelled.connect(on_cancel) # Launch simulation and watch filesystem to monitor simulation filelist = [f for f in os.listdir(Case.the().path + "/" + Case.the().name + "_out/") if f.startswith("Part")] for f in filelist: os.remove(Case.the().path + "/" + Case.the().name + "_out/" + f) def on_dsph_sim_finished(exit_code): """ Simulation finish handler. Defines what happens when the process finishes.""" # Reads output and completes the progress bar output = str(process.readAllStandardOutput().data(), encoding='utf-8') run_dialog.set_detail_text(str(output)) run_dialog.run_complete() run_fs_watcher.removePath(Case.the().path + "/" + Case.the().name + "_out/") if exit_code == 0: # Simulation went correctly Case.the().info.is_simulation_done = True Case.the().info.needs_to_run_gencase = False self.simulation_complete.emit(True) else: # In case of an error Case.the().info.needs_to_run_gencase = True if "exception" in str(output).lower(): log("There was an error on the execution. Opening an error dialog for that.") run_dialog.hide() self.simulation_complete.emit(False) error_dialog(__("An error occurred during execution. Make sure that parameters exist and are properly defined. " "You can also check your execution device (update the driver of your GPU). Read the details for more information."), str(output)) save_case(Case.the().path, Case.the()) # Launches a QProcess in background process = QtCore.QProcess(get_fc_main_window()) process.finished.connect(on_dsph_sim_finished) process.start(Case.the().executable_paths.dsphysics, final_params_ex) def on_fs_change(): """ Executed each time the filesystem changes. This updates the percentage of the simulation and its details.""" run_file_data = "" with open(Case.the().path + "/" + Case.the().name + "_out/Run.out", "r") as run_file: run_file_data = run_file.readlines() # Fill details window run_dialog.set_detail_text("".join(run_file_data)) # Set percentage scale based on timemax for l in run_file_data: if Case.the().execution_parameters.timemax == -1: if "TimeMax=" in l: Case.the().execution_parameters.timemax = float(l.split("=")[1]) current_value: float = 0.0 totalpartsout: int = 0 last_estimated_time = None # Update execution metrics last_part_lines = list(filter(lambda x: "Part_" in x and "stored" not in x and " " in x, run_file_data)) if last_part_lines: current_value = (float(last_part_lines[-1].split(None)[1]) * float(100)) / float(Case.the().execution_parameters.timemax) else: current_value = None # Update particles out last_particles_out_lines = list(filter(lambda x: "(total: " in x and "Particles out:" in x, run_file_data)) if last_particles_out_lines: totalpartsout = int(last_particles_out_lines[-1].split("(total: ")[1].split(")")[0]) try: last_estimated_time = str(" ".join(last_part_lines[-1].split(None)[-2:])) except IndexError: last_estimated_time = None # Update run dialog run_dialog.run_update(current_value, totalpartsout, last_estimated_time) # Set filesystem watcher to the out directory. run_fs_watcher.addPath(Case.the().path + "/" + Case.the().name + "_out/") run_fs_watcher.directoryChanged.connect(on_fs_change) # Handle error on simulation start if process.state() == QtCore.QProcess.NotRunning: # Probably error happened. run_fs_watcher.removePath(Case.the().path + "/" + Case.the().name + "_out/") process = None error_dialog("Error on simulation start. Check that the DualSPHysics executable is correctly set.") else: run_dialog.show()
def __init__(self, link_spheric_id, bodies_widgets, parent=None): super().__init__(parent=parent) self.case = Case.the() self.link_spheric_id = link_spheric_id # Title self.setWindowTitle(__("Link spheric configuration")) self.link_spheric_edit_layout = QtGui.QVBoxLayout() # Find the link spheric for which the button was pressed target_link_spheric = None for link_spheric in self.case.chrono.link_spheric: if link_spheric.id == self.link_spheric_id: target_link_spheric = link_spheric # This should not happen but if no link spheric is found with reference id, it spawns an error. if target_link_spheric is None: error_dialog("There was an error opnening the link spheric to edit") return # Elements that interact self.body_layout = QtGui.QHBoxLayout() self.body_one_label = QtGui.QLabel(__("Body 1: ")) self.body_one_line_edit = QtGui.QComboBox() if str(target_link_spheric.idbody1) != "": self.body_one_line_edit.insertItems(0, ["", str(target_link_spheric.idbody1)]) self.body_one_line_edit.setCurrentIndex(1) else: self.body_one_line_edit.insertItems(0, [str(target_link_spheric.idbody1)]) for body in bodies_widgets: if body.object_check.isChecked() and body.object_name != str(target_link_spheric.idbody1): self.body_one_line_edit.insertItems(0, [body.object_name]) self.body_two_label = QtGui.QLabel(__("Body 2: ")) self.body_two_line_edit = QtGui.QComboBox() if str(target_link_spheric.idbody2) != "": self.body_two_line_edit.insertItems(0, ["", str(target_link_spheric.idbody2)]) self.body_two_line_edit.setCurrentIndex(1) else: self.body_two_line_edit.insertItems(0, [str(target_link_spheric.idbody2)]) for body in bodies_widgets: if body.object_check.isChecked() and body.object_name != str(target_link_spheric.idbody2): self.body_two_line_edit.insertItems(0, [body.object_name]) self.body_to_body_label = QtGui.QLabel(__("to")) self.body_layout.addWidget(self.body_one_label) self.body_layout.addWidget(self.body_one_line_edit) self.body_layout.addWidget(self.body_to_body_label) self.body_layout.addWidget(self.body_two_label) self.body_layout.addWidget(self.body_two_line_edit) self.body_layout.addStretch(1) self.link_spheric_edit_layout.addLayout(self.body_layout) # Points where the elements interact self.points_layout = QtGui.QHBoxLayout() self.points_label = QtGui.QLabel(__("Points: ")) self.point_x_label = QtGui.QLabel(__("X")) self.point_x_line_edit = QtGui.QLineEdit(str(target_link_spheric.rotpoint[0])) self.point_y_label = QtGui.QLabel(__("Y")) self.point_y_line_edit = QtGui.QLineEdit(str(target_link_spheric.rotpoint[1])) self.point_z_label = QtGui.QLabel(__("Z")) self.point_z_line_edit = QtGui.QLineEdit(str(target_link_spheric.rotpoint[2])) self.points_layout.addWidget(self.points_label) self.points_layout.addWidget(self.point_x_label) self.points_layout.addWidget(self.point_x_line_edit) self.points_layout.addWidget(self.point_y_label) self.points_layout.addWidget(self.point_y_line_edit) self.points_layout.addWidget(self.point_z_label) self.points_layout.addWidget(self.point_z_line_edit) self.link_spheric_edit_layout.addLayout(self.points_layout) # Torsion options self.torsion_stiffness_layout = QtGui.QHBoxLayout() self.torsion_damping_layout = QtGui.QHBoxLayout() self.stiffness_label = QtGui.QLabel(__("Stiffness (Nm/rad):")) self.stiffness_line_edit = QtGui.QLineEdit(str(target_link_spheric.stiffness)) self.damping_label = QtGui.QLabel(__("Damping (Nms/rad):")) self.damping_line_edit = QtGui.QLineEdit(str(target_link_spheric.damping)) self.torsion_stiffness_layout.addWidget(self.stiffness_label) self.torsion_stiffness_layout.addWidget(self.stiffness_line_edit) self.torsion_damping_layout.addWidget(self.damping_label) self.torsion_damping_layout.addWidget(self.damping_line_edit) self.link_spheric_edit_layout.addLayout(self.torsion_stiffness_layout) self.link_spheric_edit_layout.addLayout(self.torsion_damping_layout) # Buttons self.ok_button = QtGui.QPushButton("Save") self.ok_button.clicked.connect(self.on_save) self.cancel_button = QtGui.QPushButton("Cancel") self.cancel_button.clicked.connect(self.on_cancel) self.button_layout = QtGui.QHBoxLayout() self.button_layout.addStretch(1) self.button_layout.addWidget(self.ok_button) self.button_layout.addWidget(self.cancel_button) self.link_spheric_edit_layout.addLayout(self.button_layout) # Add the elements to the window self.setLayout(self.link_spheric_edit_layout) self.exec_()
def __init__(self, parent=None): super().__init__(parent=parent) self.main_layout = QtGui.QVBoxLayout() self.main_layout.setContentsMargins(0, 0, 0, 0) self.label_layout = QtGui.QHBoxLayout() self.first_row_layout = QtGui.QHBoxLayout() self.second_row_layout = QtGui.QHBoxLayout() self.third_row_layout = QtGui.QHBoxLayout() self.fourth_row_layout = QtGui.QHBoxLayout() self.casecontrols_label = QtGui.QLabel("<b>{}</b>".format( __("Pre-processing"))) self.force_button = QtGui.QPushButton(__("Force Enable Panels")) self.force_button.setStyleSheet( "font-size: 8px; max-height: 10px; padding-bottom: 0; padding-top: 0; padding-left:2px; padding-right: 2px" ) self.new_case_button = QtGui.QToolButton() self.new_case_button.setPopupMode(QtGui.QToolButton.MenuButtonPopup) self.new_case_button.setToolButtonStyle( QtCore.Qt.ToolButtonTextBesideIcon) self.new_case_button.setText(" {}".format(__("New\n Case"))) self.new_case_button.setToolTip( __("Creates a new case. \nThe opened documents will be closed.")) self.new_case_button.setIcon( QtGui.QIcon.fromTheme("document-new", get_icon("new.png"))) self.new_case_button.setIconSize(QtCore.QSize(28, 28)) self.new_case_menu = QtGui.QMenu() self.new_case_menu.addAction( QtGui.QIcon.fromTheme("document-new", get_icon("new.png")), __("New")) self.new_case_menu.addAction( QtGui.QIcon.fromTheme("document-new", get_icon("new.png")), __("Import FreeCAD Document")) self.new_case_button.setMenu(self.new_case_menu) self.new_case_menu.resize(60, 60) self.save_button = QtGui.QToolButton() self.save_button.setPopupMode(QtGui.QToolButton.MenuButtonPopup) self.save_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.save_button.setText(" {}".format(__("Save\n Case"))) self.save_button.setToolTip(__("Saves the case.")) self.save_button.setIcon( QtGui.QIcon.fromTheme("document-save", get_icon("save.png"))) self.save_button.setIconSize(QtCore.QSize(28, 28)) self.save_menu = QtGui.QMenu() self.save_menu.addAction( QtGui.QIcon.fromTheme("document-save-as", get_icon("save.png")), __("Save as...")) self.save_button.setMenu(self.save_menu) self.load_button = QtGui.QToolButton() self.load_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.load_button.setText(" {}".format(__("Load\n Case"))) self.load_button.setToolTip( __("Loads a case from disk. All the current documents\nwill be closed." )) self.load_button.setIcon( QtGui.QIcon.fromTheme("document-open", get_icon("load.png"))) self.load_button.setIconSize(QtCore.QSize(28, 28)) self.add_fillbox_button = QtGui.QPushButton(__("Add fillbox")) self.add_fillbox_button.setToolTip( __("Adds a FillBox. A FillBox is able to fill an empty space\nwithin limits of geometry and a maximum bounding\nbox placed by the user." )) self.add_fillbox_button.setIcon(QtGui.QIcon.fromTheme("list-add")) self.add_geometry_button = QtGui.QPushButton("Import GEO") self.add_geometry_button.setToolTip( __("Imports a GEO object with postprocessing. This way you can set the scale of the imported object." )) self.add_geometry_button.setIcon(QtGui.QIcon.fromTheme("list-add")) self.import_xml_button = QtGui.QPushButton(__("Import XML")) self.import_xml_button.setToolTip( __("Imports an already created XML case from disk.")) self.case_summary_button = QtGui.QPushButton(__("Case summary")) self.case_summary_button.setToolTip( __("Shows a complete case summary with objects, configurations and settings in a brief view." )) self.case_summary_button.setIcon( QtGui.QIcon.fromTheme("document-properties")) self.toggle_2d_mode_button = QtGui.QPushButton(__("Change 3D/2D")) self.toggle_2d_mode_button.setToolTip( __("Changes the case mode between 2D and 3D mode, switching the Case Limits between a plane or a cube" )) self.toggle_2d_mode_button.setIcon( QtGui.QIcon.fromTheme("object-flip-horizontal")) self.special_button = QtGui.QPushButton(__("Special")) self.special_button.setToolTip(__("Special actions for the case.")) self.special_button.setIcon(QtGui.QIcon.fromTheme("window-new")) self.gencase_button = QtGui.QPushButton(__("Run GenCase")) self.gencase_button.setStyleSheet("QPushButton {font-weight: bold; }") self.gencase_button.setToolTip( __("This pre-processing tool creates the initial state of the particles (position, velocity and density) and defines the different SPH parameters for the simulation." )) self.gencase_button.setIcon(get_icon("run_gencase.png")) self.gencase_button.setIconSize(QtCore.QSize(12, 12)) self.force_button.clicked.connect(self.on_force_button) self.new_case_button.clicked.connect(lambda: self.on_new_case(True)) self.save_button.clicked.connect(self.on_save_case) self.gencase_button.clicked.connect(self.on_execute_gencase) self.new_case_menu.triggered.connect(self.on_newdoc_menu) self.save_menu.triggered.connect(self.on_save_menu) self.load_button.clicked.connect(self.on_load_button) self.add_fillbox_button.clicked.connect(self.on_add_fillbox) self.add_geometry_button.clicked.connect(self.on_add_geo) self.import_xml_button.clicked.connect(lambda: error_dialog( "XML Import is not available in this version.")) self.case_summary_button.clicked.connect(CaseSummary) self.toggle_2d_mode_button.clicked.connect(self.on_2d_toggle) self.special_button.clicked.connect(SpecialOptionsSelectorDialog) self.label_layout.addWidget(self.casecontrols_label) self.label_layout.addStretch(1) self.label_layout.addWidget(self.force_button) self.first_row_layout.addWidget(self.new_case_button) self.first_row_layout.addWidget(self.save_button) self.first_row_layout.addWidget(self.load_button) self.second_row_layout.addWidget(self.case_summary_button) self.second_row_layout.addWidget(self.toggle_2d_mode_button) self.third_row_layout.addWidget(self.add_fillbox_button) self.third_row_layout.addWidget(self.add_geometry_button) # self.third_row_layout.addWidget(self.import_xml_button) self.fourth_row_layout.addWidget(self.special_button) self.fourth_row_layout.addWidget(self.gencase_button) self.main_layout.addLayout(self.label_layout) self.main_layout.addLayout(self.first_row_layout) self.main_layout.addLayout(self.third_row_layout) self.main_layout.addLayout(self.second_row_layout) self.main_layout.addLayout(self.fourth_row_layout) self.setLayout(self.main_layout)
def on_multilayeredmb_menu(self, action): """ Defines MLPiston menu behaviour""" # Get currently selected object try: selection = FreeCADGui.Selection.getSelection()[0] except IndexError: error_dialog(__("You must select an object")) return # Check if object is in the simulation if not Case.the().is_object_in_simulation(selection.Name): error_dialog( __("The selected object must be added to the simulation")) return # Check if it is fluid and warn the user. if Case.the().get_simulation_object( selection.Name).type == ObjectType.FLUID: error_dialog( __("You can't apply a piston movement to a fluid.\nPlease select a boundary and try again" )) return # Get selection mk selection_obj = Case.the().get_simulation_object(selection.Name) selection_mk: int = selection_obj.obj_mk mk_properties: MKBasedProperties = Case.the().get_mk_based_properties( selection_obj.type, selection_mk) # Check that this mk has no other motions applied if mk_properties.has_movements(): # MK has motions applied. Warn the user and delete them motion_delete_warning = ok_cancel_dialog( APP_NAME, __("This mk already has motions applied. Setting a Multi-layered piston will delete all of its movement. Are you sure?" )) if motion_delete_warning == QtGui.QMessageBox.Cancel: return mk_properties.remove_all_movements() # 1D or 2D piston if __("1 Dimension") in action.text(): if mk_properties.mlayerpiston and not isinstance( mk_properties.mlayerpiston, MLPiston1D): overwrite_warn = ok_cancel_dialog( APP_NAME, __("You're about to overwrite a previous coupling movement for this mk. Are you sure?" )) if overwrite_warn == QtGui.QMessageBox.Cancel: return config_dialog = MLPiston1DConfigDialog(selection_mk, mk_properties.mlayerpiston, parent=get_fc_main_window()) if config_dialog.result() == QtGui.QDialog.Accepted: warning_dialog( __("All changes have been applied for mk = {}").format( selection_mk)) mk_properties.mlayerpiston = config_dialog.mlpiston1d if __("2 Dimensions") in action.text(): # Check that there's no other multilayered piston for this mk if mk_properties.mlayerpiston and not isinstance( mk_properties.mlayerpiston, MLPiston2D): overwrite_warn = ok_cancel_dialog( APP_NAME, __("You're about to overwrite a previous coupling movement for this mk. Are you sure?" )) if overwrite_warn == QtGui.QMessageBox.Cancel: return config_dialog = MLPiston2DConfigDialog(selection_mk, mk_properties.mlayerpiston, parent=get_fc_main_window()) if config_dialog.result() == QtGui.QDialog.Accepted: warning_dialog( __("All changes have been applied for mk = {}").format( selection_mk)) mk_properties.mlayerpiston = config_dialog.mlpiston2d self.accept()
# Probably already copied the file. pass except IOError: error("Unable to copy {} into {}".format(filename, save_name)) # Dumps all the case data to an XML file. XMLExporter().save_to_disk(save_name, case) case.version = VERSION # Save data array on disk. It is saved as a binary file with Pickle. try: with open(save_name + "/casedata.dsphdata", "wb") as picklefile: pickle.dump(case, picklefile, PICKLE_PROTOCOL) except Exception: print_exc() error_dialog(__("There was a problem saving the DSPH information file (casedata.dsphdata).")) refocus_cwd() def get_default_config_file(): """ Gets the default-config.json from disk """ current_script_folder = path.dirname(path.realpath(__file__)) with open("{}/../default-config.json".format(current_script_folder)) as data_file: loaded_data = json.load(data_file) if "win" in platform: to_ret = loaded_data["windows"] elif "linux" in platform: to_ret = loaded_data["linux"]
def __init__(self, link_pointline_id, bodies_widgets, parent=None): super().__init__(parent=parent) self.case = Case.the() self.link_pointline_id = link_pointline_id # Title self.setWindowTitle(__("Link pointline configuration")) self.link_pointline_edit_layout = QtGui.QVBoxLayout() # Find the link pointline for which the button was pressed target_link_pointline = None for link_pointline in self.case.chrono.link_pointline: if link_pointline.id == self.link_pointline_id: target_link_pointline = link_pointline # This should not happen but if no link pointline is found with reference id, it spawns an error. if target_link_pointline is None: error_dialog("There was an error opnening the link pointline to edit") return # Elements that interact self.body_layout = QtGui.QHBoxLayout() self.body_one_label = QtGui.QLabel(__("Body 1: ")) self.body_one_line_edit = QtGui.QComboBox() if str(target_link_pointline.idbody1) != "": self.body_one_line_edit.insertItems(0, ["", str(target_link_pointline.idbody1)]) self.body_one_line_edit.setCurrentIndex(1) else: self.body_one_line_edit.insertItems(0, [str(target_link_pointline.idbody1)]) for body in bodies_widgets: if body.object_check.isChecked() and body.object_name != str(target_link_pointline.idbody1): self.body_one_line_edit.insertItems(0, [body.object_name]) self.body_layout.addWidget(self.body_one_label) self.body_layout.addWidget(self.body_one_line_edit) self.body_layout.addStretch(1) self.link_pointline_edit_layout.addLayout(self.body_layout) # Vector direction for sliding axis self.sliding_vector_layout = QtGui.QHBoxLayout() self.sliding_vector_label = QtGui.QLabel(__("Sliding Vector: ")) self.sliding_vector_x_label = QtGui.QLabel(__("X")) self.sliding_vector_x_line_edit = QtGui.QLineEdit(str(target_link_pointline.slidingvector[0])) self.sliding_vector_y_label = QtGui.QLabel(__("Y")) self.sliding_vector_y_line_edit = QtGui.QLineEdit(str(target_link_pointline.slidingvector[1])) self.sliding_vector_z_label = QtGui.QLabel(__("Z")) self.sliding_vector_z_line_edit = QtGui.QLineEdit(str(target_link_pointline.slidingvector[2])) self.sliding_vector_layout.addWidget(self.sliding_vector_label) self.sliding_vector_layout.addWidget(self.sliding_vector_x_label) self.sliding_vector_layout.addWidget(self.sliding_vector_x_line_edit) self.sliding_vector_layout.addWidget(self.sliding_vector_y_label) self.sliding_vector_layout.addWidget(self.sliding_vector_y_line_edit) self.sliding_vector_layout.addWidget(self.sliding_vector_z_label) self.sliding_vector_layout.addWidget(self.sliding_vector_z_line_edit) self.link_pointline_edit_layout.addLayout(self.sliding_vector_layout) # Point for rotation self.rotpoint_layout = QtGui.QHBoxLayout() self.rotpoint_label = QtGui.QLabel(__("Point for rotation: ")) self.rotpoint_x_label = QtGui.QLabel(__("X")) self.rotpoint_x_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotpoint[0])) self.rotpoint_y_label = QtGui.QLabel(__("Y")) self.rotpoint_y_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotpoint[1])) self.rotpoint_z_label = QtGui.QLabel(__("Z")) self.rotpoint_z_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotpoint[2])) self.rotpoint_layout.addWidget(self.rotpoint_label) self.rotpoint_layout.addWidget(self.rotpoint_x_label) self.rotpoint_layout.addWidget(self.rotpoint_x_line_edit) self.rotpoint_layout.addWidget(self.rotpoint_y_label) self.rotpoint_layout.addWidget(self.rotpoint_y_line_edit) self.rotpoint_layout.addWidget(self.rotpoint_z_label) self.rotpoint_layout.addWidget(self.rotpoint_z_line_edit) self.link_pointline_edit_layout.addLayout(self.rotpoint_layout) # Vector direction for rotation self.rotvector_layout = QtGui.QHBoxLayout() self.rotvector_label = QtGui.QLabel(__("Vector direction: ")) self.rotvector_x_label = QtGui.QLabel(__("X")) self.rotvector_x_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotvector[0])) self.rotvector_y_label = QtGui.QLabel(__("Y")) self.rotvector_y_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotvector[1])) self.rotvector_z_label = QtGui.QLabel(__("Z")) self.rotvector_z_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotvector[2])) self.rotvector_layout.addWidget(self.rotvector_label) self.rotvector_layout.addWidget(self.rotvector_x_label) self.rotvector_layout.addWidget(self.rotvector_x_line_edit) self.rotvector_layout.addWidget(self.rotvector_y_label) self.rotvector_layout.addWidget(self.rotvector_y_line_edit) self.rotvector_layout.addWidget(self.rotvector_z_label) self.rotvector_layout.addWidget(self.rotvector_z_line_edit) self.link_pointline_edit_layout.addLayout(self.rotvector_layout) # Second vector to avoid rotation self.rotvector2_layout = QtGui.QHBoxLayout() self.rotvector2_label = QtGui.QLabel(__("Second vector: ")) self.rotvector2_x_label = QtGui.QLabel(__("X")) self.rotvector2_x_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotvector2[0])) self.rotvector2_y_label = QtGui.QLabel(__("Y")) self.rotvector2_y_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotvector2[1])) self.rotvector2_z_label = QtGui.QLabel(__("Z")) self.rotvector2_z_line_edit = QtGui.QLineEdit(str(target_link_pointline.rotvector2[2])) self.rotvector2_layout.addWidget(self.rotvector2_label) self.rotvector2_layout.addWidget(self.rotvector2_x_label) self.rotvector2_layout.addWidget(self.rotvector2_x_line_edit) self.rotvector2_layout.addWidget(self.rotvector2_y_label) self.rotvector2_layout.addWidget(self.rotvector2_y_line_edit) self.rotvector2_layout.addWidget(self.rotvector2_z_label) self.rotvector2_layout.addWidget(self.rotvector2_z_line_edit) self.link_pointline_edit_layout.addLayout(self.rotvector2_layout) # Torsion options self.torsion_stiffness_layout = QtGui.QHBoxLayout() self.torsion_damping_layout = QtGui.QHBoxLayout() self.stiffness_label = QtGui.QLabel(__("Stiffness")) self.stiffness_line_edit = QtGui.QLineEdit(str(target_link_pointline.stiffness)) self.damping_label = QtGui.QLabel(__("Damping")) self.damping_line_edit = QtGui.QLineEdit(str(target_link_pointline.damping)) self.torsion_stiffness_layout.addWidget(self.stiffness_label) self.torsion_stiffness_layout.addWidget(self.stiffness_line_edit) self.torsion_damping_layout.addWidget(self.damping_label) self.torsion_damping_layout.addWidget(self.damping_line_edit) self.link_pointline_edit_layout.addLayout(self.torsion_stiffness_layout) self.link_pointline_edit_layout.addLayout(self.torsion_damping_layout) # Buttons self.ok_button = QtGui.QPushButton("Save") self.ok_button.clicked.connect(self.on_save) self.cancel_button = QtGui.QPushButton("Cancel") self.cancel_button.clicked.connect(self.on_cancel) self.button_layout = QtGui.QHBoxLayout() self.button_layout.addStretch(1) self.button_layout.addWidget(self.ok_button) self.button_layout.addWidget(self.cancel_button) self.link_pointline_edit_layout.addLayout(self.button_layout) # Add the elements to the window self.setLayout(self.link_pointline_edit_layout) self.exec_()