def test_undo_redo( brush_shape, brush_size, mode, selected_label, preserve_labels, n_dimensional, ): blobs = data.binary_blobs(length=64, volume_fraction=0.3, n_dim=3) layer = Labels(blobs) data_history = [blobs.copy()] with pytest.warns(FutureWarning): layer.brush_shape = brush_shape layer.brush_size = brush_size layer.mode = mode layer.selected_label = selected_label layer.preserve_labels = preserve_labels layer.n_edit_dimensions = 3 if n_dimensional else 2 coord = np.random.random((3, )) * (np.array(blobs.shape) - 1) while layer.data[tuple(coord.astype(int))] == 0 and np.any(layer.data): coord = np.random.random((3, )) * (np.array(blobs.shape) - 1) if layer.mode == 'fill': layer.fill(coord, layer.selected_label) if layer.mode == 'erase': layer.paint(coord, 0) if layer.mode == 'paint': layer.paint(coord, layer.selected_label) data_history.append(np.copy(layer.data)) layer.undo() np.testing.assert_array_equal(layer.data, data_history[0]) layer.redo() np.testing.assert_array_equal(layer.data, data_history[1])
def test_erase_3d_undo(MouseEvent): """Test erasing labels in 3D then undoing the erase. Specifically, this test checks that undo is correctly filled even when a click and drag starts outside of the data volume. """ data = np.zeros((20, 20, 20), dtype=np.int32) data[10, :, :] = 1 layer = Labels(data) layer.brush_size = 5 layer.mode = 'erase' layer._slice_dims(point=(0, 0, 0), ndisplay=3) layer.n_edit_dimensions = 3 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(-1, -1, -1), view_direction=(1, 0, 0), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_press_callbacks(layer, event) # Simulate drag. Note: we need to include top left and bottom right in the # drag or there are no coordinates to interpolate event = ReadOnlyWrapper( MouseEvent( type='mouse_move', is_dragging=True, position=(-1, 0.1, 0.1), view_direction=(1, 0, 0), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_move_callbacks(layer, event) event = ReadOnlyWrapper( MouseEvent( type='mouse_move', is_dragging=True, position=(-1, 18.9, 18.9), view_direction=(1, 0, 0), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper( MouseEvent( type='mouse_release', is_dragging=False, position=(-1, 21, 21), view_direction=(1, 0, 0), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_release_callbacks(layer, event) # Erasing goes from (-1, -1, -1) to (-1, 21, 21), should split the labels # into two sections. Undoing should work and reunite the labels to one # square assert ndi.label(layer.data)[1] == 2 layer.undo() assert ndi.label(layer.data)[1] == 1