コード例 #1
0
    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)
コード例 #2
0
    def on_add_geo(self):
        """ Add STL file. Opens a file opener and allows the user to set parameters for the import process """
        self.need_refresh.emit()

        file_name, _ = QtGui.QFileDialog().getOpenFileName(
            get_fc_main_window(), __("Select GEO to import"),
            Case.the().info.last_used_directory,
            "STL Files (*.stl);;PLY Files (*.ply);;VTK Files (*.vtk)")
        Case.the().info.update_last_used_directory(file_name)
        if not file_name:
            return
        AddGEODialog(file_name, parent=get_fc_main_window())
 def on_nnparameters_button(self):
     """ Defines nnparameters button behaviour"""
     if Case.the().executable_paths.dsphysics.find('NNewtonian') == -1:
         warning_dialog(
             __("DualSPHysics executable is not set as Non-Newtonian!"))
     else:
         NonNewtonianDialog(parent=get_fc_main_window())
         self.accept()
 def on_lsparameters_button(self):
     """ Defines lsparameters button behaviour"""
     if Case.the().executable_paths.dsphysics.find('LiquidSediment') == -1:
         warning_dialog(
             __("DualSPHysics executable is not set as Liquid-Sediment!"))
     else:
         LiquidSedimentDialog(parent=get_fc_main_window())
         self.accept()
コード例 #5
0
    def __init__(self, parent=None):
        super().__init__(parent=parent)

        # Post processing section scaffolding
        self.main_layout = QtGui.QVBoxLayout()
        self.main_layout.setContentsMargins(0, 0, 0, 0)

        self.title_label = QtGui.QLabel("<b>{}</b>".format(__("Post-processing")))
        self.title_label.setWordWrap(True)

        self.first_row_layout = QtGui.QHBoxLayout()
        self.second_row_layout = QtGui.QHBoxLayout()

        self.partvtk_button = QtGui.QPushButton(__("PartVTK"))
        self.computeforces_button = QtGui.QPushButton(__("ComputeForces"))
        self.isosurface_button = QtGui.QPushButton(__("IsoSurface"))
        self.floatinginfo_button = QtGui.QPushButton(__("FloatingInfo"))
        self.measuretool_button = QtGui.QPushButton(__("MeasureTool"))
        self.flowtool_button = QtGui.QPushButton(__("FlowTool"))

        self.partvtk_button.setToolTip(__("Opens the PartVTK tool."))
        self.computeforces_button.setToolTip(__("Opens the ComputeForces tool."))
        self.floatinginfo_button.setToolTip(__("Opens the FloatingInfo tool."))
        self.measuretool_button.setToolTip(__("Opens the MeasureTool tool."))
        self.isosurface_button.setToolTip(__("Opens the IsoSurface tool."))
        self.flowtool_button.setToolTip(__("Opens the FlowTool tool."))

        self.partvtk_button.clicked.connect(lambda: PartVTKDialog(self, parent=get_fc_main_window()))
        self.computeforces_button.clicked.connect(lambda: ComputeForcesDialog(self, parent=get_fc_main_window()))
        self.floatinginfo_button.clicked.connect(lambda: FloatingInfoDialog(self, parent=get_fc_main_window()))
        self.measuretool_button.clicked.connect(lambda: MeasureToolDialog(self, parent=get_fc_main_window()))
        self.isosurface_button.clicked.connect(lambda: IsoSurfaceDialog(self, parent=get_fc_main_window()))
        self.flowtool_button.clicked.connect(lambda: FlowToolDialog(self, parent=get_fc_main_window()))

        self.main_layout.addWidget(self.title_label)
        self.first_row_layout.addWidget(self.partvtk_button)
        self.first_row_layout.addWidget(self.computeforces_button)
        self.first_row_layout.addWidget(self.isosurface_button)
        self.second_row_layout.addWidget(self.floatinginfo_button)
        self.second_row_layout.addWidget(self.measuretool_button)
        self.second_row_layout.addWidget(self.flowtool_button)

        self.main_layout.addLayout(self.first_row_layout)
        self.main_layout.addLayout(self.second_row_layout)

        self.setLayout(self.main_layout)
 def on_damping_option(self):
     """ Defines damping button behaviour"""
     damping_group_name = setup_damping_environment()
     Case.the().add_damping_group(damping_group_name)
     DampingConfigDialog(damping_group_name,
                         Case.the(),
                         parent=get_fc_main_window())
     self.accept()
コード例 #7
0
def mksmixing_export(obj, post_processing_widget, case) -> None:
    """ MKsMixing tool export. """
    post_processing_widget.adapt_to_export_start()

    exported_parts: int = get_total_exported_parts_from_disk(
        case.get_out_folder_path())

    export_dialog = ExportProgressDialog(0,
                                         exported_parts,
                                         parent=get_fc_main_window())
    export_dialog.show()

    case.info.current_output = ""

    executable_parameters = [
        case.get_out_folder_path(), obj["step"], obj["init"], obj["mk"],
        obj["dp"], obj["cdp"], obj["tout"], obj["n1"], obj["n2"], obj["n3"],
        obj["calc"], obj["vtk"]
    ]

    def on_stdout_ready():
        """ Updates the export dialog on every stdout available from the process. """
        current_output = str(export_process.readAllStandardOutput().data(),
                             encoding='utf-8')
        case.info.current_output += current_output
        try:
            current_part = int(current_output.split()[1])
        except:
            current_part = export_dialog.get_value()
        export_dialog.update_data(current_part)

    def on_cancel():
        """ Kills the process and cancels the export dialog. """
        export_process.kill()
        post_processing_widget.adapt_to_export_finished()
        export_dialog.reject()

    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.custom.mksmixing, " ".join(executable_parameters),
            case.info.current_output)

        if not exit_code:
            info_dialog(info_text=__("MKsMixing finished successfully"),
                        detailed_text=detailed_text)
            if case.custom.mksmixing_plot:
                MKsMixingPlotDialog(
                    parent=post_processing_widget,
                    paths=[
                        "{out_path}{file_name}.csv".format(
                            out_path=case.get_out_folder_path(),
                            file_name="MKsMixing")
                    ])

        else:
コード例 #8
0
    def refresh_movements_table(self):
        """ Refreshes the movement table. """
        self.movement_list_table.clearContents()
        self.movement_list_table.setRowCount(
            len(Case.the().info.global_movements) + 1)
        current_row = 0
        for movement in Case.the().info.global_movements:
            self.movement_list_table.setItem(
                current_row, 0, QtGui.QTableWidgetItem(movement.name))
            try:
                has_loop = movement.loop
            except AttributeError:
                has_loop = False
            if isinstance(movement, Movement):
                movement_actions = MovementActions(current_row,
                                                   movement
                                                   in self.movements_selected,
                                                   has_loop,
                                                   parent=get_fc_main_window())
                movement_actions.loop.connect(self.on_loop_movement)
            elif isinstance(movement, SpecialMovement):
                movement_actions = WaveMovementActions(
                    current_row,
                    movement in self.movements_selected,
                    parent=get_fc_main_window())

            movement_actions.delete.connect(self.on_delete_movement)
            movement_actions.use.connect(self.on_check_movement)
            self.movement_list_table.setCellWidget(current_row, 1,
                                                   movement_actions)

            current_row += 1

        try:
            self.create_new_movement_button.clicked.disconnect()
            self.create_new_movement_menu.triggered.disconnect()
        except RuntimeError:
            # Nothing connected yet.
            pass

        self.create_new_movement_button.clicked.connect(self.on_new_movement)
        self.create_new_movement_menu.triggered.connect(
            self.on_new_wave_generator)

        self.movement_list_table.setCellWidget(current_row, 0, QtGui.QWidget())
    def on_accinput_button(self):
        """ Acceleration input button behaviour."""
        accinput_dialog = AccelerationInputDialog(
            Case.the().acceleration_input, parent=get_fc_main_window())
        result = accinput_dialog.exec_()

        if result == QtGui.QDialog.Accepted:
            Case.the().acceleration_input = accinput_dialog.get_result()
        self.accept()
コード例 #10
0
 def link_pulley_edit(self, link_pulley_id):
     """ Edit a link pulley element """
     selected_chrono_object_widgets = list(
         filter(lambda x: x.object_check.isChecked(),
                self.chrono_object_options_widgets))
     LinkPulleyEdit(link_pulley_id=link_pulley_id,
                    bodies_widgets=selected_chrono_object_widgets,
                    parent=get_fc_main_window())
     self.refresh_link_pulley()
コード例 #11
0
 def link_coulombdamping_edit(self, link_coulombdamping_id):
     """ Edit a link coulombdamping element """
     selected_chrono_object_widgets = list(
         filter(lambda x: x.object_check.isChecked(),
                self.chrono_object_options_widgets))
     LinkCoulombDampingEdit(link_coulombdamping_id=link_coulombdamping_id,
                            bodies_widgets=selected_chrono_object_widgets,
                            parent=get_fc_main_window())
     self.refresh_link_coulombdamping()
コード例 #12
0
    def __init__(self, parent=None):
        super().__init__(parent=parent)

        self.setObjectName(MAIN_WIDGET_INTERNAL_NAME)
        self.setWindowTitle("{} {}".format(APP_NAME, str(VERSION)))

        self.root_widget = QtGui.QWidget()
        self.main_layout = QtGui.QVBoxLayout()
        self.main_layout.setContentsMargins(5, 0, 5, 0)

        self.dock_logo_widget = DockLogoWidget(parent=get_fc_main_window())
        self.dock_configuration_widget = DockConfigurationWidget(
            parent=get_fc_main_window())
        self.dp_widget = DockDPWidget(parent=get_fc_main_window())
        self.pre_proccessing_widget = DockPreProcessingWidget(
            parent=get_fc_main_window())
        self.simulation_widget = DockSimulationWidget(
            parent=get_fc_main_window())
        self.post_processing_widget = DockPostProcessingWidget(
            parent=get_fc_main_window())
        self.object_list_widget = DockObjectListTableWidget(
            parent=get_fc_main_window())

        self.main_layout.addWidget(self.dock_logo_widget)
        self.main_layout.addWidget(h_line_generator())
        self.main_layout.addWidget(self.dock_configuration_widget)
        self.main_layout.addWidget(h_line_generator())
        self.main_layout.addWidget(self.dp_widget)
        self.main_layout.addWidget(h_line_generator())
        self.main_layout.addWidget(self.pre_proccessing_widget)
        self.main_layout.addWidget(h_line_generator())
        self.main_layout.addWidget(self.simulation_widget)
        self.main_layout.addWidget(h_line_generator())
        self.main_layout.addWidget(self.post_processing_widget)
        self.main_layout.addWidget(h_line_generator())
        self.main_layout.addWidget(self.object_list_widget)

        self.root_widget.setLayout(self.main_layout)
        self.setWidget(self.root_widget)

        self.adapt_to_no_case()

        # Signal handling
        self.pre_proccessing_widget.force_pressed.connect(
            self.on_preprocessing_force_pressed)
        self.pre_proccessing_widget.need_refresh.connect(self.on_refresh)
        self.pre_proccessing_widget.update_dp.connect(self.on_signal_update_dp)
        self.pre_proccessing_widget.case_created.connect(
            self.adapt_to_new_case)
        self.pre_proccessing_widget.gencase_completed.connect(
            self.adapt_to_gencase_done)
        self.pre_proccessing_widget.simulation_completed.connect(
            self.adapt_to_simulation_done)
        self.simulation_widget.simulation_complete.connect(
            self.adapt_to_simulation_done)
        self.simulation_widget.simulation_started.connect(
            self.adapt_to_simulation_start)
        self.simulation_widget.simulation_cancelled.connect(
            self.adapt_to_simulation_cancel)
コード例 #13
0
 def geo_dialog_browse(self):
     """ Defines the browse button behaviour."""
     file_name_temp, _ = QtGui.QFileDialog().getOpenFileName(
         get_fc_main_window(), __("Select GEO to import"),
         Case.the().info.last_used_directory,
         "STL Files (*.stl);;PLY Files (*.ply);;VTK Files (*.vtk)")
     Case.the().info.update_last_used_directory(file_name_temp)
     if file_name_temp:
         self.geo_file_path.setText(file_name_temp)
     self.raise_()
     self.activateWindow()
     self.geo_button_ok.setFocus()
コード例 #14
0
def boundaryvtk_export(obj, post_processing_widget, case) -> None:
    """ BoundaryVTK tool export. """
    post_processing_widget.adapt_to_export_start()

    exported_parts: int = get_total_exported_parts_from_disk(
        case.get_out_folder_path())

    export_dialog = ExportProgressDialog(0,
                                         exported_parts,
                                         parent=get_fc_main_window())
    export_dialog.show()

    case.info.current_output = ""

    # Eventually clear previous files
    if os.path.isdir("{out_path}{file_name}".format(
            out_path=case.get_out_folder_path(), file_name=obj['name'])):
コード例 #15
0
    def on_new_from_freecad_document(self, prompt=True):
        """ Creates a new case based on an existing FreeCAD document.
        This is specially useful for CAD users that want to use existing geometry for DesignSPHysics. """
        file_name, _ = QtGui.QFileDialog().getOpenFileName(
            get_fc_main_window(), "Select document to import",
            Case.the().info.last_used_directory)
        Case.the().info.update_last_used_directory(file_name)
        if file_name and document_count(
        ) and not prompt_close_all_documents(prompt):
            return

        create_dsph_document_from_fcstd(file_name)
        Case.the().reset()
        # Case.the().add_object_to_sim(SimulationObject(CASE_LIMITS_OBJ_NAME, -1, ObjectType.SPECIAL, ObjectFillMode.SPECIAL))

        self.update_dp.emit()
        self.case_created.emit()
        self.need_refresh.emit()
コード例 #16
0
    def on_2d_toggle(self):
        """ Handles Toggle 3D/2D Button. Changes the Case Limits object accordingly. """
        if not valid_document_environment():
            error("Not a valid case environment")
            return

        fc_object = get_fc_object(CASE_LIMITS_OBJ_NAME)

        if Case.the().mode3d:
            # 3D to 2D
            Case.the().info.last_3d_width = fc_object.Width.Value
            config_dialog = Mode2DConfigDialog(fc_object.Placement.Base.y,
                                               parent=get_fc_main_window())
            if config_dialog.exit_status == QtGui.QDialog.Rejected:
                return
            fc_object.Placement.Base.y = float(config_dialog.stored_y_value)
            fc_object.Label = CASE_LIMITS_2D_LABEL
            Case.the().mode3d = not Case.the().mode3d
        else:
            # 2D to 3D
            Case.the().mode3d = not Case.the().mode3d
            fc_object.Width = Case.the().info.last_3d_width if Case.the(
            ).info.last_3d_width > 0.0 else fc_object.Length
            fc_object.Label = CASE_LIMITS_3D_LABEL
コード例 #17
0
    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()
コード例 #18
0
 def on_additional_parameters(self):
     """ Handles additional parameters button for execution """
     RunAdditionalParametersDialog(parent=get_fc_main_window())
コード例 #19
0
 def box_edit(self, box_id):
     """ Box edit button behaviour. Opens a dialog to edit the selected FlowTool Box"""
     FlowToolBoxEditDialog(box_id, parent=get_fc_main_window())
     self.refresh_boxlist()
コード例 #20
0
from mod.file_tools import get_total_exported_parts_from_disk, save_measuretool_info
from mod.executable_tools import ensure_process_is_executable_or_fail

from mod.widgets.postprocessing.export_progress_dialog import ExportProgressDialog


def partvtk_export(options, case, post_processing_widget) -> None:
    """ Export VTK button behaviour. Launches a process while disabling the button. """
    post_processing_widget.adapt_to_export_start()

    save_extension: str = {0: "vtk", 1: "csv", 2: "asc"}[options["save_mode"]]
    save_flag: str = {0: "-savevtk", 1: "-savecsv", 2: "-saveascii"}[options["save_mode"]]

    exported_parts: int = get_total_exported_parts_from_disk(case.get_out_folder_path())

    export_dialog = ExportProgressDialog(0, exported_parts, parent=get_fc_main_window())
    export_dialog.show()

    case.info.current_output = ""

    # Build parameters
    executable_parameters = ["-dirin {}".format(case.get_out_folder_path()),
                             "{save_flag} {out_path}{file_name}".format(save_flag=save_flag, out_path=case.get_out_folder_path(), file_name=options["file_name"]),
                             "-onlytype:{save_types} {additional}".format(save_types=options["save_types"], additional=options["additional_parameters"])]

    # Information ready handler.
    def on_stdout_ready():
        """ Updates the export dialog on every stdout available from the process. """
        current_output = str(export_process.readAllStandardOutput().data(), encoding='utf-8')
        case.info.current_output += current_output
        try:
コード例 #21
0
    """ Export VTK button behaviour. Launches a process while disabling the button. """
    post_processing_widget.adapt_to_export_start()

    save_extension: str = {0: "vtk", 1: "csv", 2: "asc"}[options["save_mode"]]
    save_flag: str = {
        0: "-savevtk",
        1: "-savecsv",
        2: "-saveascii"
    }[options["save_mode"]]

    exported_parts: int = get_total_exported_parts_from_disk(
        case.get_out_folder_path())

    export_dialog = ExportProgressDialog(0,
                                         exported_parts,
                                         parent=get_fc_main_window())
    export_dialog.show()

    case.info.current_output = ""

    # Build parameters
    executable_parameters = [
        "-dirin {}".format(case.get_out_folder_path()),
        "{save_flag} {out_path}{file_name}".format(
            save_flag=save_flag,
            out_path=case.get_out_folder_path(),
            file_name=options["file_name"]),
        "-onlytype:{save_types} {additional}".format(
            save_types=options["save_types"],
            additional=options["additional_parameters"])
    ]
コード例 #22
0
 def on_motion_change(self):
     """ Movement configuration button behaviour. """
     MovementDialog(parent=get_fc_main_window())
コード例 #23
0
 def on_initials_change(self):
     """ Initials configuration button behaviour. """
     InitialsDialog(parent=get_fc_main_window())
コード例 #24
0
 def on_damping_config(self):
     """ Configures the damping configuration for the selected object """
     DampingConfigDialog(FreeCADGui.Selection.getSelection()[0].Name,
                         Case.the(),
                         parent=get_fc_main_window())
コード例 #25
0
 def zone_edit(self, io_id):
     """ Calls a window for edit zones """
     debug("Trying to open a zone edit for zone UUID {}".format(io_id))
     InletZoneEdit(io_id, parent=get_fc_main_window())
     self.refresh_zones()
コード例 #26
0
def boot():
    """ Boots the application. """
    print_license()
    check_compatibility()

    try:
        master_branch_version = str(
            urlopen(GITHUB_MASTER_CONSTANTS_URL).read()).split(
                "VERSION = \"")[-1].split("\"")[0]
        if VERSION < master_branch_version and NOTIFY_ON_OUTDATED_VERSION:
            info_dialog(
                __("Your version of DesignSPHyiscs is outdated. Please go to the Addon Manager and update it. New versions include bug fixes, new features and new DualSPHysics executables, among other things."
                   ),
                __("The version you're using is {} while the version that you can update to is {}"
                   ).format(VERSION, master_branch_version))
    except URLError:
        log("No network connection or Git repo is down. Skipping version check."
            )

    if document_count() > 0:
        success = prompt_close_all_documents()
        if not success:
            debug(
                "User chose not to close the currently opened documents. Aborting startup"
            )
            quit()

    # Tries to delete docks created by a previous execution of DesignSPHysics
    delete_existing_docks()

    designsphysics_dock = DesignSPHysicsDock(get_fc_main_window())
    properties_widget = PropertiesDockWidget(parent=get_fc_main_window())

    get_fc_main_window().addDockWidget(QtCore.Qt.RightDockWidgetArea,
                                       designsphysics_dock)
    get_fc_main_window().addDockWidget(QtCore.Qt.LeftDockWidgetArea,
                                       properties_widget)

    # Subscribe the FreeCAD Objects tree to the item selection change function.
    # This helps FreeCAD notify DesignSPHysics for the deleted and changed objects to get updated correctly.
    fc_object_tree: QtGui.QTreeWidget = get_fc_main_window().findChildren(
        QtGui.QSplitter)[0].findChildren(QtGui.QTreeWidget)[0]
    fc_object_tree.itemSelectionChanged.connect(
        lambda p=properties_widget, d=designsphysics_dock:
        on_tree_item_selection_change(p, d))
    debug(
        "Subscribing selection change monitor handler to freecad object tree item changed."
    )

    properties_widget.need_refresh.connect(
        lambda p=properties_widget, d=designsphysics_dock:
        on_tree_item_selection_change(p, d))
    designsphysics_dock.need_refresh.connect(
        lambda p=properties_widget, d=designsphysics_dock:
        on_tree_item_selection_change(p, d))

    # Launch a monitor thread that ensures some things are not changed.
    monitor_thread = threading.Thread(
        target=lambda p=properties_widget, d=designsphysics_dock:
        selection_monitor(p, d))
    monitor_thread.start()

    FreeCADGui.activateWorkbench(DEFAULT_WORKBENCH)
    log(__("Initialization finished for {} v{}").format(APP_NAME, VERSION))
コード例 #27
0
    def on_movement_selected(self, row, _):
        """ Shows the timeline for the selected movement. """
        try:
            self.currently_selected_movement = Case.the(
            ).info.global_movements[row]
        except IndexError:
            self.timeline_list_table.clearContents()
            self.timeline_list_table.setEnabled(False)
            self.timeline_list_table.setRowCount(1)
            self.timeline_list_table.setCellWidget(
                0, 0, MovementTimelinePlaceholder())
            return
        self.timeline_list_table.clearContents()

        # Reset the notice label if a valid change is made
        self.notice_label.setText("")

        if isinstance(self.currently_selected_movement, Movement):
            self.timeline_list_table.setRowCount(
                len(self.currently_selected_movement.motion_list))
            self.timeline_list_table.setEnabled(True)
            self.actions_groupbox_table.setEnabled(True)

            current_row = 0
            for motion in self.currently_selected_movement.motion_list:
                if isinstance(motion, RectMotion):
                    target_to_put = RectilinearMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, WaitMotion):
                    target_to_put = WaitMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, AccRectMotion):
                    target_to_put = AccRectilinearMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, RotMotion):
                    target_to_put = RotationalMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, AccRotMotion):
                    target_to_put = AccRotationalMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, AccCirMotion):
                    target_to_put = AccCircularMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, RotSinuMotion):
                    target_to_put = RotSinuMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, CirSinuMotion):
                    target_to_put = CirSinuMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                elif isinstance(motion, RectSinuMotion):
                    target_to_put = RectSinuMotionTimeline(
                        current_row, motion, parent=get_fc_main_window())
                else:
                    raise NotImplementedError(
                        "The type of movement: {} is not implemented.".format(
                            str(motion.__class__.__name__)))

                target_to_put.changed.connect(self.on_timeline_item_change)
                target_to_put.deleted.connect(self.on_timeline_item_delete)
                target_to_put.order_up.connect(self.on_timeline_item_order_up)
                target_to_put.order_down.connect(
                    self.on_timeline_item_order_down)
                self.timeline_list_table.setCellWidget(current_row, 0,
                                                       target_to_put)

                if current_row == 0:
                    target_to_put.disable_order_up_button()
                elif current_row == len(
                        self.currently_selected_movement.motion_list) - 1:
                    target_to_put.disable_order_down_button()

                current_row += 1
        elif isinstance(self.currently_selected_movement, SpecialMovement):
            self.timeline_list_table.setRowCount(1)
            self.timeline_list_table.setEnabled(True)
            self.actions_groupbox_table.setEnabled(False)

            if isinstance(self.currently_selected_movement.generator,
                          RegularPistonWaveGen):
                target_to_put = RegularPistonWaveMotionTimeline(
                    self.currently_selected_movement.generator,
                    parent=get_fc_main_window())
            elif isinstance(self.currently_selected_movement.generator,
                            IrregularPistonWaveGen):
                target_to_put = IrregularPistonWaveMotionTimeline(
                    self.currently_selected_movement.generator,
                    parent=get_fc_main_window())
            if isinstance(self.currently_selected_movement.generator,
                          RegularFlapWaveGen):
                target_to_put = RegularFlapWaveMotionTimeline(
                    self.currently_selected_movement.generator,
                    parent=get_fc_main_window())
            elif isinstance(self.currently_selected_movement.generator,
                            IrregularFlapWaveGen):
                target_to_put = IrregularFlapWaveMotionTimeline(
                    self.currently_selected_movement.generator,
                    parent=get_fc_main_window())
            elif isinstance(self.currently_selected_movement.generator,
                            FileGen):
                target_to_put = FileMotionTimeline(
                    self.currently_selected_movement.generator,
                    Case.the().path,
                    parent=get_fc_main_window())
            elif isinstance(self.currently_selected_movement.generator,
                            RotationFileGen):
                target_to_put = RotationFileMotionTimeline(
                    self.currently_selected_movement.generator,
                    Case.the().path,
                    parent=get_fc_main_window())

            target_to_put.changed.connect(self.on_timeline_item_change)
            self.timeline_list_table.setCellWidget(0, 0, target_to_put)
コード例 #28
0
 def on_floatstate_change(self):
     """ Float configuration button behaviour. """
     FloatStateDialog(parent=get_fc_main_window())
 def on_moorings_button(self):
     """ Moorings button behaviour."""
     MooringsConfigurationDialog(parent=get_fc_main_window())
     self.accept()
    def on_relaxationzone_menu(self, action):
        """ Defines Relaxation Zone menu behaviour."""

        # Check which type of relaxationzone it is
        if action.text() == __("Regular waves"):
            if Case.the().relaxation_zone is not None:
                if not isinstance(Case.the().relaxation_zone,
                                  RelaxationZoneRegular):
                    overwrite_warn = ok_cancel_dialog(
                        __("Relaxation Zone"),
                        __("There's already another type of Relaxation Zone defined. Continuing will overwrite it. Are you sure?"
                           ))
                    if overwrite_warn == QtGui.QMessageBox.Cancel:
                        return
                    Case.the().relaxation_zone = RelaxationZoneRegular()

            config_dialog = RelaxationZoneRegularConfigDialog(
                Case.the().relaxation_zone, parent=get_fc_main_window())

            # Set the relaxation zone. Can be an object or be None
            Case.the().relaxation_zone = config_dialog.relaxationzone
        if action.text() == __("Irregular waves"):
            if Case.the().relaxation_zone is not None:
                if not isinstance(Case.the().relaxation_zone,
                                  RelaxationZoneIrregular):
                    overwrite_warn = ok_cancel_dialog(
                        __("Relaxation Zone"),
                        __("There's already another type of Relaxation Zone defined. Continuing will overwrite it. Are you sure?"
                           ))
                    if overwrite_warn == QtGui.QMessageBox.Cancel:
                        return
                    Case.the().relaxation_zone = RelaxationZoneIrregular()

            config_dialog = RelaxationZoneIrregularConfigDialog(
                Case.the().relaxation_zone, parent=get_fc_main_window())

            # Set the relaxation zone. Can be an object or be None
            Case.the().relaxation_zone = config_dialog.relaxationzone
        if action.text() == __("External Input"):
            if Case.the().relaxation_zone is not None:
                if not isinstance(Case.the().relaxation_zone,
                                  RelaxationZoneFile):
                    overwrite_warn = ok_cancel_dialog(
                        __("Relaxation Zone"),
                        __("There's already another type of Relaxation Zone defined. Continuing will overwrite it. Are you sure?"
                           ))
                    if overwrite_warn == QtGui.QMessageBox.Cancel:
                        return
                    Case.the().relaxation_zone = RelaxationZoneFile()

            config_dialog = RelaxationZoneFileConfigDialog(
                Case.the().relaxation_zone, parent=get_fc_main_window())

            # Set the relaxation zone. Can be an object or be None
            Case.the().relaxation_zone = config_dialog.relaxationzone

        if action.text() == __("Uniform velocity"):
            if Case.the().relaxation_zone is not None:
                if not isinstance(Case.the().relaxation_zone,
                                  RelaxationZoneUniform):
                    overwrite_warn = ok_cancel_dialog(
                        __("Relaxation Zone"),
                        __("There's already another type of Relaxation Zone defined. Continuing will overwrite it. Are you sure?"
                           ))
                    if overwrite_warn == QtGui.QMessageBox.Cancel:
                        return
                    Case.the().relaxation_zone = RelaxationZoneUniform()

            config_dialog = RelaxationZoneUniformConfigDialog(
                Case.the().relaxation_zone, parent=get_fc_main_window())

            # Set the relaxation zone. Can be an object or be None
            Case.the().relaxation_zone = config_dialog.relaxationzone

        self.accept()