def generalForm(self): """Creates the form inputs for general settings""" self.addGroup(settings.Group.General) frame = QtWidgets.QWidget() main_layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QHBoxLayout() key = settings.Key.Check_Update self.global_names.append(key) value = settings.value(key) checkbox = QtWidgets.QCheckBox('Check for updates on startup') checkbox.setChecked(value) checkbox.stateChanged.connect( lambda ignore, c=checkbox: self.changeSetting(c.isChecked())) checkbox.setProperty(self.prop_name, (key, value)) layout.addWidget(checkbox) main_layout.addLayout(layout) main_layout.addSpacing(10) layout = QtWidgets.QHBoxLayout() key = settings.Key.Custom_Instruments_Path self.global_names.append(key) value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Custom Instruments: ')) path_picker = FilePicker(value, select_folder=True) path_picker.setProperty(self.prop_name, (key, value)) path_picker.value_changed.connect(self.changeSetting) layout.addWidget(path_picker) main_layout.addLayout(layout) main_layout.addStretch(1) frame.setLayout(main_layout) self.stack.addWidget(create_scroll_area(frame))
def updateInstrumentList(self): """Updates the list of instrument description files found in the instrument directories""" self.instruments.clear() custom_path = settings.value(settings.Key.Custom_Instruments_Path) directories = [path for path in (custom_path, INSTRUMENTS_PATH) if os.path.isdir(path)] if not directories: return for path in directories: for name in os.listdir(path): idf = os.path.join(path, name, 'instrument.json') if not os.path.isfile(idf): continue try: with open(idf) as json_file: data = json.load(json_file) except (OSError, ValueError): data = {} instrument_data = data.get('instrument', None) if instrument_data is None: continue name = instrument_data.get('name', '').strip().upper() version = instrument_data.get('version', '').strip() if name and version: self.instruments[name] = IDF(name, idf, version)
def runSimulation(self): """Creates and starts a new simulation""" if self.model.alignment is None: self.view.showMessage( 'Sample must be aligned on the instrument for Simulation', MessageType.Information) return if self.model.measurement_points.size == 0: self.view.showMessage( 'Measurement points should be added before Simulation', MessageType.Information) return if not self.model.measurement_points.enabled.any(): self.view.showMessage( 'No measurement points are enabled. Enable points from the point manager to proceed.', MessageType.Information) return if settings.value(settings.Key.Skip_Zero_Vectors): vectors = self.model.measurement_vectors[ self.model.measurement_points.enabled, :, :] if (np.linalg.norm(vectors, axis=1) < VECTOR_EPS).all(): self.view.showMessage( 'No measurement vectors have been added and the software is configured to ' '"Skip the measurement" when the measurement vector is unset. Change ' 'the behaviour in Preferences to proceed.', MessageType.Information) return self.view.docks.showSimulationResults() if self.model.simulation is not None and self.model.simulation.isRunning( ): return compute_path_length = self.view.compute_path_length_action.isChecked() check_collision = self.view.check_collision_action.isChecked() render_graphics = self.view.show_sim_graphics_action.isChecked() check_limits = self.view.check_limits_action.isChecked() self.model.createSimulation(compute_path_length, render_graphics, check_limits, check_collision) # Start the simulation process. This can be slow due to pickling of arguments self.model.simulation.start()
def __init__(self, parent): super().__init__(parent) self.parent = parent self.parent_model = parent.presenter.model self.parent.scenes.switchToSampleScene() self.main_layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QHBoxLayout() layout.addWidget(QtWidgets.QLabel('Alignment:')) self.alignment_combobox = QtWidgets.QComboBox() self.alignment_combobox.setView(QtWidgets.QListView()) self.alignment_combobox.activated.connect(self.onComboBoxActivated) layout.addWidget(self.alignment_combobox, 4) layout.addSpacing(10) self.detector_combobox = QtWidgets.QComboBox() self.detector_combobox.setView(QtWidgets.QListView()) self.detector_combobox.addItems( list(self.parent_model.instrument.detectors.keys())) self.detector_combobox.activated.connect(self.onComboBoxActivated) if len(self.parent_model.instrument.detectors) > 1: layout.addWidget(QtWidgets.QLabel('Detector:')) layout.addWidget(self.detector_combobox, 4) size = self.detector_combobox.iconSize() self.detector_combobox.setItemIcon( 0, create_icon(settings.value(settings.Key.Vector_1_Colour), size)) self.detector_combobox.setItemIcon( 1, create_icon(settings.value(settings.Key.Vector_2_Colour), size)) self.delete_vector_action = QtWidgets.QAction("Delete Vectors", self) self.delete_vector_action.triggered.connect(self.deleteVectors) self.delete_vector_action.setStatusTip( 'Remove (zero) selected vectors or all vectors in current alignment' ) self.delete_alignment_action = QtWidgets.QAction( "Delete Alignment", self) self.delete_alignment_action.triggered.connect(self.deleteAlignment) self.delete_alignment_action.setStatusTip( 'Remove selected vector alignment') delete_menu = QtWidgets.QMenu() delete_menu.addAction(self.delete_vector_action) delete_menu.addAction(self.delete_alignment_action) self.delete_alignment_button = create_tool_button( icon_path=path_for('cross.png'), style_name='ToolButton', status_tip='Remove measurement vectors or alignments') self.delete_alignment_button.setPopupMode( QtWidgets.QToolButton.InstantPopup) self.delete_alignment_button.setMenu(delete_menu) layout.addStretch(1) layout.addWidget(self.delete_alignment_button) layout.setAlignment(self.delete_alignment_button, QtCore.Qt.AlignBottom) self.main_layout.addLayout(layout, 0) self.table = QtWidgets.QTableWidget() self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.table.setColumnCount(3) self.table.setHorizontalHeaderLabels(['X', 'Y', 'Z']) self.table.setAlternatingRowColors(True) self.table.setMinimumHeight(300) self.table.setMaximumHeight(500) self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.table.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) self.table.horizontalHeader().setMinimumSectionSize(40) self.table.horizontalHeader().setDefaultSectionSize(40) self.updateWidget() self.main_layout.addWidget(self.table, 20) self.main_layout.addStretch(1) self.setLayout(self.main_layout) self.title = 'Measurement Vectors' self.setMinimumWidth(450) self.parent_model.measurement_vectors_changed.connect( self.updateWidget) self.parent.scenes.rendered_alignment_changed.connect( self.updateWidget)
def graphicsForm(self): """Creates form inputs for graphics settings""" self.addGroup(settings.Group.Graphics) frame = QtWidgets.QWidget() main_layout = QtWidgets.QVBoxLayout() main_layout.addWidget(create_header('Rendering Size')) layout = QtWidgets.QHBoxLayout() key = settings.Key.Fiducial_Size value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Fiducials:')) size = (5, 15, 30) combo_box = QtWidgets.QComboBox() combo_box.addItems(['Small', 'Medium', 'Large']) combo_box.setProperty(self.prop_name, (key, value)) combo_box.setCurrentIndex(size.index(value) if value in size else 0) combo_box.currentIndexChanged.connect( lambda i, v=size: self.changeSetting(v[i])) layout.addWidget(combo_box) layout.addStretch(1) main_layout.addLayout(layout) main_layout.addSpacing(5) layout = QtWidgets.QHBoxLayout() key = settings.Key.Measurement_Size value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Measurement Points:')) size = (5, 15, 30) combo_box = QtWidgets.QComboBox() combo_box.addItems(['Small', 'Medium', 'Large']) combo_box.setProperty(self.prop_name, (key, value)) combo_box.setCurrentIndex(size.index(value) if value in size else 0) combo_box.currentIndexChanged.connect( lambda i, v=size: self.changeSetting(v[i])) layout.addWidget(combo_box) layout.addStretch(1) main_layout.addLayout(layout) main_layout.addSpacing(5) layout = QtWidgets.QHBoxLayout() key = settings.Key.Vector_Size value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Measurement Vectors:')) size = (10, 35, 50) combo_box = QtWidgets.QComboBox() combo_box.addItems(['Small', 'Medium', 'Large']) combo_box.setProperty(self.prop_name, (key, value)) combo_box.setCurrentIndex(size.index(value) if value in size else 0) combo_box.currentIndexChanged.connect( lambda i, v=size: self.changeSetting(v[i])) layout.addWidget(combo_box) layout.addStretch(1) main_layout.addLayout(layout) main_layout.addSpacing(5) main_layout.addWidget(create_header('Rendering Colour')) layout = QtWidgets.QHBoxLayout() key = settings.Key.Sample_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Sample:')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Fiducial_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Fiducials (Enabled): ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Fiducial_Disabled_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Fiducials (Disabled): ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Measurement_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Measurement Point (Enabled): ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Measurement_Disabled_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Measurement Point (Disabled): ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Vector_1_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Measurement Vector 1: ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Vector_2_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Measurement Vector 2: ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Cross_Sectional_Plane_Colour value = settings.value(key) layout.addWidget(QtWidgets.QLabel('Cross-Sectional Plane: ')) colour_picker = ColourPicker(QtGui.QColor.fromRgbF(*value)) colour_picker.value_changed.connect(self.changeSetting) colour_picker.setProperty(self.prop_name, (key, value)) layout.addWidget(colour_picker) layout.addStretch(1) main_layout.addLayout(layout) main_layout.addStretch(1) frame.setLayout(main_layout) self.stack.addWidget(create_scroll_area(frame))
def simulationForm(self): """Creates the form inputs for simulation settings""" self.addGroup(settings.Group.Simulation) frame = QtWidgets.QWidget() main_layout = QtWidgets.QVBoxLayout() main_layout.setSpacing(10) layout = QtWidgets.QVBoxLayout() key = settings.Key.Skip_Zero_Vectors value = settings.value(key) layout.addWidget(create_header('Zero Measurement Vector:')) group = QtWidgets.QWidget() group_layout = QtWidgets.QVBoxLayout() group_layout.setContentsMargins(0, 0, 0, 0) radio_button_1 = QtWidgets.QRadioButton('Skip the measurement') radio_button_1.setChecked(value) radio_button_1.setProperty(self.prop_name, (key, value)) radio_button_1.toggled.connect(lambda: self.changeSetting(True)) radio_button_2 = QtWidgets.QRadioButton( 'Perform translation but no rotation') radio_button_2.setChecked(not value) radio_button_2.setProperty(self.prop_name, (key, value)) radio_button_2.toggled.connect(lambda: self.changeSetting(False)) group.setLayout(group_layout) group_layout.addWidget(radio_button_1) group_layout.addWidget(radio_button_2) layout.addWidget(group) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QVBoxLayout() key = settings.Key.Align_First value = settings.value(key) layout.addWidget(create_header('Execution Order:')) group = QtWidgets.QWidget() group_layout = QtWidgets.QVBoxLayout() group_layout.setContentsMargins(0, 0, 0, 0) radio_button_1 = QtWidgets.QRadioButton( 'Run alignments before next point', frame) radio_button_1.setChecked(value) radio_button_1.setProperty(self.prop_name, (key, value)) radio_button_1.toggled.connect(lambda: self.changeSetting(True)) radio_button_2 = QtWidgets.QRadioButton( 'Run next point before alignments', frame) radio_button_2.setChecked(not value) radio_button_2.setProperty(self.prop_name, (key, value)) radio_button_2.toggled.connect(lambda: self.changeSetting(False)) group.setLayout(group_layout) group_layout.addWidget(radio_button_1) group_layout.addWidget(radio_button_2) layout.addWidget(group) layout.addStretch(1) main_layout.addLayout(layout) main_layout.addWidget(create_header('Inverse Kinematics')) layout = QtWidgets.QHBoxLayout() key = settings.Key.Position_Stop_Val value = settings.value(key) lim = settings.default(key).limits layout.addWidget( QtWidgets.QLabel('Position termination tolerance (mm): ')) spin = QtWidgets.QDoubleSpinBox() spin.setDecimals(3) spin.setRange(*lim) spin.setValue(settings.value(key)) spin.setProperty(self.prop_name, (key, value)) spin.valueChanged.connect(self.changeSetting) layout.addWidget(spin) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Angular_Stop_Val value = settings.value(key) lim = settings.default(key).limits layout.addWidget( QtWidgets.QLabel('Orientation termination tolerance (degrees): ')) spin = QtWidgets.QDoubleSpinBox() spin.setDecimals(3) spin.setRange(*lim) spin.setValue(settings.value(key)) spin.setProperty(self.prop_name, (key, value)) spin.valueChanged.connect(self.changeSetting) layout.addWidget(spin) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Global_Max_Eval value = settings.value(key) lim = settings.default(key).limits layout.addWidget( QtWidgets.QLabel( f'Number of evaluations for global optimization ({lim[0]} - {lim[1]}): ' )) spin = QtWidgets.QSpinBox() spin.setRange(*lim) spin.setValue(settings.value(key)) spin.setProperty(self.prop_name, (key, value)) spin.valueChanged.connect(self.changeSetting) layout.addWidget(spin) layout.addStretch(1) main_layout.addLayout(layout) layout = QtWidgets.QHBoxLayout() key = settings.Key.Local_Max_Eval value = settings.value(key) lim = settings.default(key).limits layout.addWidget( QtWidgets.QLabel( f'Number of evaluations for local optimization ({lim[0]} - {lim[1]}): ' )) spin = QtWidgets.QSpinBox() spin.setRange(*lim) spin.setValue(value) spin.setProperty(self.prop_name, (key, value)) spin.valueChanged.connect(self.changeSetting) layout.addWidget(spin) layout.addStretch(1) main_layout.addLayout(layout) main_layout.addStretch(1) frame.setLayout(main_layout) self.stack.addWidget(create_scroll_area(frame))