コード例 #1
0
 def get_used_mkfluid_labels(self) -> list:
     "Retrurns a list with all the MKFluid labels used on the case."
     to_ret = list()
     for obj in Case.the().get_all_fluid_objects():
         if get_fc_object(obj.name).Label not in to_ret:
             to_ret.append(get_fc_object(obj.name).Label)
     return to_ret
コード例 #2
0
    def refresh(self) -> None:
        """ Deletes everything and refreshes contents with the current simulation objects. """
        self.clear_table_contents()
        num_objects_in_simulation: int = Case.the(
        ).number_of_objects_in_simulation()
        self.set_table_row_count(num_objects_in_simulation)

        current_row = 0
        for sim_object in Case.the().objects:
            if sim_object.name == CASE_LIMITS_OBJ_NAME:
                continue
            target_widget = ObjectOrderWidget(index=current_row,
                                              object_mk=sim_object.obj_mk,
                                              mktype=sim_object.type,
                                              object_name=get_fc_object(
                                                  sim_object.name).Label,
                                              parent=self)

            if current_row == 0:
                target_widget.disable_up()
            if current_row == num_objects_in_simulation - 1:
                target_widget.disable_down()

            self.set_table_cell_widget(current_row, 0, target_widget)
            current_row += 1
コード例 #3
0
 def supports_changing_type(self) -> bool:
     """ Returns whether this object supports changing types or not. """
     fc_object = get_fc_object(self.name)
     return fc_object.TypeId in SUPPORTED_TYPES or \
         "part" in fc_object.TypeId.lower() or \
         "mesh" in fc_object.TypeId.lower() or \
         (fc_object.TypeId == FreeCADObjectType.FOLDER and "fillbox" in fc_object.Name.lower())
コード例 #4
0
ファイル: case_summary.py プロジェクト: luzpaz/DesignSPHysics
    def get_objects_info(self) -> str:
        """ Returns an HTML string with information about the objects in the case. """
        each_object_info: list = list()

        obj: SimulationObject = None
        for obj in Case.the().objects:
            if obj.name == CASE_LIMITS_OBJ_NAME:
                continue

            is_floating_text: str = "Yes" if Case.the(
            ).get_mk_based_properties(obj.type,
                                      obj.obj_mk).float_property else "No"
            has_initials_text: str = "Yes" if Case.the(
            ).get_mk_based_properties(obj.type, obj.obj_mk).initials else "No"

            to_append = "<li>"
            to_append += "<b>{}</b> ({})<br>".format(
                get_fc_object(obj.name).Label, obj.name)
            to_append += "Type: {type} (MK{type}: <b>{mk}</b> ; MK: <b>{real_mk}</b>)<br/>".format(
                type=str(obj.type).capitalize(),
                mk=str(obj.obj_mk),
                real_mk=str(obj.obj_mk + MKFLUID_OFFSET if obj.type ==
                            ObjectType.FLUID else obj.obj_mk + MKFLUID_LIMIT))
            to_append += "Fill mode: {}<br/>".format(
                str(obj.fillmode).capitalize())
            to_append += "Floating: {}<br/>".format(is_floating_text)
            to_append += "Initials: {}</li><br/>".format(has_initials_text)
            to_append += "</li>"

            each_object_info.append(to_append)

        return "<ul>{}</ul>".format(
            "".join(each_object_info)
            if each_object_info else "No objects were added to the case.")
コード例 #5
0
def on_tree_item_selection_change(properties_widget, designsphysics_dock):
    """ Refreshes relevant parts of DesignsPHysics under an important change event. """
    debug("Syncronizing FreeCAD data structures with DesignSPHysics")
    selection = FreeCADGui.Selection.getSelection()
    properties_widget.set_add_button_enabled(True)

    if selection:
        if len(selection) > 1:
            # Multiple objects selected
            properties_widget.configure_to_add_multiple_selection()
        else:
            # One object selected
            if selection[0].Name == "Case_Limits" or "_internal_" in selection[
                    0].Name:
                properties_widget.configure_to_no_selection()
            elif Case.the().is_damping_bound_to_object(selection[0].Name):
                properties_widget.configure_to_damping_selection()
            elif Case.the().is_object_in_simulation(selection[0].Name):
                # Show properties on table
                properties_widget.configure_to_regular_selection()
                properties_widget.adapt_to_simulation_object(
                    Case.the().get_simulation_object(selection[0].Name),
                    selection[0])
            else:
                if not selection[0].InList:
                    # Show button to add to simulation
                    properties_widget.configure_to_add_single_selection()
                else:
                    properties_widget.configure_to_incompatible_object()
    else:
        properties_widget.configure_to_no_selection()

    # Delete invalid or already deleted (in FreeCAD) objects
    for object_name in Case.the().get_all_simulation_object_names():
        fc_object = get_fc_object(object_name)
        if not fc_object or fc_object.InList:
            Case.the().remove_object(object_name)

    for damping_to_delete in list(
            filter(lambda x: not get_fc_object(x),
                   Case.the().damping_zones)):
        Case.the().remove_damping_zone(damping_to_delete)

    # Update dsph objects list
    designsphysics_dock.refresh_object_list()
    properties_widget.fit_size()
コード例 #6
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
コード例 #7
0
def save_case(save_name: str, case: "Case") -> None:
    """ Saves a case to disk in the given path. """
    project_name = save_name.split("/")[-1]
    case.path = save_name
    case.name = project_name

    if not path.exists(save_name):
        makedirs(save_name)

    if not path.exists("{}/{}_out".format(save_name, project_name)):
        makedirs("{}/{}_out".format(save_name, project_name))

    # Export all complex objects to STL
    for obj in case.get_all_complex_objects():
        Mesh.export([get_fc_object(obj.name)], "{}/{}.stl".format(save_name, obj.name))

    # FIXME: Too many branches

    # Copy files from movements and change its paths to be inside the project.
    for _, mkproperties in case.mkbasedproperties.items():
        for movement in mkproperties.movements:
            if isinstance(movement, SpecialMovement):
                if isinstance(movement.generator, (FileGen, RotationFileGen)):
                    filename = movement.generator.filename
                    debug("Copying {} to {}".format(filename, save_name))

                    # Change directory to de case one, so if file path is already relative it copies it to the
                    # out folder
                    chdir(save_name)
コード例 #8
0
 def supports_motion(self) -> bool:
     """ Returns whether this object supports motion or not. """
     fc_object = get_fc_object(self.name)
     return fc_object.TypeId in SUPPORTED_TYPES \
         or FreeCADObjectType.CUSTOM_MESH in str(fc_object.TypeId) or \
         (fc_object.TypeId == FreeCADObjectType.FOLDER and "fillbox" in fc_object.Name.lower())
コード例 #9
0
 def supports_floating(self) -> bool:
     """ Returns whether this object supports floating or not. """
     fc_object = get_fc_object(self.name)
     return fc_object.TypeId in SUPPORTED_TYPES or \
         (fc_object.TypeId == FreeCADObjectType.FOLDER and "fillbox" in fc_object.Name.lower())
コード例 #10
0
 def supports_changing_fillmode(self) -> bool:
     """ Returns whether this object supports changing its fillmode or not. """
     fc_object = get_fc_object(self.name)
     return fc_object.TypeId in SUPPORTED_TYPES
コード例 #11
0
def save_case(save_name: str, case: "Case") -> None:
    """ Saves a case to disk in the given path. """
    project_name = save_name.split("/")[-1]
    case.path = save_name
    case.name = project_name

    if not path.exists(save_name):
        makedirs(save_name)

    if not path.exists("{}/{}_out".format(save_name, project_name)):
        makedirs("{}/{}_out".format(save_name, project_name))

    # Export all complex objects to STL
    for obj in case.get_all_complex_objects():
        Mesh.export([get_fc_object(obj.name)],
                    "{}/{}.stl".format(save_name, obj.name))

    # FIXME: Too many branches

    # Copy files from movements and change its paths to be inside the project.
    for _, mkproperties in case.mkbasedproperties.items():
        for movement in mkproperties.movements:
            if isinstance(movement, SpecialMovement):
                if isinstance(movement.generator, (FileGen, RotationFileGen)):
                    filename = movement.generator.filename
                    debug("Copying {} to {}".format(filename, save_name))

                    # Change directory to de case one, so if file path is already relative it copies it to the
                    # out folder
                    chdir(save_name)
コード例 #12
0
    def __init__(self, parent=None):
        super().__init__(parent=parent)

        # Reference to avoid calling instance every time
        self.case = Case.the()

        # Creates a dialog
        self.setWindowTitle("Chrono configuration")
        self.setMinimumWidth(500)
        self.setMinimumHeight(600)
        self.main_layout = QtGui.QVBoxLayout()

        # Option for saves CSV with data exchange for each time interval
        self.csv_option_layout = QtGui.QHBoxLayout()
        self.csv_intervals_checkbox = QtGui.QCheckBox()
        self.csv_intervals_checkbox.setCheckState(QtCore.Qt.Checked if self.case.chrono.csv_intervals.enabled else QtCore.Qt.Unchecked)
        self.csv_intervals_checkbox.toggled.connect(self.on_csv_intervals_check)
        self.csv_intervals_option = QtGui.QLabel(__("CSV intervals:"))
        self.csv_intervals_line_edit = QtGui.QLineEdit(str(self.case.chrono.csv_intervals.value))
        self.csv_option_layout.addWidget(self.csv_intervals_checkbox)
        self.csv_option_layout.addWidget(self.csv_intervals_option)
        self.csv_option_layout.addWidget(self.csv_intervals_line_edit)

        # Option for define scale used to create the initial scheme of Chrono objects
        self.scale_scheme_option_layout = QtGui.QHBoxLayout()
        self.scale_scheme_checkbox = QtGui.QCheckBox()
        self.scale_scheme_checkbox.setCheckState(QtCore.Qt.Checked if self.case.chrono.scale_scheme.enabled else QtCore.Qt.Unchecked)
        self.scale_scheme_checkbox.toggled.connect(self.on_scale_scheme_checkbox)
        self.scale_scheme_option = QtGui.QLabel(__("Scale for scheme:"))
        self.scale_scheme_line_edit = QtGui.QLineEdit(str(self.case.chrono.scale_scheme.value))
        self.scale_scheme_option_layout.addWidget(self.scale_scheme_checkbox)
        self.scale_scheme_option_layout.addWidget(self.scale_scheme_option)
        self.scale_scheme_option_layout.addWidget(self.scale_scheme_line_edit)

        # Option for allow collision overlap according Dp
        self.collisiondp_option_layout = QtGui.QHBoxLayout()
        self.collisiondp_checkbox = QtGui.QCheckBox()
        if self.case.chrono.collisiondp.enabled:
            self.collisiondp_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.collisiondp_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.collisiondp_checkbox.toggled.connect(self.on_collisiondp_checkbox)
        self.collisiondp_option = QtGui.QLabel(__("Collision Dp:"))
        self.collisiondp_line_edit = QtGui.QLineEdit(str(self.case.chrono.collisiondp.value))
        self.collisiondp_option_layout.addWidget(self.collisiondp_checkbox)
        self.collisiondp_option_layout.addWidget(self.collisiondp_option)
        self.collisiondp_option_layout.addWidget(self.collisiondp_line_edit)

        # Create the list for chrono objects
        self.main_chrono = QtGui.QGroupBox("Chrono objects")
        self.main_chrono.setMinimumHeight(150)
        self.chrono_layout = QtGui.QVBoxLayout()

        self.objectlist_table = QtGui.QTableWidget(0, 1)
        self.objectlist_table.setObjectName("Chrono objects table")
        self.objectlist_table.verticalHeader().setVisible(False)
        self.objectlist_table.horizontalHeader().setVisible(False)
        self.objectlist_table.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch)

        self.objectlist_table.setEnabled(True)

        # Create the necessary spaces in the list
        self.count = 0
        self.objectlist_table.setRowCount(len(self.case.get_all_bound_objects()))
        self.current_row = 0
        self.objects_with_parent = list()
        self.is_floating = ""
        self.chrono_object_options_widgets = list()

        # Select the objects that are going to be listed
        for sim_object in self.case.get_all_bound_objects():
            freecad_object = get_fc_object(sim_object.name)
            self.is_floating = "bodyfloating" if self.case.get_mk_based_properties(sim_object.type, sim_object.obj_mk).float_property else "bodyfixed"

            # Collects the information of the object
            self.target_widget = ChronoObjectCheckOptions(
                key=sim_object.name,
                object_mk=sim_object.obj_mk,
                mktype=sim_object.type,
                object_name=freecad_object.Label,
                is_floating=self.is_floating,
                parent=get_fc_main_window()
            )

            # Updates the state of list options
            if self.case.chrono.objects:
                for elem in self.case.chrono.objects:
                    if elem.id == sim_object.name:
                        self.target_widget.object_check.setCheckState(QtCore.Qt.Checked)
                        self.target_widget.geometry_check.setCheckState(QtCore.Qt.Checked if elem.modelnormal_enabled else QtCore.Qt.Unchecked)
                        self.target_widget.modelnormal_input.setCurrentIndex({ChronoModelNormalType.ORIGINAL: 0, ChronoModelNormalType.INVERT: 1, ChronoModelNormalType.TWOFACE: 2}[elem.modelnormal_type])

            # Saves the information about object for being process later
            self.chrono_object_options_widgets.append(self.target_widget)

            # Shows the object in table
            self.objectlist_table.setCellWidget(self.current_row, 0, self.target_widget)

            self.current_row += 1

        # Add table to the layout
        self.chrono_layout.addWidget(self.objectlist_table)

        # Creates 2 main buttons
        self.ok_button = QtGui.QPushButton("Save")
        self.cancel_button = QtGui.QPushButton("Cancel")
        self.button_layout = QtGui.QHBoxLayout()
        self.button_layout.addStretch(1)

        self.ok_button.clicked.connect(self.on_ok)
        self.cancel_button.clicked.connect(self.on_cancel)

        # Link Linearspring option list
        self.main_link_linearspring = QtGui.QGroupBox("Linearspring")
        self.link_linearspring_layout = QtGui.QVBoxLayout()
        self.link_linearspring_layout2 = QtGui.QVBoxLayout()

        self.link_linearspring_button_layout = QtGui.QHBoxLayout()
        self.button_link_linearspring = QtGui.QPushButton("Add")
        self.link_linearspring_button_layout.addStretch(1)
        self.link_linearspring_button_layout.addWidget(self.button_link_linearspring)
        self.button_link_linearspring.clicked.connect(self.on_link_linearspring_add)

        self.link_linearspring_layout.addLayout(self.link_linearspring_button_layout)
        self.link_linearspring_layout.addLayout(self.link_linearspring_layout2)
        self.main_link_linearspring.setLayout(self.link_linearspring_layout)

        self.refresh_link_linearspring()

        # Link hinge option list
        self.main_link_hinge = QtGui.QGroupBox("Hinge")
        self.link_hinge_layout = QtGui.QVBoxLayout()
        self.link_hinge_layout2 = QtGui.QVBoxLayout()

        self.link_hinge_button_layout = QtGui.QHBoxLayout()
        self.button_link_hinge = QtGui.QPushButton("Add")
        self.link_hinge_button_layout.addStretch(1)
        self.link_hinge_button_layout.addWidget(self.button_link_hinge)
        self.button_link_hinge.clicked.connect(self.on_link_hinge_add)

        self.link_hinge_layout.addLayout(self.link_hinge_button_layout)
        self.link_hinge_layout.addLayout(self.link_hinge_layout2)
        self.main_link_hinge.setLayout(self.link_hinge_layout)

        self.refresh_link_hinge()

        # Link Spheric option list
        self.main_link_spheric = QtGui.QGroupBox("Spheric")
        self.link_spheric_layout = QtGui.QVBoxLayout()
        self.link_spheric_layout2 = QtGui.QVBoxLayout()

        self.link_spheric_button_layout = QtGui.QHBoxLayout()
        self.button_link_spheric = QtGui.QPushButton("Add")
        self.link_spheric_button_layout.addStretch(1)
        self.link_spheric_button_layout.addWidget(self.button_link_spheric)
        self.button_link_spheric.clicked.connect(self.on_link_spheric_add)

        self.link_spheric_layout.addLayout(self.link_spheric_button_layout)
        self.link_spheric_layout.addLayout(self.link_spheric_layout2)
        self.main_link_spheric.setLayout(self.link_spheric_layout)

        self.refresh_link_spheric()

        # Link Pointline option list
        self.main_link_pointline = QtGui.QGroupBox("Pointline")
        self.link_pointline_layout = QtGui.QVBoxLayout()
        self.link_pointline_layout2 = QtGui.QVBoxLayout()

        self.link_pointline_button_layout = QtGui.QHBoxLayout()
        self.button_link_pointline = QtGui.QPushButton("Add")
        self.link_pointline_button_layout.addStretch(1)
        self.link_pointline_button_layout.addWidget(self.button_link_pointline)
        self.button_link_pointline.clicked.connect(self.on_link_pointline_add)

        self.link_pointline_layout.addLayout(self.link_pointline_button_layout)
        self.link_pointline_layout.addLayout(self.link_pointline_layout2)
        self.main_link_pointline.setLayout(self.link_pointline_layout)

        self.refresh_link_pointline()

        # Adds all layouts to main
        self.main_layout.addLayout(self.csv_option_layout)
        self.main_layout.addLayout(self.scale_scheme_option_layout)
        self.main_layout.addLayout(self.collisiondp_option_layout)
        self.main_chrono.setLayout(self.chrono_layout)
        self.main_layout.addWidget(self.main_chrono)
        self.main_layout.addWidget(self.main_link_linearspring)
        self.main_layout.addWidget(self.main_link_hinge)
        self.main_layout.addWidget(self.main_link_spheric)
        self.main_layout.addWidget(self.main_link_pointline)

        self.button_layout.addWidget(self.ok_button)
        self.button_layout.addWidget(self.cancel_button)

        # Adds scroll area
        self.main_layout_dialog = QtGui.QVBoxLayout()
        self.main_layout_scroll = QtGui.QScrollArea()
        self.main_layout_scroll.setMinimumWidth(400)
        self.main_layout_scroll.setWidgetResizable(True)
        self.main_layout_scroll_widget = QtGui.QWidget()
        self.main_layout_scroll_widget.setMinimumWidth(400)

        self.main_layout_scroll_widget.setLayout(self.main_layout)
        self.main_layout_scroll.setWidget(self.main_layout_scroll_widget)
        self.main_layout_scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        self.main_layout_dialog.addWidget(self.main_layout_scroll)
        self.main_layout_dialog.addLayout(self.button_layout)
        self.on_scale_scheme_checkbox()
        self.on_csv_intervals_check()
        self.on_collisiondp_checkbox()

        self.setLayout(self.main_layout_dialog)

        self.ok_button.setFocus()

        self.exec_()
コード例 #13
0
ファイル: file_tools.py プロジェクト: luzpaz/DesignSPHysics
def save_case(save_name: str, case: "Case") -> None:
    """ Saves a case to disk in the given path. """
    project_name = save_name.split("/")[-1]
    case.path = save_name
    case.name = project_name

    if not path.exists(save_name):
        makedirs(save_name)

    if not path.exists("{}/{}_out".format(save_name, project_name)):
        makedirs("{}/{}_out".format(save_name, project_name))

    # Export all complex objects to STL
    for obj in case.get_all_complex_objects():
        Mesh.export([get_fc_object(obj.name)],
                    "{}/{}.stl".format(save_name, obj.name))

    # FIXME: Too many branches

    # Copy files from movements and change its paths to be inside the project.
    for _, mkproperties in case.mkbasedproperties.items():
        for movement in mkproperties.movements:
            if isinstance(movement, SpecialMovement):
                if isinstance(movement.generator, (FileGen, RotationFileGen)):
                    filename = movement.generator.filename
                    debug("Copying {} to {}".format(filename, save_name))

                    # Change directory to de case one, so if file path is already relative it copies it to the
                    # out folder
                    chdir(save_name)