Ejemplo n.º 1
0
    def __init__(self, tpm):
        super(ViaSettingsDialog, self).__init__()
        self.tpm = tpm

        self.radius_li = UnitLineEdit(UNIT_GROUP_MM)
        self.radius_li.setValue(self.tpm.radius)

        self.layout.addRow("Radius:", self.radius_li)
Ejemplo n.º 2
0
    def __init__(self, parent, model):
        super(KeypointAlignmentWidget, self).__init__()
        self.model = model
        self._parent = parent

        layout = QtGui.QFormLayout()
        self.setLayout(layout)

        keypoint_gb = QtGui.QGroupBox("Keypoint")
        layout.addWidget(keypoint_gb)

        edit_layout = QtGui.QFormLayout()
        keypoint_gb.setLayout(edit_layout)


        self.kpts_sel = QtGui.QComboBox()
        self.kpts_sel.setModel(self.model.combo_adapter)
        self.kpts_sel.currentIndexChanged.connect(self.kptChanged)
        edit_layout.addRow("Keypoint:", self.kpts_sel)

        self.wx = UnitLineEdit(UNIT_GROUP_MM)
        self.wy = UnitLineEdit(UNIT_GROUP_MM)
        edit_layout.addRow("World X", self.wx)
        edit_layout.addRow("World Y", self.wy)
        self.wx.edited.connect(self.update_world)
        self.wy.edited.connect(self.update_world)

        self.px = UnitLineEdit(UNIT_GROUP_PX)
        self.py = UnitLineEdit(UNIT_GROUP_PX)
        edit_layout.addRow("Image X", self.px)
        edit_layout.addRow("Image Y", self.py)
        self.px.edited.connect(self.update_layer)
        self.py.edited.connect(self.update_layer)


        self.use_for_alignment = QtGui.QCheckBox()
        edit_layout.addRow("Use", self.use_for_alignment)
        self.use_for_alignment.clicked.connect(self.update_used)

        self.add_btn = QtGui.QPushButton("Add New")
        self.add_btn.clicked.connect(self.addKeypoint)
        self.del_btn = QtGui.QPushButton("Remove Current")
        self.del_btn.clicked.connect(self.delKeypoint)
        bhl = QtGui.QHBoxLayout()
        bhl.addWidget(self.add_btn)
        bhl.addWidget(self.del_btn)
        edit_layout.addRow(bhl)


        self.constraint_status_lbl = QtGui.QLabel("")
        self.constraint_status_lbl.setWordWrap(True)
        layout.addRow(self.constraint_status_lbl)

        self.model.changed.connect(self.modelChanged)
        self.modelChanged()
Ejemplo n.º 3
0
    def __init__(self, model, attr, unitgroup, defaultunit=None):
        self.widget = UnitLineEdit(unitgroup)
        self.widget.suppress_enter = False

        self.model = model
        self.attr = attr
        path = self.attr.split('.')
        self.path = path[:-1]
        self.subattr = path[-1]

        self.load()
Ejemplo n.º 4
0
class ViaSettingsDialog(SettingsDialog):
    def __init__(self, tpm):
        super(ViaSettingsDialog, self).__init__()
        self.tpm = tpm

        self.radius_li = UnitLineEdit(UNIT_GROUP_MM)
        self.radius_li.setValue(self.tpm.radius)

        self.layout.addRow("Radius:", self.radius_li)

    @QtCore.Slot()
    def accept(self):
        self.tpm.radius = self.radius_li.getValue()
        QtGui.QDialog.accept(self)
Ejemplo n.º 5
0
    def __init__(self, parent: 'LayerAlignmentDialog',
                 model: KeypointAlignmentModel) -> None:
        super(KeypointAlignmentWidget, self).__init__()
        self.model = model
        self._parent = parent

        layout = QtWidgets.QFormLayout()
        self.setLayout(layout)

        keypoint_gb = QtWidgets.QGroupBox("Keypoint")
        layout.addWidget(keypoint_gb)

        edit_layout = QtWidgets.QFormLayout()
        keypoint_gb.setLayout(edit_layout)

        self.kpts_sel = QtWidgets.QComboBox()
        self.kpts_sel.setModel(self.model.combo_adapter)
        self.kpts_sel.currentIndexChanged.connect(self.kptChanged)
        edit_layout.addRow("Keypoint:", self.kpts_sel)

        self.wx = UnitLineEdit(UNIT_GROUP_MM)
        self.wy = UnitLineEdit(UNIT_GROUP_MM)
        edit_layout.addRow("World X", self.wx)
        edit_layout.addRow("World Y", self.wy)
        self.wx.edited.connect(self.update_world)
        self.wy.edited.connect(self.update_world)

        self.px = UnitLineEdit(UNIT_GROUP_PX)
        self.py = UnitLineEdit(UNIT_GROUP_PX)
        edit_layout.addRow("Image X", self.px)
        edit_layout.addRow("Image Y", self.py)
        self.px.edited.connect(self.update_layer)
        self.py.edited.connect(self.update_layer)

        self.use_for_alignment = QtWidgets.QCheckBox()
        edit_layout.addRow("Use", self.use_for_alignment)
        self.use_for_alignment.clicked.connect(self.update_used)

        self.add_btn = QtWidgets.QPushButton("Add New")
        self.add_btn.clicked.connect(self.addKeypoint)
        self.del_btn = QtWidgets.QPushButton("Remove Current")
        self.del_btn.clicked.connect(self.delKeypoint)
        bhl = QtWidgets.QHBoxLayout()
        bhl.addWidget(self.add_btn)
        bhl.addWidget(self.del_btn)
        edit_layout.addRow(bhl)

        self.constraint_status_lbl = QtWidgets.QLabel("")
        self.constraint_status_lbl.setWordWrap(True)
        layout.addRow(self.constraint_status_lbl)

        self.model.changed.connect(self.modelChanged)
        self.modelChanged()
Ejemplo n.º 6
0
    def __init__(self, model, attr, unitgroup, defaultunit=None):
        self.widget = UnitLineEdit(unitgroup)
        self.widget.suppress_enter = False

        self.model = model
        self.attr = attr
        path = self.attr.split(".")
        self.path = path[:-1]
        self.subattr = path[-1]

        self.load()
Ejemplo n.º 7
0
class UnitEditable(object):
    def __init__(self, model, attr, unitgroup, defaultunit=None):
        self.widget = UnitLineEdit(unitgroup)
        self.widget.suppress_enter = False

        self.model = model
        self.attr = attr
        path = self.attr.split('.')
        self.path = path[:-1]
        self.subattr = path[-1]

        self.load()


    def _get_par_obj(self):
        obj = self.model
        for p_cmp in self.path:
            obj = getattr(obj, p_cmp)

        return obj

    def load(self):
        par =  self._get_par_obj()
        elem = getattr(par, self.subattr)

        self.widget.setValue(elem)

    def save(self):
        v = self.value
        par = self._get_par_obj()
        setattr(par, self.subattr, v)

    @property
    def value(self):
        return self.widget.getValue()

    @value.setter
    def value(self, v):
        self.widget.setValue(v)
Ejemplo n.º 8
0
class UnitEditable(object):
    def __init__(self, model, attr, unitgroup, defaultunit=None):
        self.widget = UnitLineEdit(unitgroup)
        self.widget.suppress_enter = False

        self.model = model
        self.attr = attr
        path = self.attr.split(".")
        self.path = path[:-1]
        self.subattr = path[-1]

        self.load()

    def _get_par_obj(self):
        obj = self.model
        for p_cmp in self.path:
            obj = getattr(obj, p_cmp)

        return obj

    def load(self):
        par = self._get_par_obj()
        elem = getattr(par, self.subattr)

        self.widget.setValue(elem)

    def save(self):
        v = self.value
        par = self._get_par_obj()
        setattr(par, self.subattr, v)

    @property
    def value(self):
        return self.widget.getValue()

    @value.setter
    def value(self, v):
        self.widget.setValue(v)
Ejemplo n.º 9
0
    def __init__(self, parent: 'LayerAlignmentDialog', model: RectAlignmentModel) -> None:
        super(RectAlignSettingsWidget, self).__init__()
        self._parent = parent
        self.model = model

        layout = QtWidgets.QFormLayout()
        self.setLayout(layout)

        dims_gb = QtWidgets.QGroupBox("Scale")
        dims_gb_layout = QtWidgets.QFormLayout()
        dims_gb.setLayout(dims_gb_layout)
        layout.addWidget(dims_gb)

        self.dims_locked_cb = QtWidgets.QCheckBox()
        self.dims_locked_cb.clicked.connect(self.set_dims_locked)
        self.dims_1 = UnitLineEdit(UNIT_GROUP_MM)
        self.dims_2 = UnitLineEdit(UNIT_GROUP_MM)

        self.dims_1.edited.connect(self.changed_dim)
        self.dims_2.edited.connect(self.changed_dim)

        dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb)
        dims_gb_layout.addRow("Dimension 1", self.dims_1)
        dims_gb_layout.addRow("Dimension 2", self.dims_2)

        origin_gb = QtWidgets.QGroupBox("Origin")
        origin_gb_layout = QtWidgets.QFormLayout()
        origin_gb.setLayout(origin_gb_layout)
        layout.addWidget(origin_gb)

        self.origin_ref = QtWidgets.QComboBox()
        self.origin_ref.addItem("Lower-left")
        self.origin_ref.addItem("Lower-right")
        self.origin_ref.addItem("Upper-left")
        self.origin_ref.addItem("Upper-right")
        origin_gb_layout.addRow(self.origin_ref)
        self.origin_ref.currentIndexChanged.connect(self.ref_changed)

        self.origin_x = PLineEdit()
        self.origin_y = PLineEdit()

        self.origin_x.editingFinished.connect(self.changed_dim)
        self.origin_y.editingFinished.connect(self.changed_dim)

        origin_gb_layout.addRow("Offset X:", self.origin_x)
        origin_gb_layout.addRow("Offset Y:", self.origin_y)

        layout.addWidget(origin_gb)

        fr_gb = QtWidgets.QGroupBox("Flip/Rotate")
        fr_gb_layout = QtWidgets.QHBoxLayout()
        fr_gb.setLayout(fr_gb_layout)

        self.flip_x_btn = QtWidgets.QPushButton("Flip X")
        self.flip_x_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_x_btn)

        self.flip_y_btn = QtWidgets.QPushButton("Flip Y")
        self.flip_y_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_y_btn)

        fr_gb_layout.addStretch()
        fr_gb_layout.addWidget(QtWidgets.QLabel("Rotate:"))
        self.theta_le = ThetaLineEdit()
        fr_gb_layout.addWidget(self.theta_le)
        fr_gb_layout.addWidget(QtWidgets.QLabel("\u00b0"))

        self.flip_x_btn.clicked.connect(self.rotate_flip_changed)
        self.flip_y_btn.clicked.connect(self.rotate_flip_changed)
        self.theta_le.editingFinished.connect(self.rotate_flip_changed)

        layout.addWidget(fr_gb)

        self.model.update_matricies()
        self.update_from_model()
Ejemplo n.º 10
0
class RectAlignSettingsWidget(QtWidgets.QWidget):
    def __init__(self, parent: 'LayerAlignmentDialog', model: RectAlignmentModel) -> None:
        super(RectAlignSettingsWidget, self).__init__()
        self._parent = parent
        self.model = model

        layout = QtWidgets.QFormLayout()
        self.setLayout(layout)

        dims_gb = QtWidgets.QGroupBox("Scale")
        dims_gb_layout = QtWidgets.QFormLayout()
        dims_gb.setLayout(dims_gb_layout)
        layout.addWidget(dims_gb)

        self.dims_locked_cb = QtWidgets.QCheckBox()
        self.dims_locked_cb.clicked.connect(self.set_dims_locked)
        self.dims_1 = UnitLineEdit(UNIT_GROUP_MM)
        self.dims_2 = UnitLineEdit(UNIT_GROUP_MM)

        self.dims_1.edited.connect(self.changed_dim)
        self.dims_2.edited.connect(self.changed_dim)

        dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb)
        dims_gb_layout.addRow("Dimension 1", self.dims_1)
        dims_gb_layout.addRow("Dimension 2", self.dims_2)

        origin_gb = QtWidgets.QGroupBox("Origin")
        origin_gb_layout = QtWidgets.QFormLayout()
        origin_gb.setLayout(origin_gb_layout)
        layout.addWidget(origin_gb)

        self.origin_ref = QtWidgets.QComboBox()
        self.origin_ref.addItem("Lower-left")
        self.origin_ref.addItem("Lower-right")
        self.origin_ref.addItem("Upper-left")
        self.origin_ref.addItem("Upper-right")
        origin_gb_layout.addRow(self.origin_ref)
        self.origin_ref.currentIndexChanged.connect(self.ref_changed)

        self.origin_x = PLineEdit()
        self.origin_y = PLineEdit()

        self.origin_x.editingFinished.connect(self.changed_dim)
        self.origin_y.editingFinished.connect(self.changed_dim)

        origin_gb_layout.addRow("Offset X:", self.origin_x)
        origin_gb_layout.addRow("Offset Y:", self.origin_y)

        layout.addWidget(origin_gb)

        fr_gb = QtWidgets.QGroupBox("Flip/Rotate")
        fr_gb_layout = QtWidgets.QHBoxLayout()
        fr_gb.setLayout(fr_gb_layout)

        self.flip_x_btn = QtWidgets.QPushButton("Flip X")
        self.flip_x_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_x_btn)

        self.flip_y_btn = QtWidgets.QPushButton("Flip Y")
        self.flip_y_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_y_btn)

        fr_gb_layout.addStretch()
        fr_gb_layout.addWidget(QtWidgets.QLabel("Rotate:"))
        self.theta_le = ThetaLineEdit()
        fr_gb_layout.addWidget(self.theta_le)
        fr_gb_layout.addWidget(QtWidgets.QLabel("\u00b0"))

        self.flip_x_btn.clicked.connect(self.rotate_flip_changed)
        self.flip_y_btn.clicked.connect(self.rotate_flip_changed)
        self.theta_le.editingFinished.connect(self.rotate_flip_changed)

        layout.addWidget(fr_gb)

        self.model.update_matricies()
        self.update_from_model()

    def update_from_model(self) -> None:
        self.dims_1.setPlaceholderValue(self.model.placeholder_dim_values[0])
        self.dims_2.setPlaceholderValue(self.model.placeholder_dim_values[1])

        self.dims_1.setValue(self.model.dim_values[0])
        self.dims_2.setValue(self.model.dim_values[1])

        self.dims_locked_cb.setChecked(self.model.dims_locked)

        self.origin_x.setText("%f" % self.model.translate_x)
        self.origin_y.setText("%f" % self.model.translate_y)

        # Updated the box index without forcing a retrigger
        self.origin_ref.blockSignals(True)
        self.origin_ref.setCurrentIndex(self.model.origin_idx)
        self.origin_ref.blockSignals(False)

        self.flip_x_btn.setChecked(self.model.flip_x)
        self.flip_y_btn.setChecked(self.model.flip_y)
        self.theta_le.setText("%4.1f" % math.degrees(self.model.rotate_theta))

    def rotate_flip_changed(self) -> None:
        theta = math.radians(float(self.theta_le.text()))
        cmd = cmd_set_rotate(self.model, theta, self.flip_x_btn.isChecked(), self.flip_y_btn.isChecked())
        self._parent.undoStack.push(cmd)

    def set_dims_locked(self) -> None:
        cmd = cmd_set_dimensions_locked(self.model, self.dims_locked_cb.isChecked())
        self._parent.undoStack.push(cmd)

    def changed_dim(self) -> None:
        dim_a = self.dims_1.getValue()
        dim_b = self.dims_2.getValue()

        translate_x = float(self.origin_x.text())
        translate_y = float(self.origin_y.text())
        if dim_a != self.model.dim_values[0] or dim_b != self.model.dim_values[1] or \
                translate_x != self.model.translate_x or translate_y != self.model.translate_y:
            cmd = cmd_set_dimensions(self.model, dim_a, dim_b, translate_x, translate_y)
            self._parent.undoStack.push(cmd)

    def ref_changed(self, idx: int) -> None:
        # Ordering in the combo box isn't pure counterclockwise. Map ordering to CCW
        if idx == 2:
            idx = 3
        elif idx == 3:
            idx = 2

        cmd = cmd_set_origin_reference(self.model, idx)
        self._parent.undoStack.push(cmd)
Ejemplo n.º 11
0
    def __init__(self, parent, model):
        super(RectAlignSettingsWidget, self).__init__()
        self._parent = parent
        self.model = model

        layout = QtGui.QFormLayout()
        self.setLayout(layout)

        dims_gb = QtGui.QGroupBox("Scale")
        dims_gb_layout = QtGui.QFormLayout()
        dims_gb.setLayout(dims_gb_layout)
        layout.addWidget(dims_gb)

        self.dims_locked_cb = QtGui.QCheckBox()
        self.dims_locked_cb.clicked.connect(self.set_dims_locked)
        self.dims_1 = UnitLineEdit(UNIT_GROUP_MM)
        self.dims_2 = UnitLineEdit(UNIT_GROUP_MM)

        self.dims_1.edited.connect(self.changed_dim)
        self.dims_2.edited.connect(self.changed_dim)


        dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb)
        dims_gb_layout.addRow("Dimension 1", self.dims_1)
        dims_gb_layout.addRow("Dimension 2", self.dims_2)

        origin_gb = QtGui.QGroupBox("Origin")
        origin_gb_layout = QtGui.QFormLayout()
        origin_gb.setLayout(origin_gb_layout)
        layout.addWidget(origin_gb)

        self.origin_ref = QtGui.QComboBox()
        self.origin_ref.addItem("Lower-left")
        self.origin_ref.addItem("Lower-right")
        self.origin_ref.addItem("Upper-left")
        self.origin_ref.addItem("Upper-right")
        origin_gb_layout.addRow(self.origin_ref)
        self.origin_ref.currentIndexChanged.connect(self.ref_changed)

        self.origin_x = PLineEdit()
        self.origin_y = PLineEdit()

        self.origin_x.editingFinished.connect(self.changed_dim)
        self.origin_y.editingFinished.connect(self.changed_dim)

        origin_gb_layout.addRow("Offset X:", self.origin_x)
        origin_gb_layout.addRow("Offset Y:", self.origin_y)

        layout.addWidget(origin_gb)

        fr_gb = QtGui.QGroupBox("Flip/Rotate")
        fr_gb_layout = QtGui.QHBoxLayout()
        fr_gb.setLayout(fr_gb_layout)

        self.flip_x_btn = QtGui.QPushButton("Flip X")
        self.flip_x_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_x_btn)

        self.flip_y_btn = QtGui.QPushButton("Flip Y")
        self.flip_y_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_y_btn)

        fr_gb_layout.addStretch()
        fr_gb_layout.addWidget(QtGui.QLabel("Rotate:"))
        self.theta_le = ThetaLineEdit()
        fr_gb_layout.addWidget(self.theta_le)
        fr_gb_layout.addWidget(QtGui.QLabel("\u00b0"))

        self.flip_x_btn.clicked.connect(self.rotate_changed)
        self.flip_y_btn.clicked.connect(self.rotate_changed)
        self.theta_le.editingFinished.connect(self.rotate_changed)

        layout.addWidget(fr_gb)

        self.model.changed.connect(self.update_controls_ra)
        self.model.update_matricies()
        self.update_controls_ra()
Ejemplo n.º 12
0
class RectAlignSettingsWidget(QtGui.QWidget):
    def __init__(self, parent, model):
        super(RectAlignSettingsWidget, self).__init__()
        self._parent = parent
        self.model = model

        layout = QtGui.QFormLayout()
        self.setLayout(layout)

        dims_gb = QtGui.QGroupBox("Scale")
        dims_gb_layout = QtGui.QFormLayout()
        dims_gb.setLayout(dims_gb_layout)
        layout.addWidget(dims_gb)

        self.dims_locked_cb = QtGui.QCheckBox()
        self.dims_locked_cb.clicked.connect(self.set_dims_locked)
        self.dims_1 = UnitLineEdit(UNIT_GROUP_MM)
        self.dims_2 = UnitLineEdit(UNIT_GROUP_MM)

        self.dims_1.edited.connect(self.changed_dim)
        self.dims_2.edited.connect(self.changed_dim)


        dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb)
        dims_gb_layout.addRow("Dimension 1", self.dims_1)
        dims_gb_layout.addRow("Dimension 2", self.dims_2)

        origin_gb = QtGui.QGroupBox("Origin")
        origin_gb_layout = QtGui.QFormLayout()
        origin_gb.setLayout(origin_gb_layout)
        layout.addWidget(origin_gb)

        self.origin_ref = QtGui.QComboBox()
        self.origin_ref.addItem("Lower-left")
        self.origin_ref.addItem("Lower-right")
        self.origin_ref.addItem("Upper-left")
        self.origin_ref.addItem("Upper-right")
        origin_gb_layout.addRow(self.origin_ref)
        self.origin_ref.currentIndexChanged.connect(self.ref_changed)

        self.origin_x = PLineEdit()
        self.origin_y = PLineEdit()

        self.origin_x.editingFinished.connect(self.changed_dim)
        self.origin_y.editingFinished.connect(self.changed_dim)

        origin_gb_layout.addRow("Offset X:", self.origin_x)
        origin_gb_layout.addRow("Offset Y:", self.origin_y)

        layout.addWidget(origin_gb)

        fr_gb = QtGui.QGroupBox("Flip/Rotate")
        fr_gb_layout = QtGui.QHBoxLayout()
        fr_gb.setLayout(fr_gb_layout)

        self.flip_x_btn = QtGui.QPushButton("Flip X")
        self.flip_x_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_x_btn)

        self.flip_y_btn = QtGui.QPushButton("Flip Y")
        self.flip_y_btn.setCheckable(True)
        fr_gb_layout.addWidget(self.flip_y_btn)

        fr_gb_layout.addStretch()
        fr_gb_layout.addWidget(QtGui.QLabel("Rotate:"))
        self.theta_le = ThetaLineEdit()
        fr_gb_layout.addWidget(self.theta_le)
        fr_gb_layout.addWidget(QtGui.QLabel("\u00b0"))

        self.flip_x_btn.clicked.connect(self.rotate_changed)
        self.flip_y_btn.clicked.connect(self.rotate_changed)
        self.theta_le.editingFinished.connect(self.rotate_changed)

        layout.addWidget(fr_gb)

        self.model.changed.connect(self.update_controls_ra)
        self.model.update_matricies()
        self.update_controls_ra()

    def update_controls_ra(self):
        self.dims_1.setPlaceholderText("%f" % self.model.placeholder_dim_values[0])
        self.dims_2.setPlaceholderText("%f" % self.model.placeholder_dim_values[1])

        self.dims_1.setValue(self.model.dim_values[0])
        self.dims_2.setValue(self.model.dim_values[1])

        self.dims_locked_cb.setChecked(self.model.dims_locked)

        self.origin_x.setText("%f" % self.model.translate_x)
        self.origin_y.setText("%f" % self.model.translate_y)

        # Updated the box index without forcing a retrigger
        self.origin_ref.blockSignals(True)
        self.origin_ref.setCurrentIndex(self.model.origin_idx)
        self.origin_ref.blockSignals(False)


        self.flip_x_btn.setChecked(self.model.flip_x)
        self.flip_y_btn.setChecked(self.model.flip_y)
        self.theta_le.setText("%4.1f" % math.degrees(self.model.rotate_theta))


    def rotate_changed(self):
        theta = math.radians(float(self.theta_le.text()))
        cmd = cmd_set_rotate(self.model, theta, self.flip_x_btn.isChecked(), self.flip_y_btn.isChecked())
        self._parent.undoStack.push(cmd)

    def set_dims_locked(self):
        cmd = cmd_set_dimensions_locked(self.model, self.dims_locked_cb.isChecked())
        self._parent.undoStack.push(cmd)

    def changed_dim(self):
        dim_a = self.dims_1.getValue()
        dim_b = self.dims_2.getValue()

        translate_x = float(self.origin_x.text())
        translate_y = float(self.origin_y.text())
        if dim_a != self.model.dim_values[0] or dim_b != self.model.dim_values[1] or \
                        translate_x != self.model.translate_x or translate_y != self.model.translate_y:
            cmd = cmd_set_dimensions(self.model, dim_a, dim_b, translate_x, translate_y)
            self._parent.undoStack.push(cmd)


    def ref_changed(self, idx):
        # Ordering in the combo box isn't pure counterclockwise. Map ordering to CCW
        if idx == 2:
            idx = 3
        elif idx == 3:
            idx = 2

        cmd = cmd_set_origin_reference(self.model, idx)
        self._parent.undoStack.push(cmd)
Ejemplo n.º 13
0
class KeypointAlignmentWidget(QtWidgets.QWidget):
    def __init__(self, parent: 'LayerAlignmentDialog',
                 model: KeypointAlignmentModel) -> None:
        super(KeypointAlignmentWidget, self).__init__()
        self.model = model
        self._parent = parent

        layout = QtWidgets.QFormLayout()
        self.setLayout(layout)

        keypoint_gb = QtWidgets.QGroupBox("Keypoint")
        layout.addWidget(keypoint_gb)

        edit_layout = QtWidgets.QFormLayout()
        keypoint_gb.setLayout(edit_layout)

        self.kpts_sel = QtWidgets.QComboBox()
        self.kpts_sel.setModel(self.model.combo_adapter)
        self.kpts_sel.currentIndexChanged.connect(self.kptChanged)
        edit_layout.addRow("Keypoint:", self.kpts_sel)

        self.wx = UnitLineEdit(UNIT_GROUP_MM)
        self.wy = UnitLineEdit(UNIT_GROUP_MM)
        edit_layout.addRow("World X", self.wx)
        edit_layout.addRow("World Y", self.wy)
        self.wx.edited.connect(self.update_world)
        self.wy.edited.connect(self.update_world)

        self.px = UnitLineEdit(UNIT_GROUP_PX)
        self.py = UnitLineEdit(UNIT_GROUP_PX)
        edit_layout.addRow("Image X", self.px)
        edit_layout.addRow("Image Y", self.py)
        self.px.edited.connect(self.update_layer)
        self.py.edited.connect(self.update_layer)

        self.use_for_alignment = QtWidgets.QCheckBox()
        edit_layout.addRow("Use", self.use_for_alignment)
        self.use_for_alignment.clicked.connect(self.update_used)

        self.add_btn = QtWidgets.QPushButton("Add New")
        self.add_btn.clicked.connect(self.addKeypoint)
        self.del_btn = QtWidgets.QPushButton("Remove Current")
        self.del_btn.clicked.connect(self.delKeypoint)
        bhl = QtWidgets.QHBoxLayout()
        bhl.addWidget(self.add_btn)
        bhl.addWidget(self.del_btn)
        edit_layout.addRow(bhl)

        self.constraint_status_lbl = QtWidgets.QLabel("")
        self.constraint_status_lbl.setWordWrap(True)
        layout.addRow(self.constraint_status_lbl)

        self.model.changed.connect(self.modelChanged)
        self.modelChanged()

    def addKeypoint(self) -> None:
        cmd = cmd_add_keypoint(self.model)
        self._parent.undoStack.push(cmd)
        self.kpts_sel.setCurrentIndex(cmd.index)

    def delKeypoint(self) -> None:
        cmd = cmd_del_keypoint(self.model, self.model.selected_idx)
        self._parent.undoStack.push(cmd)

    def modelChanged(self) -> None:
        cmb_index = -1 if self.model.selected_idx is None else self.model.selected_idx
        self.kpts_sel.blockSignals(True)
        self.kpts_sel.setCurrentIndex(cmb_index)
        self.kpts_sel.blockSignals(False)
        self.updateTextViews()

    def kptChanged(self) -> None:
        """
        Called when keypoint combo-box drop down changed
        :return:
        """
        idx: Optional[int] = self.kpts_sel.currentIndex()
        if idx == -1:
            idx = None
        self.model.selected_idx = idx

    def update_world(self) -> None:
        idx = self.kpts_sel.currentIndex()
        vx = self.wx.getValue()
        vy = self.wy.getValue()
        if vx is None or vy is None:
            # TODO - flash bad box?
            return

        p = Vec2(vx, vy)
        cmd = cmd_set_keypoint_world(self.model, idx, p)
        self._parent.undoStack.push(cmd)

    def update_layer(self) -> None:
        idx = self.kpts_sel.currentIndex()
        vx = self.px.getValue()
        vy = self.py.getValue()
        if vx is None or vy is None:
            # TODO - flash bad box?
            return

        p = Vec2(vx, vy)
        cmd = cmd_set_keypoint_px(self.model, idx, p)
        self._parent.undoStack.push(cmd)

    def update_used(self) -> None:
        idx = self.kpts_sel.currentIndex()
        cmd = cmd_set_keypoint_used(self.model, idx,
                                    self.use_for_alignment.isChecked())
        self._parent.undoStack.push(cmd)

    def updateTextViews(self) -> None:
        idx = self.model.selected_idx

        # Disable keypoint delete when we selected a prior-existing keypoint
        # Also disable delete button when no kp is selected
        self.del_btn.setEnabled(idx is not None
                                and self.model.keypoints[idx].is_new)

        self.updateConstraintLabel()

        # If nothing is selected, clear-out all the edit fields
        if idx is None:
            self.wx.setValue(None)
            self.wy.setValue(None)
            self.px.setValue(None)
            self.py.setValue(None)
            self.wx.setEnabled(False)
            self.wy.setEnabled(False)
            self.px.setEnabled(False)
            self.py.setEnabled(False)
            self.use_for_alignment.setEnabled(False)
            self.use_for_alignment.setChecked(False)
            return

        kpt = self.model.keypoints[idx]

        # Disable editing of old keypoints
        self.wx.setEnabled(kpt.is_new)
        self.wy.setEnabled(kpt.is_new)

        self.wx.setValue(kpt.world.x)
        self.wy.setValue(kpt.world.y)

        self.use_for_alignment.setEnabled(True)
        self.use_for_alignment.setChecked(kpt.use)

        self.px.setEnabled(kpt.use)
        self.py.setEnabled(kpt.use)

        self.px.setValue(kpt.layer.x)
        self.py.setValue(kpt.layer.y)

    def updateConstraintLabel(self) -> None:
        cs = self.model.constraint_info

        if cs == Constraint.Unconstrained:
            self.constraint_status_lbl.setText(
                "Image is unconstrained. Will not be aligned in world space. "
                + "This is probably not what you want")
        elif cs == Constraint.Translation:
            self.constraint_status_lbl.setText(
                "Image is constrained only by one keypoint. This will only position "
                +
                "the image in space, but not provide scale or alignment information. "
                + "This is probably not what you want")
        elif cs == Constraint.Rotate_Scale:
            self.constraint_status_lbl.setText(
                "Image is constrained by two keypoints. This will only position, "
                +
                "proportionally scale and rotate the image. That may be OK for "
                + "scanned images")
        elif cs == Constraint.Orthogonal:
            self.constraint_status_lbl.setText(
                "Image is constrained by three keypoints. This allows alignment of "
                +
                "scale, rotation, translation and shear. This is probably not what "
                +
                "you want, but may be useful for synthetically transformed images"
            )
        elif cs == Constraint.Perspective:
            self.constraint_status_lbl.setText(
                "Image is constrained by four keypoints. This allows for full recovery"
                +
                " of the perspective transform. This is probably what you want "
                + "for camera imagery.")
        elif cs == Constraint.Singular:
            self.constraint_status_lbl.setText(
                "Can't solve for these constraints. Are keypoints overlapping or "
                + "colinear in either world or image space?")
        elif cs == Constraint.Overconstrained:
            self.constraint_status_lbl.setText(
                "Too many constraints to solve for. " +
                "Max 4 enabled keypoints for alignment.")
Ejemplo n.º 14
0
class KeypointAlignmentWidget(QtGui.QWidget):
    def __init__(self, parent, model):
        super(KeypointAlignmentWidget, self).__init__()
        self.model = model
        self._parent = parent

        layout = QtGui.QFormLayout()
        self.setLayout(layout)

        keypoint_gb = QtGui.QGroupBox("Keypoint")
        layout.addWidget(keypoint_gb)

        edit_layout = QtGui.QFormLayout()
        keypoint_gb.setLayout(edit_layout)


        self.kpts_sel = QtGui.QComboBox()
        self.kpts_sel.setModel(self.model.combo_adapter)
        self.kpts_sel.currentIndexChanged.connect(self.kptChanged)
        edit_layout.addRow("Keypoint:", self.kpts_sel)

        self.wx = UnitLineEdit(UNIT_GROUP_MM)
        self.wy = UnitLineEdit(UNIT_GROUP_MM)
        edit_layout.addRow("World X", self.wx)
        edit_layout.addRow("World Y", self.wy)
        self.wx.edited.connect(self.update_world)
        self.wy.edited.connect(self.update_world)

        self.px = UnitLineEdit(UNIT_GROUP_PX)
        self.py = UnitLineEdit(UNIT_GROUP_PX)
        edit_layout.addRow("Image X", self.px)
        edit_layout.addRow("Image Y", self.py)
        self.px.edited.connect(self.update_layer)
        self.py.edited.connect(self.update_layer)


        self.use_for_alignment = QtGui.QCheckBox()
        edit_layout.addRow("Use", self.use_for_alignment)
        self.use_for_alignment.clicked.connect(self.update_used)

        self.add_btn = QtGui.QPushButton("Add New")
        self.add_btn.clicked.connect(self.addKeypoint)
        self.del_btn = QtGui.QPushButton("Remove Current")
        self.del_btn.clicked.connect(self.delKeypoint)
        bhl = QtGui.QHBoxLayout()
        bhl.addWidget(self.add_btn)
        bhl.addWidget(self.del_btn)
        edit_layout.addRow(bhl)


        self.constraint_status_lbl = QtGui.QLabel("")
        self.constraint_status_lbl.setWordWrap(True)
        layout.addRow(self.constraint_status_lbl)

        self.model.changed.connect(self.modelChanged)
        self.modelChanged()

    def addKeypoint(self):
        cmd = cmd_add_keypoint(self.model)
        self._parent.undoStack.push(cmd)
        self.kpts_sel.setCurrentIndex(cmd.index)

    def delKeypoint(self):
        cmd = cmd_del_keypoint(self.model, self.model.selected_idx)
        self._parent.undoStack.push(cmd)

    def modelChanged(self):
        cmb_index = -1 if self.model.selected_idx is None else self.model.selected_idx
        self.kpts_sel.blockSignals(True)
        self.kpts_sel.setCurrentIndex(cmb_index)
        self.kpts_sel.blockSignals(False)
        self.updateTextViews()

    def kptChanged(self):
        """
        Called when keypoint combo-box drop down changed
        :return:
        """
        idx = self.kpts_sel.currentIndex()
        if idx == -1:
            idx = None
        self.model.selected_idx = idx

    def update_world(self):
        idx = self.kpts_sel.currentIndex()
        p = Point2(self.wx.getValue(), self.wy.getValue())
        cmd = cmd_set_keypoint_world(self.model, idx, p)
        self._parent.undoStack.push(cmd)

    def update_layer(self):
        idx = self.kpts_sel.currentIndex()
        p = Point2(self.px.getValue(), self.py.getValue())
        cmd = cmd_set_keypoint_px(self.model, idx, p)
        self._parent.undoStack.push(cmd)

    def update_used(self):
        idx = self.kpts_sel.currentIndex()
        cmd = cmd_set_keypoint_used(self.model, idx, self.use_for_alignment.isChecked())
        self._parent.undoStack.push(cmd)

    def updateTextViews(self):
        idx = self.model.selected_idx

        # Disable keypoint delete when we selected a prior-existing keypoint
        # Also disable delete button when no kp is selected
        self.del_btn.setEnabled(idx is not None and self.model.keypoints[idx].is_new)

        self.updateConstraintLabel()

        # If nothing is selected, clear-out all the edit fields
        if idx is None:
            self.wx.setValue(None)
            self.wy.setValue(None)
            self.px.setValue(None)
            self.py.setValue(None)
            self.wx.setEnabled(False)
            self.wy.setEnabled(False)
            self.px.setEnabled(False)
            self.py.setEnabled(False)
            self.use_for_alignment.setEnabled(False)
            self.use_for_alignment.setChecked(False)
            return

        kpt = self.model.keypoints[idx]

        # Disable editing of old keypoints
        self.wx.setEnabled(kpt.is_new)
        self.wy.setEnabled(kpt.is_new)

        self.wx.setValue(kpt.world.x)
        self.wy.setValue(kpt.world.y)

        self.use_for_alignment.setEnabled(True)
        self.use_for_alignment.setChecked(kpt.use)

        self.px.setEnabled(kpt.use)
        self.py.setEnabled(kpt.use)

        self.px.setValue(kpt.layer.x)
        self.py.setValue(kpt.layer.y)

    def updateConstraintLabel(self):
        cs = self.model.constraint_info

        if cs == CONS_UNCONSTRAINED:
            self.constraint_status_lbl.setText("Image is unconstrained. Will not be aligned in world space. " +
                                               "This is probably not what you want")
        elif cs == CONS_TRANSLATION:
            self.constraint_status_lbl.setText("Image is constrained only by one keypoint. This will only position " +
                                               "the image in space, but not provide scale or alignment information. " +
                                               "This is probably not what you want")
        elif cs == CONS_ROTATE_SCALE:
            self.constraint_status_lbl.setText("Image is constrained by two keypoints. This will only position, " +
                                               "proportionally scale and rotate the image. That may be OK for " +
                                               "scanned images")
        elif cs == CONS_ORTHOGONAL:
            self.constraint_status_lbl.setText("Image is constrained by three keypoints. This allows alignment of " +
                                               "scale, rotation, translation and shear. This is probably not what " +
                                               "you want, but may be useful for synthetically transformed images")
        elif cs == CONS_PERSPECTIVE:
            self.constraint_status_lbl.setText("Image is constrained by four keypoints. This allows for full recovery" +
                                               " of the perspective transform. This is probably what you want " +
                                               "for camera imagery.")
        elif cs == CONS_SINGULAR:
            self.constraint_status_lbl.setText("Can't solve for these constraints. Are keypoints overlapping or "+
                                               "colinear in either world or image space?")
        elif cs == CONS_OVERCONSTRAINED:
            self.constraint_status_lbl.setText("Too many constraints to solve for. " +
                                               "Max 4 enabled keypoints for alignment.")