vispy 0.12.2__cp39-cp39-macosx_10_9_x86_64.whl → 0.14.0__cp39-cp39-macosx_10_9_x86_64.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.

@@ -250,7 +250,7 @@ class CanvasBackend(BaseCanvasBackend):
250
250
  raise ValueError('fullscreen must be <= %s'
251
251
  % len(monitor))
252
252
  monitor = monitor[p.fullscreen]
253
- use_size = glfw.get_video_mode(monitor)[:2]
253
+ use_size = glfw.get_video_mode(monitor)[0][:2]
254
254
  if use_size != tuple(p.size):
255
255
  logger.debug('Requested size %s, will be ignored to '
256
256
  'use fullscreen mode %s' % (p.size, use_size))
vispy/app/backends/_qt.py CHANGED
@@ -22,6 +22,7 @@ known to cause unpredictable behavior and segfaults.
22
22
  from __future__ import division
23
23
 
24
24
  from time import sleep, time
25
+ import math
25
26
  import os
26
27
  import sys
27
28
  import atexit
@@ -410,17 +411,10 @@ class QtBaseCanvasBackend(BaseCanvasBackend):
410
411
  # either not PyQt5 backend or no parent window available
411
412
  pass
412
413
 
413
- # Activate touch and gesture.
414
- # NOTE: we only activate touch on OS X because there seems to be
415
- # problems on Ubuntu computers with touchscreen.
416
- # See https://github.com/vispy/vispy/pull/1143
417
- if sys.platform == 'darwin':
418
- if PYQT6_API:
419
- self.setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents)
420
- self.grabGesture(QtCore.Qt.GestureType.PinchGesture)
421
- else:
422
- self.setAttribute(QtCore.Qt.WA_AcceptTouchEvents)
423
- self.grabGesture(QtCore.Qt.PinchGesture)
414
+ # QNativeGestureEvent does not keep track of last or total
415
+ # values like QGestureEvent does
416
+ self._native_gesture_scale_values = []
417
+ self._native_gesture_rotation_values = []
424
418
 
425
419
  def screen_changed(self, new_screen):
426
420
  """Window moved from one display to another, resize canvas.
@@ -563,50 +557,81 @@ class QtBaseCanvasBackend(BaseCanvasBackend):
563
557
  def keyReleaseEvent(self, ev):
564
558
  self._keyEvent(self._vispy_canvas.events.key_release, ev)
565
559
 
560
+ def _handle_native_gesture_event(self, ev):
561
+ if self._vispy_canvas is None:
562
+ return
563
+ t = ev.gestureType()
564
+ # this is a workaround for what looks like a Qt bug where
565
+ # QNativeGestureEvent gives the wrong local position.
566
+ # See: https://bugreports.qt.io/browse/QTBUG-59595
567
+ try:
568
+ pos = self.mapFromGlobal(ev.globalPosition().toPoint())
569
+ except AttributeError:
570
+ # globalPos is deprecated in Qt6
571
+ pos = self.mapFromGlobal(ev.globalPos())
572
+ pos = pos.x(), pos.y()
573
+
574
+ if t == QtCore.Qt.NativeGestureType.BeginNativeGesture:
575
+ self._vispy_canvas.events.touch(
576
+ type='gesture_begin',
577
+ pos=_get_event_xy(ev),
578
+ )
579
+ elif t == QtCore.Qt.NativeGestureType.EndNativeGesture:
580
+ self._native_touch_total_rotation = []
581
+ self._native_touch_total_scale = []
582
+ self._vispy_canvas.events.touch(
583
+ type='gesture_end',
584
+ pos=_get_event_xy(ev),
585
+ )
586
+ elif t == QtCore.Qt.NativeGestureType.RotateNativeGesture:
587
+ angle = ev.value()
588
+ last_angle = (
589
+ self._native_gesture_rotation_values[-1]
590
+ if self._native_gesture_rotation_values
591
+ else None
592
+ )
593
+ self._native_gesture_rotation_values.append(angle)
594
+ total_rotation_angle = math.fsum(self._native_gesture_rotation_values)
595
+ self._vispy_canvas.events.touch(
596
+ type="gesture_rotate",
597
+ pos=pos,
598
+ rotation=angle,
599
+ last_rotation=last_angle,
600
+ total_rotation_angle=total_rotation_angle,
601
+ )
602
+ elif t == QtCore.Qt.NativeGestureType.ZoomNativeGesture:
603
+ scale = ev.value()
604
+ last_scale = (
605
+ self._native_gesture_scale_values[-1]
606
+ if self._native_gesture_scale_values
607
+ else None
608
+ )
609
+ self._native_gesture_scale_values.append(scale)
610
+ total_scale_factor = math.fsum(self._native_gesture_scale_values)
611
+ self._vispy_canvas.events.touch(
612
+ type="gesture_zoom",
613
+ pos=pos,
614
+ last_scale=last_scale,
615
+ scale=scale,
616
+ total_scale_factor=total_scale_factor,
617
+ )
618
+ # QtCore.Qt.NativeGestureType.PanNativeGesture
619
+ # Qt6 docs seem to imply this is only supported on Wayland but I have
620
+ # not been able to test it.
621
+ # Two finger pan events are anyway converted to scroll/wheel events.
622
+ # On macOS, more fingers are usually swallowed by the OS (by spaces,
623
+ # mission control, etc.).
624
+
566
625
  def event(self, ev):
567
626
  out = super(QtBaseCanvasBackend, self).event(ev)
568
- t = ev.type()
569
-
570
- qt_event_types = QtCore.QEvent.Type if PYQT6_API else QtCore.QEvent
571
- # Two-finger pinch.
572
- if t == qt_event_types.TouchBegin:
573
- self._vispy_canvas.events.touch(type='begin')
574
- if t == qt_event_types.TouchEnd:
575
- self._vispy_canvas.events.touch(type='end')
576
- if t == qt_event_types.Gesture:
577
- pinch_gesture = QtCore.Qt.GestureType.PinchGesture if PYQT6_API else QtCore.Qt.PinchGesture
578
- gesture = ev.gesture(pinch_gesture)
579
- if gesture:
580
- (x, y) = _get_qpoint_pos(gesture.centerPoint())
581
- scale = gesture.scaleFactor()
582
- last_scale = gesture.lastScaleFactor()
583
- rotation = gesture.rotationAngle()
584
- self._vispy_canvas.events.touch(
585
- type="pinch",
586
- pos=(x, y),
587
- last_pos=None,
588
- scale=scale,
589
- last_scale=last_scale,
590
- rotation=rotation,
591
- total_rotation_angle=gesture.totalRotationAngle(),
592
- total_scale_factor=gesture.totalScaleFactor(),
593
- )
594
- # General touch event.
595
- elif t == qt_event_types.TouchUpdate:
596
- if qt_lib == 'pyqt6' or qt_lib == 'pyside6':
597
- points = ev.points()
598
- # These variables are lists of (x, y) coordinates.
599
- pos = [_get_qpoint_pos(p.position()) for p in points]
600
- lpos = [_get_qpoint_pos(p.lastPosition()) for p in points]
601
- else:
602
- points = ev.touchPoints()
603
- # These variables are lists of (x, y) coordinates.
604
- pos = [_get_qpoint_pos(p.pos()) for p in points]
605
- lpos = [_get_qpoint_pos(p.lastPos()) for p in points]
606
- self._vispy_canvas.events.touch(type='touch',
607
- pos=pos,
608
- last_pos=lpos,
609
- )
627
+
628
+ # QNativeGestureEvent is Qt 5+
629
+ if (
630
+ (QT5_NEW_API or PYSIDE6_API or PYQT6_API)
631
+ and isinstance(ev, QtGui.QNativeGestureEvent)
632
+ ):
633
+ self._handle_native_gesture_event(ev)
634
+
610
635
  return out
611
636
 
612
637
  def _keyEvent(self, func, ev):
vispy/color/colormap.py CHANGED
@@ -1092,17 +1092,13 @@ _colormaps = dict(
1092
1092
  )
1093
1093
 
1094
1094
 
1095
- def get_colormap(name, *args, **kwargs):
1096
- """Obtain a colormap.
1095
+ def get_colormap(name):
1096
+ """Obtain a colormap by name.
1097
1097
 
1098
1098
  Parameters
1099
1099
  ----------
1100
1100
  name : str | Colormap
1101
1101
  Colormap name. Can also be a Colormap for pass-through.
1102
- *args:
1103
- Deprecated.
1104
- **kwargs
1105
- Deprecated.
1106
1102
 
1107
1103
  Examples
1108
1104
  --------
@@ -1111,18 +1107,10 @@ def get_colormap(name, *args, **kwargs):
1111
1107
 
1112
1108
  .. versionchanged: 0.7
1113
1109
 
1114
- Additional args/kwargs are no longer accepted. Colormap classes are
1115
- no longer created on the fly. To create a ``cubehelix``
1116
- (``CubeHelixColormap``), ``single_hue`` (``SingleHue``), ``hsl``
1117
- (``HSL``), ``husl`` (``HSLuv``), ``diverging`` (``Diverging``), or
1118
- ``RdYeBuCy`` (``RedYellowBlueCyan``) colormap you must import and
1119
- instantiate it directly from the ``vispy.color.colormap`` module.
1110
+ Additional args/kwargs are no longer accepted. Colormap instances are
1111
+ no longer created on the fly.
1120
1112
 
1121
1113
  """
1122
- if args or kwargs:
1123
- warnings.warn("Creating a Colormap instance with 'get_colormap' is "
1124
- "no longer supported. No additional arguments or "
1125
- "keyword arguments should be passed.", DeprecationWarning)
1126
1114
  if isinstance(name, BaseColormap):
1127
1115
  return name
1128
1116
 
@@ -1130,14 +1118,6 @@ def get_colormap(name, *args, **kwargs):
1130
1118
  raise TypeError('colormap must be a Colormap or string name')
1131
1119
  if name in _colormaps: # vispy cmap
1132
1120
  cmap = _colormaps[name]
1133
- if name in ("cubehelix", "single_hue", "hsl", "husl", "diverging", "RdYeBuCy"):
1134
- warnings.warn(
1135
- f"Colormap '{name}' has been deprecated since vispy 0.7. "
1136
- f"Please import and create 'vispy.color.colormap.{cmap.__class__.__name__}' "
1137
- "directly instead.",
1138
- DeprecationWarning,
1139
- stacklevel=2,
1140
- )
1141
1121
 
1142
1122
  elif has_matplotlib(): # matplotlib cmap
1143
1123
  try:
vispy/gloo/texture.py CHANGED
@@ -33,17 +33,22 @@ def convert_dtype_and_clip(data, dtype, copy=False):
33
33
  else:
34
34
  # to reduce copying, we clip into a pre-generated array of the right dtype
35
35
  new_data = np.empty_like(data, dtype=dtype)
36
- np.clip(data, new_min, new_max, out=new_data)
36
+ # allow "unsafe" casting here as we're explicitly clipping to the
37
+ # range of the new dtype - this was a default before numpy 1.25
38
+ np.clip(data, new_min, new_max, out=new_data, casting="unsafe")
37
39
  return new_data
38
40
 
39
41
 
40
- def downcast_to_32bit_if_needed(data, copy=False):
42
+ def downcast_to_32bit_if_needed(data, copy=False, dtype=None):
41
43
  """Downcast to 32bit dtype if necessary."""
42
- dtype = np.dtype(data.dtype)
44
+ if dtype is None:
45
+ dtype = data.dtype
46
+ dtype = np.dtype(dtype)
43
47
  if dtype.itemsize > 4:
44
48
  warnings.warn(
45
49
  f"GPUs can't support dtypes bigger than 32-bit, but got '{dtype}'. "
46
- "Precision will be lost due to downcasting to 32-bit."
50
+ "Precision will be lost due to downcasting to 32-bit.",
51
+ stacklevel=2,
47
52
  )
48
53
 
49
54
  size = min(dtype.itemsize, 4)
@@ -133,6 +133,8 @@ class BaseCamera(Node):
133
133
  viewbox.events.mouse_release.connect(self.viewbox_mouse_event)
134
134
  viewbox.events.mouse_move.connect(self.viewbox_mouse_event)
135
135
  viewbox.events.mouse_wheel.connect(self.viewbox_mouse_event)
136
+ viewbox.events.gesture_zoom.connect(self.viewbox_mouse_event)
137
+ viewbox.events.gesture_rotate.connect(self.viewbox_mouse_event)
136
138
  viewbox.events.resize.connect(self.viewbox_resize_event)
137
139
  # todo: also add key events! (and also on viewbox (they're missing)
138
140
 
@@ -144,6 +146,8 @@ class BaseCamera(Node):
144
146
  viewbox.events.mouse_release.disconnect(self.viewbox_mouse_event)
145
147
  viewbox.events.mouse_move.disconnect(self.viewbox_mouse_event)
146
148
  viewbox.events.mouse_wheel.disconnect(self.viewbox_mouse_event)
149
+ viewbox.events.gesture_zoom.disconnect(self.viewbox_mouse_event)
150
+ viewbox.events.gesture_rotate.disconnect(self.viewbox_mouse_event)
147
151
  viewbox.events.resize.disconnect(self.viewbox_resize_event)
148
152
 
149
153
  @property
@@ -207,7 +207,10 @@ class PanZoomCamera(BaseCamera):
207
207
  center = self._scene_transform.imap(event.pos)
208
208
  self.zoom((1 + self.zoom_factor)**(-event.delta[1] * 30), center)
209
209
  event.handled = True
210
-
210
+ elif event.type == 'gesture_zoom':
211
+ center = self._scene_transform.imap(event.pos)
212
+ self.zoom(1 - event.scale, center)
213
+ event.handled = True
211
214
  elif event.type == 'mouse_move':
212
215
  if event.press_event is None:
213
216
  return
@@ -62,6 +62,12 @@ class PerspectiveCamera(BaseCamera):
62
62
  if self._distance is not None:
63
63
  self._distance *= s
64
64
  self.view_changed()
65
+ elif event.type == 'gesture_zoom':
66
+ s = 1 - event.scale
67
+ self._scale_factor *= s
68
+ if self._distance is not None:
69
+ self._distance *= s
70
+ self.view_changed()
65
71
 
66
72
  @property
67
73
  def scale_factor(self):
@@ -82,4 +82,41 @@ def test_panzoom_center():
82
82
  assert v.camera.center == (-12.8, -12.8, 0)
83
83
 
84
84
 
85
+ @requires_application()
86
+ def test_panzoom_gesture_zoom():
87
+ with TestingCanvas(size=(120, 200)) as canvas:
88
+ view = canvas.central_widget.add_view()
89
+ imdata = io.load_crate().astype('float32') / 255
90
+ scene.visuals.Image(imdata, parent=view.scene)
91
+ view.camera = scene.PanZoomCamera(aspect=1)
92
+
93
+ assert view.camera.rect.size == (1, 1)
94
+
95
+ canvas.events.touch(
96
+ type="gesture_zoom",
97
+ pos=(60, 100),
98
+ scale=-1.0,
99
+ )
100
+
101
+ assert view.camera.rect.size == (2, 2)
102
+
103
+
104
+ @requires_application()
105
+ def test_turntable_gesture_zoom():
106
+ with TestingCanvas(size=(120, 200)) as canvas:
107
+ view = canvas.central_widget.add_view()
108
+ imdata = io.load_crate().astype('float32') / 255
109
+ scene.visuals.Image(imdata, parent=view.scene)
110
+ view.camera = scene.TurntableCamera()
111
+
112
+ initial_scale_factor = view.camera.scale_factor
113
+ canvas.events.touch(
114
+ type="gesture_zoom",
115
+ pos=(60, 100),
116
+ scale=-1.0,
117
+ )
118
+
119
+ assert view.camera.scale_factor == 2 * initial_scale_factor
120
+
121
+
85
122
  run_tests_if_main()
vispy/scene/canvas.py CHANGED
@@ -140,6 +140,7 @@ class SceneCanvas(app.Canvas, Frozen):
140
140
  self.events.mouse_move.connect(self._process_mouse_event)
141
141
  self.events.mouse_release.connect(self._process_mouse_event)
142
142
  self.events.mouse_wheel.connect(self._process_mouse_event)
143
+ self.events.touch.connect(self._process_mouse_event)
143
144
 
144
145
  self.scene = SubScene()
145
146
  self.freeze()
@@ -344,7 +345,12 @@ class SceneCanvas(app.Canvas, Frozen):
344
345
 
345
346
  def _process_mouse_event(self, event):
346
347
  prof = Profiler() # noqa
347
- deliver_types = ['mouse_press', 'mouse_wheel']
348
+ deliver_types = [
349
+ 'mouse_press',
350
+ 'mouse_wheel',
351
+ 'gesture_zoom',
352
+ 'gesture_rotate',
353
+ ]
348
354
  if self._send_hover_events:
349
355
  deliver_types += ['mouse_move']
350
356
 
@@ -487,11 +493,8 @@ class SceneCanvas(app.Canvas, Frozen):
487
493
  than triggering transform updates across the scene with every
488
494
  click.
489
495
  """
490
- try:
491
- self._scene.picking = True
496
+ with self._scene.set_picking():
492
497
  img = self.render(bgcolor=(0, 0, 0, 0), crop=crop)
493
- finally:
494
- self._scene.picking = False
495
498
  img = img.astype('int32') * [2**0, 2**8, 2**16, 2**24]
496
499
  id_ = img.sum(axis=2).astype('int32')
497
500
  return id_
@@ -524,6 +527,7 @@ class SceneCanvas(app.Canvas, Frozen):
524
527
  self.events.mouse_move.disconnect(self._process_mouse_event)
525
528
  self.events.mouse_release.disconnect(self._process_mouse_event)
526
529
  self.events.mouse_wheel.disconnect(self._process_mouse_event)
530
+ self.events.touch.disconnect(self._process_mouse_event)
527
531
 
528
532
  # -------------------------------------------------- transform handling ---
529
533
  def push_viewport(self, viewport):
vispy/scene/events.py CHANGED
@@ -71,6 +71,15 @@ class SceneMouseEvent(Event):
71
71
  """The increment by which the mouse wheel has moved."""
72
72
  return self.mouse_event.delta
73
73
 
74
+ @property
75
+ def scale(self):
76
+ """The scale of a gesture_zoom event"""
77
+ try:
78
+ return self.mouse_event.scale
79
+ except AttributeError:
80
+ errmsg = f"SceneMouseEvent type '{self.type}' has no scale"
81
+ raise TypeError(errmsg)
82
+
74
83
  def copy(self):
75
84
  ev = self.__class__(self.mouse_event, self.visual)
76
85
  return ev
vispy/scene/node.py CHANGED
@@ -5,6 +5,7 @@
5
5
  from __future__ import division
6
6
 
7
7
  import weakref
8
+ from contextlib import contextmanager
8
9
 
9
10
  from ..util.event import Event, EmitterGroup
10
11
  from ..visuals.transforms import (NullTransform, BaseTransform,
@@ -63,7 +64,8 @@ class Node(object):
63
64
  # Add some events to the emitter groups:
64
65
  events = ['canvas_change', 'parent_change', 'children_change',
65
66
  'transform_change', 'mouse_press', 'mouse_move',
66
- 'mouse_release', 'mouse_wheel', 'key_press', 'key_release']
67
+ 'mouse_release', 'mouse_wheel', 'key_press', 'key_release',
68
+ 'gesture_zoom', 'gesture_rotate']
67
69
  # Create event emitter if needed (in subclasses that inherit from
68
70
  # Visual, we already have an emitter to share)
69
71
  if not hasattr(self, 'events'):
@@ -625,3 +627,18 @@ class Node(object):
625
627
  for c in self.children:
626
628
  c.picking = p
627
629
  self._picking = p
630
+
631
+ @contextmanager
632
+ def set_picking(self, *, picking=True):
633
+ """Context manager to temporarily set picking for this node and its children.
634
+
635
+ Note that this function will not alter the picking mode unless/until
636
+ the context manager is entered (using the `with` statement). Use
637
+ :py:attr:`~.picking` for setting the picking mode directly.
638
+ """
639
+ old_picking = self.picking
640
+ try:
641
+ self.picking = picking
642
+ yield self.picking
643
+ finally:
644
+ self.picking = old_picking
@@ -1,3 +1,5 @@
1
+ import pytest
2
+
1
3
  from vispy.scene import visuals, Node
2
4
  from vispy.scene.visuals import VisualNode
3
5
  import vispy.visuals
@@ -26,3 +28,114 @@ def test_visual_node_generation():
26
28
  vis_node = getattr(visuals, name[:-6])
27
29
  assert issubclass(vis_node, Node)
28
30
  assert issubclass(vis_node, obj)
31
+
32
+
33
+ def test_push_gl_state():
34
+ node = vispy.visuals.MeshVisual()
35
+ og_gl_state = node._vshare.gl_state.copy()
36
+ node.push_gl_state(blend=False, depth_test=False)
37
+ assert node._vshare.gl_state != og_gl_state
38
+ # preset is always set, unset kwargs should be absent
39
+ assert node._vshare.gl_state == {
40
+ "preset": None,
41
+ "blend": False,
42
+ "depth_test": False,
43
+ }
44
+ node.pop_gl_state()
45
+ assert node._vshare.gl_state == og_gl_state
46
+
47
+
48
+ def test_push_gl_state_update():
49
+ node = vispy.visuals.MeshVisual()
50
+ og_gl_state = node._vshare.gl_state.copy()
51
+ assert "blend" not in og_gl_state
52
+ assert node._vshare.gl_state["depth_test"]
53
+
54
+ node.push_gl_state_update(blend=False, depth_test=False)
55
+ assert node._vshare.gl_state != og_gl_state
56
+ assert not node._vshare.gl_state["blend"]
57
+ assert not node._vshare.gl_state["depth_test"]
58
+
59
+ node.pop_gl_state()
60
+ assert node._vshare.gl_state == og_gl_state
61
+
62
+
63
+ def test_pop_empty_gl_state():
64
+ node = vispy.visuals.MeshVisual()
65
+ assert node._prev_gl_state == []
66
+ og_gl_state = node._vshare.gl_state.copy()
67
+ node.pop_gl_state()
68
+ assert node._vshare.gl_state == og_gl_state
69
+
70
+
71
+ def test_update_gl_state():
72
+ node = vispy.visuals.MeshVisual()
73
+
74
+ og_gl_state = node._vshare.gl_state.copy()
75
+ assert og_gl_state
76
+ og_gl_state["blend"] = False
77
+
78
+ node.update_gl_state(blend=True)
79
+
80
+ # check that the state was updated
81
+ assert node._vshare.gl_state.pop("blend") != og_gl_state.pop("blend")
82
+ # the rest of the state should be unchanged
83
+ assert node._vshare.gl_state == og_gl_state
84
+
85
+
86
+ def test_update_gl_state_context_manager():
87
+ node = vispy.visuals.MeshVisual()
88
+
89
+ node.set_gl_state(blend=False)
90
+ og_gl_state = node._vshare.gl_state.copy()
91
+
92
+ with node.update_gl_state(blend=True):
93
+ # check that the state was updated
94
+ assert node._vshare.gl_state == {**og_gl_state, "blend": True}
95
+
96
+ # the update should be reverted once out of the context
97
+ assert node._vshare.gl_state == og_gl_state
98
+
99
+
100
+ def test_set_gl_state():
101
+ node = vispy.visuals.MeshVisual()
102
+
103
+ node.set_gl_state(blend=False, depth_test=False)
104
+ # preset is always set, unset kwargs should be absent
105
+ assert node._vshare.gl_state == {
106
+ "preset": None,
107
+ "blend": False,
108
+ "depth_test": False,
109
+ }
110
+
111
+ node.set_gl_state(blend=False)
112
+ # preset is always set, unset kwargs should be absent
113
+ assert node._vshare.gl_state == {"preset": None, "blend": False}
114
+
115
+
116
+ def test_set_gl_state_context_manager():
117
+ node = vispy.visuals.MeshVisual()
118
+
119
+ node.set_gl_state(blend=False)
120
+ og_gl_state = node._vshare.gl_state.copy()
121
+
122
+ with node.set_gl_state(blend=True):
123
+ # preset is always set, unset kwargs should be absent
124
+ assert node._vshare.gl_state == {"preset": None, "blend": True}
125
+
126
+ # the update should be reverted once out of the context
127
+ assert node._vshare.gl_state == og_gl_state
128
+
129
+
130
+ @pytest.mark.parametrize("enable_picking", [True, False])
131
+ def test_picking_context(enable_picking):
132
+ mesh = visuals.Mesh()
133
+ mesh.picking = not enable_picking
134
+
135
+ assert mesh.picking != enable_picking
136
+
137
+ with mesh.set_picking(picking=enable_picking) as p:
138
+ assert p == enable_picking
139
+ assert mesh.picking == enable_picking
140
+
141
+ assert mesh.picking != enable_picking
vispy/scene/visuals.py CHANGED
@@ -71,7 +71,10 @@ class VisualNode(Node):
71
71
  return
72
72
  self._picking = p
73
73
  self._picking_filter.enabled = p
74
- self.update_gl_state(blend=not p)
74
+ if p:
75
+ self.push_gl_state_update(blend=False)
76
+ else:
77
+ self.pop_gl_state()
75
78
 
76
79
  def _update_trsys(self, event):
77
80
  """Transform object(s) have changed for this Node; assign these to the
@@ -244,6 +247,7 @@ Histogram = create_visual_node(visuals.HistogramVisual)
244
247
  Image = create_visual_node(visuals.ImageVisual)
245
248
  ComplexImage = create_visual_node(visuals.ComplexImageVisual)
246
249
  InfiniteLine = create_visual_node(visuals.InfiniteLineVisual)
250
+ InstancedMesh = create_visual_node(visuals.InstancedMeshVisual)
247
251
  Isocurve = create_visual_node(visuals.IsocurveVisual)
248
252
  Isoline = create_visual_node(visuals.IsolineVisual)
249
253
  Isosurface = create_visual_node(visuals.IsosurfaceVisual)
vispy/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # file generated by setuptools_scm
2
2
  # don't change, don't track in version control
3
- __version__ = version = '0.12.2'
4
- __version_tuple__ = version_tuple = (0, 12, 2)
3
+ __version__ = version = '0.14.0'
4
+ __version_tuple__ = version_tuple = (0, 14, 0)
vispy/visuals/__init__.py CHANGED
@@ -21,6 +21,7 @@ from .image_complex import ComplexImageVisual # noqa
21
21
  from .gridmesh import GridMeshVisual # noqa
22
22
  from .histogram import HistogramVisual # noqa
23
23
  from .infinite_line import InfiniteLineVisual # noqa
24
+ from .instanced_mesh import InstancedMeshVisual # noqa
24
25
  from .isocurve import IsocurveVisual # noqa
25
26
  from .isoline import IsolineVisual # noqa
26
27
  from .isosurface import IsosurfaceVisual # noqa
@@ -2,8 +2,9 @@
2
2
  # Copyright (c) Vispy Development Team. All Rights Reserved.
3
3
  # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
4
 
5
- from .base_filter import Filter # noqa
5
+ from .base_filter import Filter, PrimitivePickingFilter # noqa
6
6
  from .clipper import Clipper # noqa
7
7
  from .color import Alpha, ColorFilter, IsolineFilter, ZColormapFilter # noqa
8
8
  from .picking import PickingFilter # noqa
9
- from .mesh import TextureFilter, ShadingFilter, WireframeFilter # noqa
9
+ from .markers import MarkerPickingFilter # noqa
10
+ from .mesh import TextureFilter, ShadingFilter, InstancedShadingFilter, WireframeFilter, FacePickingFilter # noqa