vispy 0.14.2__cp39-cp39-macosx_11_0_arm64.whl → 0.15.0__cp39-cp39-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of vispy might be problematic. Click here for more details.
- vispy/app/backends/_qt.py +46 -11
- vispy/color/colormap.py +106 -27
- vispy/color/tests/test_color.py +27 -1
- vispy/ext/cocoapy.py +1 -21
- vispy/geometry/__init__.py +1 -1
- vispy/geometry/calculations.py +30 -2
- vispy/geometry/meshdata.py +3 -1
- vispy/geometry/tests/test_triangulation.py +88 -0
- vispy/geometry/triangulation.py +14 -14
- vispy/gloo/buffer.py +4 -4
- vispy/gloo/gl/tests/test_functionality.py +4 -2
- vispy/gloo/glir.py +7 -2
- vispy/gloo/program.py +2 -2
- vispy/gloo/texture.py +4 -3
- vispy/scene/cameras/arcball.py +1 -2
- vispy/scene/cameras/base_camera.py +63 -50
- vispy/scene/cameras/panzoom.py +4 -1
- vispy/scene/cameras/perspective.py +6 -1
- vispy/scene/cameras/turntable.py +11 -1
- vispy/testing/_runners.py +3 -1
- vispy/util/__init__.py +15 -0
- vispy/version.py +9 -4
- vispy/visuals/_scalable_textures.py +7 -5
- vispy/visuals/collections/array_list.py +4 -4
- vispy/visuals/filters/mesh.py +6 -1
- vispy/visuals/gridlines.py +61 -5
- vispy/visuals/image.py +21 -8
- vispy/visuals/surface_plot.py +1 -1
- vispy/visuals/tests/test_gridlines.py +30 -0
- vispy/visuals/tests/test_image.py +17 -15
- vispy/visuals/tests/test_scalable_textures.py +16 -0
- vispy/visuals/tests/test_surface_plot.py +8 -3
- vispy/visuals/text/_sdf_cpu.cpython-39-darwin.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +2 -0
- vispy/visuals/volume.py +35 -4
- {vispy-0.14.2.dist-info → vispy-0.15.0.dist-info}/METADATA +53 -28
- {vispy-0.14.2.dist-info → vispy-0.15.0.dist-info}/RECORD +40 -39
- {vispy-0.14.2.dist-info → vispy-0.15.0.dist-info}/WHEEL +2 -1
- {vispy-0.14.2.dist-info → vispy-0.15.0.dist-info/licenses}/LICENSE.txt +1 -1
- {vispy-0.14.2.dist-info → vispy-0.15.0.dist-info}/top_level.txt +0 -0
vispy/visuals/gridlines.py
CHANGED
|
@@ -4,27 +4,31 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import division
|
|
6
6
|
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
7
9
|
from .image import ImageVisual
|
|
8
10
|
from ..color import Color
|
|
9
11
|
from .shaders import Function
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
_GRID_COLOR = """
|
|
15
|
+
uniform vec4 u_gridlines_bounds;
|
|
16
|
+
uniform float u_border_width;
|
|
17
|
+
|
|
13
18
|
vec4 grid_color(vec2 pos) {
|
|
14
19
|
vec4 px_pos = $map_to_doc(vec4(pos, 0, 1));
|
|
15
20
|
px_pos /= px_pos.w;
|
|
16
21
|
|
|
17
22
|
// Compute vectors representing width, height of pixel in local coords
|
|
18
|
-
float s = 1.;
|
|
19
23
|
vec4 local_pos = $map_doc_to_local(px_pos);
|
|
20
|
-
vec4 dx = $map_doc_to_local(px_pos + vec4(1.0
|
|
21
|
-
vec4 dy = $map_doc_to_local(px_pos + vec4(0, 1.0
|
|
24
|
+
vec4 dx = $map_doc_to_local(px_pos + vec4(1.0, 0, 0, 0));
|
|
25
|
+
vec4 dy = $map_doc_to_local(px_pos + vec4(0, 1.0, 0, 0));
|
|
22
26
|
local_pos /= local_pos.w;
|
|
23
27
|
dx = dx / dx.w - local_pos;
|
|
24
28
|
dy = dy / dy.w - local_pos;
|
|
25
29
|
|
|
26
30
|
// Pixel length along each axis, rounded to the nearest power of 10
|
|
27
|
-
vec2 px =
|
|
31
|
+
vec2 px = vec2(abs(dx.x) + abs(dy.x), abs(dx.y) + abs(dy.y));
|
|
28
32
|
float log10 = log(10.0);
|
|
29
33
|
float sx = pow(10.0, floor(log(px.x) / log10) + 1.) * $scale.x;
|
|
30
34
|
float sy = pow(10.0, floor(log(px.y) / log10) + 1.) * $scale.y;
|
|
@@ -57,6 +61,17 @@ vec4 grid_color(vec2 pos) {
|
|
|
57
61
|
if (alpha == 0.) {
|
|
58
62
|
discard;
|
|
59
63
|
}
|
|
64
|
+
|
|
65
|
+
if (any(lessThan(local_pos.xy + u_border_width / 2, u_gridlines_bounds.xz)) ||
|
|
66
|
+
any(greaterThan(local_pos.xy - u_border_width / 2, u_gridlines_bounds.yw))) {
|
|
67
|
+
discard;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (any(lessThan(local_pos.xy - u_gridlines_bounds.xz, vec2(u_border_width / 2))) ||
|
|
71
|
+
any(lessThan(u_gridlines_bounds.yw - local_pos.xy, vec2(u_border_width / 2)))) {
|
|
72
|
+
alpha = 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
return vec4($color.rgb, $color.a * alpha);
|
|
61
76
|
}
|
|
62
77
|
"""
|
|
@@ -73,9 +88,16 @@ class GridLinesVisual(ImageVisual):
|
|
|
73
88
|
color : Color
|
|
74
89
|
The base color for grid lines. The final color may have its alpha
|
|
75
90
|
channel modified.
|
|
91
|
+
grid_bounds : tuple or None
|
|
92
|
+
The lower and upper bound for each axis beyond which no grid is rendered.
|
|
93
|
+
In the form of (minx, maxx, miny, maxy).
|
|
94
|
+
border_width : float
|
|
95
|
+
Tickness of the border rendered at the bounds of the grid.
|
|
76
96
|
"""
|
|
77
97
|
|
|
78
|
-
def __init__(self, scale=(1, 1), color='w'
|
|
98
|
+
def __init__(self, scale=(1, 1), color='w',
|
|
99
|
+
grid_bounds=None,
|
|
100
|
+
border_width=2):
|
|
79
101
|
# todo: PlaneVisual should support subdivide/impostor methods from
|
|
80
102
|
# image and gridlines should inherit from plane instead.
|
|
81
103
|
self._grid_color_fn = Function(_GRID_COLOR)
|
|
@@ -86,6 +108,40 @@ class GridLinesVisual(ImageVisual):
|
|
|
86
108
|
self.shared_program.frag['get_data'] = self._grid_color_fn
|
|
87
109
|
cfun = Function('vec4 null(vec4 x) { return x; }')
|
|
88
110
|
self.shared_program.frag['color_transform'] = cfun
|
|
111
|
+
self.unfreeze()
|
|
112
|
+
self.grid_bounds = grid_bounds
|
|
113
|
+
self.border_width = border_width
|
|
114
|
+
self.freeze()
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def grid_bounds(self):
|
|
118
|
+
return self._grid_bounds
|
|
119
|
+
|
|
120
|
+
@grid_bounds.setter
|
|
121
|
+
def grid_bounds(self, value):
|
|
122
|
+
if value is None:
|
|
123
|
+
value = (None,) * 4
|
|
124
|
+
grid_bounds = []
|
|
125
|
+
for i, v in enumerate(value):
|
|
126
|
+
if v is None:
|
|
127
|
+
if i % 2:
|
|
128
|
+
v = -np.inf
|
|
129
|
+
else:
|
|
130
|
+
v = np.inf
|
|
131
|
+
grid_bounds.append(v)
|
|
132
|
+
self.shared_program['u_gridlines_bounds'] = value
|
|
133
|
+
self._grid_bounds = grid_bounds
|
|
134
|
+
self.update()
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def border_width(self):
|
|
138
|
+
return self._border_width
|
|
139
|
+
|
|
140
|
+
@border_width.setter
|
|
141
|
+
def border_width(self, value):
|
|
142
|
+
self.shared_program['u_border_width'] = value
|
|
143
|
+
self._border_width = value
|
|
144
|
+
self.update()
|
|
89
145
|
|
|
90
146
|
@property
|
|
91
147
|
def size(self):
|
vispy/visuals/image.py
CHANGED
|
@@ -16,6 +16,7 @@ from .transforms import NullTransform
|
|
|
16
16
|
from .visual import Visual
|
|
17
17
|
from ..io import load_spatial_filters
|
|
18
18
|
from ._scalable_textures import CPUScaledTexture2D, GPUScaledTexture2D
|
|
19
|
+
from ..util import np_copy_if_needed
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
_VERTEX_SHADER = """
|
|
@@ -90,11 +91,9 @@ _TEXTURE_LOOKUP = """
|
|
|
90
91
|
|
|
91
92
|
_APPLY_CLIM_FLOAT = """
|
|
92
93
|
float apply_clim(float data) {
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
discard;
|
|
97
|
-
}
|
|
94
|
+
// pass through NaN values to get handled by the colormap
|
|
95
|
+
if (!(data <= 0.0 || 0.0 <= data)) return data;
|
|
96
|
+
|
|
98
97
|
data = clamp(data, min($clim.x, $clim.y), max($clim.x, $clim.y));
|
|
99
98
|
data = (data - $clim.x) / ($clim.y - $clim.x);
|
|
100
99
|
return data;
|
|
@@ -102,7 +101,7 @@ _APPLY_CLIM_FLOAT = """
|
|
|
102
101
|
|
|
103
102
|
_APPLY_CLIM = """
|
|
104
103
|
vec4 apply_clim(vec4 color) {
|
|
105
|
-
// Handle NaN values
|
|
104
|
+
// Handle NaN values (clamp them to the minimum value)
|
|
106
105
|
// http://stackoverflow.com/questions/11810158/how-to-deal-with-nan-or-inf-in-opengl-es-2-0-shaders
|
|
107
106
|
color.r = !(color.r <= 0.0 || 0.0 <= color.r) ? min($clim.x, $clim.y) : color.r;
|
|
108
107
|
color.g = !(color.g <= 0.0 || 0.0 <= color.g) ? min($clim.x, $clim.y) : color.g;
|
|
@@ -116,6 +115,9 @@ _APPLY_CLIM = """
|
|
|
116
115
|
|
|
117
116
|
_APPLY_GAMMA_FLOAT = """
|
|
118
117
|
float apply_gamma(float data) {
|
|
118
|
+
// pass through NaN values to get handled by the colormap
|
|
119
|
+
if (!(data <= 0.0 || 0.0 <= data)) return data;
|
|
120
|
+
|
|
119
121
|
return pow(data, $gamma);
|
|
120
122
|
}"""
|
|
121
123
|
|
|
@@ -128,7 +130,7 @@ _APPLY_GAMMA = """
|
|
|
128
130
|
|
|
129
131
|
_NULL_COLOR_TRANSFORM = 'vec4 pass(vec4 color) { return color; }'
|
|
130
132
|
|
|
131
|
-
_C2L_RED = 'float
|
|
133
|
+
_C2L_RED = 'float color_to_luminance(vec4 color) { return color.r; }'
|
|
132
134
|
|
|
133
135
|
_CUSTOM_FILTER = """
|
|
134
136
|
vec4 texture_lookup(vec2 texcoord) {
|
|
@@ -380,7 +382,7 @@ class ImageVisual(Visual):
|
|
|
380
382
|
texture_format : str or None
|
|
381
383
|
|
|
382
384
|
"""
|
|
383
|
-
data = np.array(image, copy=copy)
|
|
385
|
+
data = np.array(image, copy=copy or np_copy_if_needed)
|
|
384
386
|
if np.iscomplexobj(data):
|
|
385
387
|
raise TypeError(
|
|
386
388
|
"Complex data types not supported. Please use 'ComplexImage' instead"
|
|
@@ -455,6 +457,17 @@ class ImageVisual(Visual):
|
|
|
455
457
|
self.shared_program.frag['color_transform'][2]['gamma'] = self._gamma
|
|
456
458
|
self.update()
|
|
457
459
|
|
|
460
|
+
@property
|
|
461
|
+
def bad_color(self):
|
|
462
|
+
"""Color used to render NaN values."""
|
|
463
|
+
return self._cmap.get_bad_color()
|
|
464
|
+
|
|
465
|
+
@bad_color.setter
|
|
466
|
+
def bad_color(self, color):
|
|
467
|
+
self._cmap.set_bad_color(color)
|
|
468
|
+
self._need_colortransform_update = True
|
|
469
|
+
self.update()
|
|
470
|
+
|
|
458
471
|
@property
|
|
459
472
|
def method(self):
|
|
460
473
|
"""Get rendering method name."""
|
vispy/visuals/surface_plot.py
CHANGED
|
@@ -126,7 +126,7 @@ class SurfacePlotVisual(MeshVisual):
|
|
|
126
126
|
# convert (width, height, 4) to (num_verts, 4)
|
|
127
127
|
vert_shape = self.__vertices.shape
|
|
128
128
|
num_vertices = vert_shape[0] * vert_shape[1]
|
|
129
|
-
colors = colors.reshape(num_vertices,
|
|
129
|
+
colors = colors.reshape(num_vertices, colors.shape[-1])
|
|
130
130
|
return colors
|
|
131
131
|
|
|
132
132
|
def set_data(self, x=None, y=None, z=None, colors=None):
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
3
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Tests for GridLines
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
from vispy.scene import GridLines, STTransform
|
|
12
|
+
from vispy.testing import (requires_application, TestingCanvas,
|
|
13
|
+
run_tests_if_main)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@requires_application()
|
|
17
|
+
def test_gridlines():
|
|
18
|
+
with TestingCanvas(size=(80, 80)) as c:
|
|
19
|
+
grid = GridLines(parent=c.scene)
|
|
20
|
+
grid.transform = STTransform(translate=(40, 40))
|
|
21
|
+
render = c.render()
|
|
22
|
+
np.testing.assert_array_equal(render[40, 40], (151, 151, 151, 255))
|
|
23
|
+
np.testing.assert_array_equal(render[50, 50], (0, 0, 0, 255))
|
|
24
|
+
|
|
25
|
+
grid.grid_bounds = (-10, 10, -10, 10)
|
|
26
|
+
render = c.render()
|
|
27
|
+
np.testing.assert_array_equal(render[50, 50], (255, 255, 255, 255))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
run_tests_if_main()
|
|
@@ -128,28 +128,30 @@ def test_image_clims_and_gamma(input_dtype, texture_format, num_channels,
|
|
|
128
128
|
@pytest.mark.xfail(IS_CI, reason="CI environments sometimes treat NaN as 0")
|
|
129
129
|
@requires_application()
|
|
130
130
|
@pytest.mark.parametrize('texture_format', [None, 'auto'])
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
data
|
|
135
|
-
data[:
|
|
131
|
+
@pytest.mark.parametrize('bad_color', [None, (1, 0, 0, 1)])
|
|
132
|
+
def test_image_nan(texture_format, bad_color):
|
|
133
|
+
size = (80, 80)
|
|
134
|
+
data = np.ones(size)
|
|
135
|
+
data[:20, :20] = np.nan
|
|
136
|
+
data[-20: -20:] = 0
|
|
136
137
|
|
|
137
|
-
expected = (np.ones(
|
|
138
|
-
|
|
139
|
-
expected[:5, -5:, :3] = 0
|
|
138
|
+
expected = (np.ones(size + (4,)) * 255).astype(np.uint8)
|
|
139
|
+
expected[-20: -20:] = (0, 0, 0, 225)
|
|
140
140
|
if texture_format is None:
|
|
141
141
|
# CPU scaling's NaNs get converted to 0s
|
|
142
|
-
expected[:
|
|
142
|
+
expected[:20, :20] = (0, 0, 0, 255)
|
|
143
143
|
else:
|
|
144
144
|
# GPU receives NaNs
|
|
145
|
-
# nan -
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
# nan - mapped to bad color
|
|
146
|
+
if bad_color is None:
|
|
147
|
+
# no bad color means transparent, so we should see the green canvas
|
|
148
|
+
bad_color = (0, 1, 0, 1)
|
|
149
|
+
expected[:20, :20] = np.array(bad_color) * 255
|
|
149
150
|
|
|
150
151
|
with TestingCanvas(size=size[::-1], bgcolor=(0, 1, 0)) as c:
|
|
151
|
-
Image(data, cmap='grays',
|
|
152
|
+
image = Image(data, cmap='grays', clim=(0, 1),
|
|
152
153
|
texture_format=texture_format, parent=c.scene)
|
|
154
|
+
image.bad_color = bad_color
|
|
153
155
|
rendered = c.render()
|
|
154
156
|
np.testing.assert_allclose(rendered, expected)
|
|
155
157
|
|
|
@@ -327,7 +329,7 @@ def test_image_interpolation():
|
|
|
327
329
|
assert np.allclose(render[center_left], black)
|
|
328
330
|
assert np.allclose(render[center_right], white)
|
|
329
331
|
|
|
330
|
-
image.interpolation = '
|
|
332
|
+
image.interpolation = 'linear'
|
|
331
333
|
render = c.render()
|
|
332
334
|
assert np.allclose(render[left], black)
|
|
333
335
|
assert np.allclose(render[right], white)
|
|
@@ -133,6 +133,22 @@ def test_clim_handling_cpu():
|
|
|
133
133
|
assert st.clim == (5, 25)
|
|
134
134
|
assert st.clim_normalized == (0, 1)
|
|
135
135
|
|
|
136
|
+
# u8 auto -> f32 auto
|
|
137
|
+
st = CPUScaledStub()
|
|
138
|
+
st.set_clim("auto")
|
|
139
|
+
assert st.clim == "auto"
|
|
140
|
+
st.scale_and_set_data(ref_data.astype(np.uint8))
|
|
141
|
+
assert st.clim == (5, 25)
|
|
142
|
+
assert st.clim_normalized == (0, 1)
|
|
143
|
+
# set new data with an out-of-range value
|
|
144
|
+
# it should clip at the limits of the original data type
|
|
145
|
+
st.set_clim("auto")
|
|
146
|
+
assert st.clim == "auto"
|
|
147
|
+
new_data = np.array([[10, 10, 5], [15, 2048, 15]], dtype=np.float32)
|
|
148
|
+
st.scale_and_set_data(new_data)
|
|
149
|
+
assert st.clim == (5, 255)
|
|
150
|
+
assert st.clim_normalized == (0, 1)
|
|
151
|
+
|
|
136
152
|
|
|
137
153
|
def test_clim_handling_gpu():
|
|
138
154
|
ref_data = np.array([[10, 10, 5], [15, 25, 15]])
|
|
@@ -12,7 +12,8 @@ import pytest
|
|
|
12
12
|
@requires_application()
|
|
13
13
|
@pytest.mark.parametrize('x1dim', [True, False])
|
|
14
14
|
@pytest.mark.parametrize('y1dim', [True, False])
|
|
15
|
-
|
|
15
|
+
@pytest.mark.parametrize('use_vertex_colors', [True, False])
|
|
16
|
+
def test_surface_plot(x1dim:bool, y1dim:bool, use_vertex_colors:bool):
|
|
16
17
|
"""Test SurfacePlot visual"""
|
|
17
18
|
with TestingCanvas(bgcolor='w') as c:
|
|
18
19
|
|
|
@@ -29,7 +30,8 @@ def test_surface_plot(x1dim:bool, y1dim:bool):
|
|
|
29
30
|
# color vertices
|
|
30
31
|
cnorm = z / abs(np.amax(z))
|
|
31
32
|
colormap = get_colormap("viridis").map(cnorm)
|
|
32
|
-
|
|
33
|
+
if not use_vertex_colors:
|
|
34
|
+
colormap = colormap.reshape(z.shape + (-1,))
|
|
33
35
|
|
|
34
36
|
# 1 or 2 dimensional x and y data
|
|
35
37
|
x_input = x if x1dim else xv
|
|
@@ -41,7 +43,10 @@ def test_surface_plot(x1dim:bool, y1dim:bool):
|
|
|
41
43
|
y=y_input,
|
|
42
44
|
shading=None)
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
if use_vertex_colors:
|
|
47
|
+
surface.mesh_data.set_vertex_colors(colormap)
|
|
48
|
+
else:
|
|
49
|
+
surface.set_data(colors=colormap)
|
|
45
50
|
|
|
46
51
|
# c.draw_visual(surface)
|
|
47
52
|
view.add(surface)
|
|
Binary file
|
vispy/visuals/text/_sdf_cpu.pyx
CHANGED
vispy/visuals/volume.py
CHANGED
|
@@ -417,8 +417,8 @@ _ATTENUATED_MIP_SNIPPETS = dict(
|
|
|
417
417
|
// Scale and clamp accumulation in `sumval` by contrast limits so that:
|
|
418
418
|
// * attenuation value does not depend on data values
|
|
419
419
|
// * negative values do not amplify instead of attenuate
|
|
420
|
-
sumval = sumval + clamp((val - clim.x) / (clim.y - clim.x), 0.0, 1.0);
|
|
421
|
-
scale = exp(-u_attenuation * (sumval - 1)
|
|
420
|
+
sumval = sumval + u_relative_step_size * clamp((val - clim.x) / (clim.y - clim.x), 0.0, 1.0);
|
|
421
|
+
scale = exp(-u_attenuation * (sumval - 1));
|
|
422
422
|
if( maxval > scale * clim.y ) {
|
|
423
423
|
// stop if no chance of finding a higher maxval
|
|
424
424
|
iter = nsteps;
|
|
@@ -1165,9 +1165,40 @@ class VolumeVisual(Visual):
|
|
|
1165
1165
|
|
|
1166
1166
|
@relative_step_size.setter
|
|
1167
1167
|
def relative_step_size(self, value):
|
|
1168
|
+
"""Set the relative step size used during raycasting.
|
|
1169
|
+
|
|
1170
|
+
Very small values give increased detail when rendering volumes with
|
|
1171
|
+
few voxels, but values that are too small give worse performance
|
|
1172
|
+
(framerate), in extreme cases causing a GPU hang and for the process
|
|
1173
|
+
to be killed by the OS. See discussion at:
|
|
1174
|
+
|
|
1175
|
+
https://github.com/vispy/vispy/pull/2587
|
|
1176
|
+
|
|
1177
|
+
For this reason, this setter issues a warning when the value is
|
|
1178
|
+
smaller than ``side_len / (2 * MAX_CANVAS_SIZE)``, where ``side_len``
|
|
1179
|
+
is the smallest side of the volume and ``MAX_CANVAS_SIZE`` is what
|
|
1180
|
+
we consider to be the largest likely monitor resolution along its
|
|
1181
|
+
longest side: 7680 pixels, equivalent to an 8K monitor.
|
|
1182
|
+
|
|
1183
|
+
This setter also raises a ValueError when the value is 0 or negative.
|
|
1184
|
+
"""
|
|
1168
1185
|
value = float(value)
|
|
1169
|
-
|
|
1170
|
-
|
|
1186
|
+
side_len = np.min(self._vol_shape)
|
|
1187
|
+
MAX_CANVAS_SIZE = 7680
|
|
1188
|
+
minimum_val = side_len / (2 * MAX_CANVAS_SIZE)
|
|
1189
|
+
if value <= 0:
|
|
1190
|
+
raise ValueError('relative_step_size cannot be 0 or negative.')
|
|
1191
|
+
elif value < minimum_val:
|
|
1192
|
+
warnings.warn(
|
|
1193
|
+
f'To display a volume of shape {self._vol_shape} without '
|
|
1194
|
+
f'artifacts, you need a step size no smaller than {side_len} /'
|
|
1195
|
+
f'(2 * {MAX_CANVAS_SIZE}) = {minimum_val:,.3g}. To prevent '
|
|
1196
|
+
'extreme degradation in rendering performance, the provided '
|
|
1197
|
+
f'value of {value} is being clipped to {minimum_val:,.3g}. If '
|
|
1198
|
+
'you believe you need a smaller step size, please raise an '
|
|
1199
|
+
'issue at https://github.com/vispy/vispy/issues.'
|
|
1200
|
+
)
|
|
1201
|
+
value = minimum_val
|
|
1171
1202
|
self._relative_step_size = value
|
|
1172
1203
|
self.shared_program['u_relative_step_size'] = value
|
|
1173
1204
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: vispy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Interactive visualization in Python
|
|
5
5
|
Home-page: http://vispy.org
|
|
6
6
|
Download-URL: https://pypi.python.org/pypi/vispy
|
|
@@ -19,13 +19,13 @@ Classifier: Operating System :: MacOS :: MacOS X
|
|
|
19
19
|
Classifier: Operating System :: Microsoft :: Windows
|
|
20
20
|
Classifier: Operating System :: POSIX
|
|
21
21
|
Classifier: Programming Language :: Python
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.9
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.10
|
|
25
24
|
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
26
|
Classifier: Framework :: IPython
|
|
27
27
|
Provides: vispy
|
|
28
|
-
Requires-Python: >=3.
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
29
|
Description-Content-Type: text/x-rst
|
|
30
30
|
License-File: LICENSE.txt
|
|
31
31
|
Requires-Dist: numpy
|
|
@@ -33,38 +33,63 @@ Requires-Dist: freetype-py
|
|
|
33
33
|
Requires-Dist: hsluv
|
|
34
34
|
Requires-Dist: kiwisolver
|
|
35
35
|
Requires-Dist: packaging
|
|
36
|
-
Provides-Extra: doc
|
|
37
|
-
Requires-Dist: pydata-sphinx-theme ; extra == 'doc'
|
|
38
|
-
Requires-Dist: numpydoc ; extra == 'doc'
|
|
39
|
-
Requires-Dist: sphinxcontrib-apidoc ; extra == 'doc'
|
|
40
|
-
Requires-Dist: sphinx-gallery ; extra == 'doc'
|
|
41
|
-
Requires-Dist: myst-parser ; extra == 'doc'
|
|
42
|
-
Requires-Dist: pillow ; extra == 'doc'
|
|
43
|
-
Requires-Dist: pytest ; extra == 'doc'
|
|
44
|
-
Requires-Dist: pyopengl ; extra == 'doc'
|
|
45
|
-
Provides-Extra: io
|
|
46
|
-
Requires-Dist: meshio ; extra == 'io'
|
|
47
|
-
Requires-Dist: Pillow ; extra == 'io'
|
|
48
36
|
Provides-Extra: ipython-static
|
|
49
|
-
Requires-Dist: ipython
|
|
37
|
+
Requires-Dist: ipython; extra == "ipython-static"
|
|
50
38
|
Provides-Extra: pyglet
|
|
51
|
-
Requires-Dist: pyglet
|
|
39
|
+
Requires-Dist: pyglet>=1.2; extra == "pyglet"
|
|
52
40
|
Provides-Extra: pyqt5
|
|
53
|
-
Requires-Dist: pyqt5
|
|
41
|
+
Requires-Dist: pyqt5; extra == "pyqt5"
|
|
54
42
|
Provides-Extra: pyqt6
|
|
55
|
-
Requires-Dist: pyqt6
|
|
43
|
+
Requires-Dist: pyqt6; extra == "pyqt6"
|
|
56
44
|
Provides-Extra: pyside
|
|
57
|
-
Requires-Dist: PySide
|
|
45
|
+
Requires-Dist: PySide; extra == "pyside"
|
|
58
46
|
Provides-Extra: pyside2
|
|
59
|
-
Requires-Dist: PySide2
|
|
47
|
+
Requires-Dist: PySide2; extra == "pyside2"
|
|
60
48
|
Provides-Extra: pyside6
|
|
61
|
-
Requires-Dist: PySide6
|
|
49
|
+
Requires-Dist: PySide6; extra == "pyside6"
|
|
50
|
+
Provides-Extra: glfw
|
|
51
|
+
Requires-Dist: glfw; extra == "glfw"
|
|
62
52
|
Provides-Extra: sdl2
|
|
63
|
-
Requires-Dist: PySDL2
|
|
64
|
-
Provides-Extra: tk
|
|
65
|
-
Requires-Dist: pyopengltk ; extra == 'tk'
|
|
53
|
+
Requires-Dist: PySDL2; extra == "sdl2"
|
|
66
54
|
Provides-Extra: wx
|
|
67
|
-
Requires-Dist: wxPython
|
|
55
|
+
Requires-Dist: wxPython; extra == "wx"
|
|
56
|
+
Provides-Extra: tk
|
|
57
|
+
Requires-Dist: pyopengltk; extra == "tk"
|
|
58
|
+
Provides-Extra: doc
|
|
59
|
+
Requires-Dist: pydata-sphinx-theme; extra == "doc"
|
|
60
|
+
Requires-Dist: numpydoc; extra == "doc"
|
|
61
|
+
Requires-Dist: sphinxcontrib-apidoc; extra == "doc"
|
|
62
|
+
Requires-Dist: sphinx-gallery; extra == "doc"
|
|
63
|
+
Requires-Dist: myst-parser; extra == "doc"
|
|
64
|
+
Requires-Dist: pillow; extra == "doc"
|
|
65
|
+
Requires-Dist: pytest; extra == "doc"
|
|
66
|
+
Requires-Dist: pyopengl; extra == "doc"
|
|
67
|
+
Provides-Extra: io
|
|
68
|
+
Requires-Dist: meshio; extra == "io"
|
|
69
|
+
Requires-Dist: Pillow; extra == "io"
|
|
70
|
+
Provides-Extra: test
|
|
71
|
+
Requires-Dist: pytest; extra == "test"
|
|
72
|
+
Requires-Dist: pytest-sugar; extra == "test"
|
|
73
|
+
Requires-Dist: meshio; extra == "test"
|
|
74
|
+
Requires-Dist: pillow; extra == "test"
|
|
75
|
+
Requires-Dist: sphinx_gallery; extra == "test"
|
|
76
|
+
Requires-Dist: imageio; extra == "test"
|
|
77
|
+
Dynamic: author
|
|
78
|
+
Dynamic: author-email
|
|
79
|
+
Dynamic: classifier
|
|
80
|
+
Dynamic: description
|
|
81
|
+
Dynamic: description-content-type
|
|
82
|
+
Dynamic: download-url
|
|
83
|
+
Dynamic: home-page
|
|
84
|
+
Dynamic: keywords
|
|
85
|
+
Dynamic: license
|
|
86
|
+
Dynamic: license-file
|
|
87
|
+
Dynamic: platform
|
|
88
|
+
Dynamic: provides
|
|
89
|
+
Dynamic: provides-extra
|
|
90
|
+
Dynamic: requires-dist
|
|
91
|
+
Dynamic: requires-python
|
|
92
|
+
Dynamic: summary
|
|
68
93
|
|
|
69
94
|
VisPy: interactive scientific visualization in Python
|
|
70
95
|
-----------------------------------------------------
|
|
@@ -205,7 +230,7 @@ External links
|
|
|
205
230
|
- `Chat room <https://gitter.im/vispy/vispy>`__
|
|
206
231
|
- `Developer chat room <https://gitter.im/vispy/vispy-dev>`__
|
|
207
232
|
- `Wiki <http://github.com/vispy/vispy/wiki>`__
|
|
208
|
-
- `Gallery <http://vispy.org/gallery.html>`__
|
|
233
|
+
- `Gallery <http://vispy.org/gallery/index.html>`__
|
|
209
234
|
- `Documentation <http://vispy.readthedocs.org>`__
|
|
210
235
|
|
|
211
236
|
.. |Build Status| image:: https://github.com/vispy/vispy/workflows/CI/badge.svg
|