Skip to content

Commit e4962ca

Browse files
authored
Merge pull request #163 from kushalkolar/pygfx-apr2023-refactor
catch up with pygfx refactor of of cameras, controllers, and Texture
2 parents c9c6c78 + 66fd98c commit e4962ca

10 files changed

Lines changed: 148 additions & 541 deletions

File tree

examples/simple.ipynb

Lines changed: 109 additions & 466 deletions
Large diffs are not rendered by default.

fastplotlib/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.0.a9
1+
0.1.0.a10

fastplotlib/graphics/features/_colors.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ def __init__(self, parent, cmap: str):
220220
self.name = cmap
221221

222222
def _set(self, cmap_name: str):
223-
self._parent.world_object.material.map.texture.data[:] = make_colors(256, cmap_name)
224-
self._parent.world_object.material.map.texture.update_range((0, 0, 0), size=(256, 1, 1))
223+
self._parent.world_object.material.map.data[:] = make_colors(256, cmap_name)
224+
self._parent.world_object.material.map.update_range((0, 0, 0), size=(256, 1, 1))
225225
self.name = cmap_name
226226

227227
self._feature_changed(key=None, new_data=self.name)
@@ -246,8 +246,8 @@ class HeatmapCmapFeature(ImageCmapFeature):
246246
"""
247247

248248
def _set(self, cmap_name: str):
249-
self._parent._material.map.texture.data[:] = make_colors(256, cmap_name)
250-
self._parent._material.map.texture.update_range((0, 0, 0), size=(256, 1, 1))
249+
self._parent._material.map.data[:] = make_colors(256, cmap_name)
250+
self._parent._material.map.update_range((0, 0, 0), size=(256, 1, 1))
251251
self.name = cmap_name
252252

253253
self._feature_changed(key=None, new_data=self.name)

fastplotlib/graphics/features/_data.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import *
22

33
import numpy as np
4-
from pygfx import Buffer, Texture, TextureView
4+
from pygfx import Buffer, Texture
55

66
from ._base import GraphicFeatureIndexable, cleanup_slice, FeatureEvent, to_gpu_supported_dtype
77

@@ -87,7 +87,7 @@ def _feature_changed(self, key, new_data):
8787

8888
class ImageDataFeature(GraphicFeatureIndexable):
8989
"""
90-
Access to the TextureView buffer shown in an ImageGraphic.
90+
Access to the Texture buffer shown in an ImageGraphic.
9191
"""
9292

9393
def __init__(self, parent, data: Any):
@@ -102,7 +102,7 @@ def __init__(self, parent, data: Any):
102102
@property
103103
def buffer(self) -> Texture:
104104
"""Texture buffer for the image data"""
105-
return self._parent.world_object.geometry.grid.texture
105+
return self._parent.world_object.geometry.grid
106106

107107
def update_gpu(self):
108108
"""Update the GPU with the buffer"""
@@ -153,7 +153,7 @@ class HeatmapDataFeature(ImageDataFeature):
153153
@property
154154
def buffer(self) -> List[Texture]:
155155
"""list of Texture buffer for the image data"""
156-
return [img.geometry.grid.texture for img in self._parent.world_object.children]
156+
return [img.geometry.grid for img in self._parent.world_object.children]
157157

158158
def update_gpu(self):
159159
"""Update the GPU with the buffer"""

fastplotlib/graphics/image.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import numpy as np
66
import pygfx
7-
from pygfx.utils import unpack_bitfield
87

98
from ._base import Graphic, Interaction, PreviouslyModifiedData
109
from .features import ImageCmapFeature, ImageDataFeature, HeatmapDataFeature, HeatmapCmapFeature
@@ -87,18 +86,18 @@ def __init__(
8786
if (vmin is None) or (vmax is None):
8887
vmin, vmax = quick_min_max(data)
8988

90-
texture_view = pygfx.Texture(buffer_init, dim=2).get_view(filter=filter)
89+
texture = pygfx.Texture(buffer_init, dim=2)
9190

92-
geometry = pygfx.Geometry(grid=texture_view)
91+
geometry = pygfx.Geometry(grid=texture)
9392

9493
# if data is RGB
9594
if data.ndim == 3:
9695
self.cmap = None
97-
material = pygfx.ImageBasicMaterial(clim=(vmin, vmax))
96+
material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map_interpolation=filter)
9897
# if data is just 2D without color information, use colormap LUT
9998
else:
10099
self.cmap = ImageCmapFeature(self, cmap)
101-
material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap())
100+
material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap(), map_interpolation=filter)
102101

103102
world_object = pygfx.Image(
104103
geometry,
@@ -151,21 +150,13 @@ class _ImageTile(pygfx.Image):
151150
"""
152151
Similar to pygfx.Image, only difference is that it contains a few properties to keep track of
153152
row chunk index, column chunk index
154-
155-
156153
"""
157154
def _wgpu_get_pick_info(self, pick_value):
158-
tex = self.geometry.grid
159-
if hasattr(tex, "texture"):
160-
tex = tex.texture # tex was a view
161-
# This should match with the shader
162-
values = unpack_bitfield(pick_value, wobject_id=20, x=22, y=22)
163-
x = values["x"] / 4194304 * tex.size[0] - 0.5
164-
y = values["y"] / 4194304 * tex.size[1] - 0.5
165-
ix, iy = int(x + 0.5), int(y + 0.5)
155+
pick_info = super()._wgpu_get_pick_info(pick_value)
156+
157+
# add row chunk and col chunk index to pick_info dict
166158
return {
167-
"index": (ix, iy),
168-
"pixel_coord": (x - ix, y - iy),
159+
**pick_info,
169160
"row_chunk_index": self.row_chunk_index,
170161
"col_chunk_index": self.col_chunk_index
171162
}
@@ -281,7 +272,7 @@ def __init__(
281272
vmin, vmax = quick_min_max(data)
282273

283274
self.cmap = HeatmapCmapFeature(self, cmap)
284-
self._material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap())
275+
self._material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap(), map_interpolation=filter)
285276

286277
for start, stop, chunk in zip(start_ixs, stop_ixs, chunks):
287278
row_start, col_start = start
@@ -290,8 +281,8 @@ def __init__(
290281
# x and y positions of the Tile in world space coordinates
291282
y_pos, x_pos = row_start, col_start
292283

293-
tex_view = pygfx.Texture(buffer_init[row_start:row_stop, col_start:col_stop], dim=2).get_view(filter=filter)
294-
geometry = pygfx.Geometry(grid=tex_view)
284+
texture = pygfx.Texture(buffer_init[row_start:row_stop, col_start:col_stop], dim=2)
285+
geometry = pygfx.Geometry(grid=texture)
295286
# material = pygfx.ImageBasicMaterial(clim=(0, 1), map=self.cmap())
296287

297288
img = _ImageTile(geometry, self._material)

fastplotlib/layouts/_base.py

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,11 @@ def __init__(
7070
self._camera = camera
7171
self._controller = controller
7272

73-
self.controller.add_default_event_handlers(
73+
self.controller.add_camera(self.camera)
74+
self.controller.register_events(
7475
self.viewport,
75-
self.camera
7676
)
7777

78-
# camera.far and camera.near clipping planes get
79-
# wonky with setting controller.distance = 0
80-
if isinstance(self.camera, OrthographicCamera):
81-
self.controller.distance = 0
82-
# also set a initial zoom
83-
self.controller.zoom(0.8 / self.controller.zoom_value)
84-
8578
self.renderer.add_event_handler(self.set_viewport_rect, "resize")
8679

8780
# list of hex id strings for all graphics managed by this PlotArea
@@ -158,7 +151,6 @@ def set_viewport_rect(self, *args):
158151

159152
def render(self):
160153
# does not flush
161-
self.controller.update_camera(self.camera)
162154
self.viewport.render(self.scene, self.camera)
163155

164156
for child in self.children:
@@ -213,17 +205,7 @@ def _check_graphic_name_exists(self, name):
213205
if name in graphic_names:
214206
raise ValueError(f"graphics must have unique names, current graphic names are:\n {graphic_names}")
215207

216-
def _refresh_camera(self):
217-
self.controller.update_camera(self.camera)
218-
if sum(self.renderer.logical_size) > 0:
219-
scene_lsize = self.viewport.rect[2], self.viewport.rect[3]
220-
else:
221-
scene_lsize = (1, 1)
222-
223-
self.camera.set_view_size(*scene_lsize)
224-
self.camera.update_projection_matrix()
225-
226-
def center_graphic(self, graphic: Graphic, zoom: float = 1.3):
208+
def center_graphic(self, graphic: Graphic, zoom: float = 1.35):
227209
"""
228210
Center the camera w.r.t. the passed graphic
229211
@@ -236,17 +218,14 @@ def center_graphic(self, graphic: Graphic, zoom: float = 1.3):
236218
zoom the camera after centering
237219
238220
"""
239-
if not isinstance(self.camera, OrthographicCamera):
240-
warn("`center_graphic()` not yet implemented for `PerspectiveCamera`")
241-
return
242221

243-
self._refresh_camera()
222+
self.camera.show_object(graphic.world_object)
244223

245-
self.controller.show_object(self.camera, graphic.world_object)
224+
# camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
225+
# probably because camera.show_object uses bounding sphere
226+
self.camera.zoom = zoom
246227

247-
self.controller.zoom(zoom)
248-
249-
def center_scene(self, zoom: float = 1.3):
228+
def center_scene(self, zoom: float = 1.35):
250229
"""
251230
Auto-center the scene, does not scale.
252231
@@ -259,15 +238,11 @@ def center_scene(self, zoom: float = 1.3):
259238
if not len(self.scene.children) > 0:
260239
return
261240

262-
if not isinstance(self.camera, OrthographicCamera):
263-
warn("`center_scene()` not yet implemented for `PerspectiveCamera`")
264-
return
265-
266-
self._refresh_camera()
241+
self.camera.show_object(self.scene)
267242

268-
self.controller.show_object(self.camera, self.scene)
269-
270-
self.controller.zoom(zoom)
243+
# camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
244+
# probably because camera.show_object uses bounding sphere
245+
self.camera.zoom = zoom
271246

272247
def auto_scale(self, maintain_aspect: bool = False, zoom: float = 0.8):
273248
"""
@@ -303,9 +278,7 @@ def auto_scale(self, maintain_aspect: bool = False, zoom: float = 0.8):
303278
self.camera.width = width
304279
self.camera.height = height
305280

306-
# self.controller.distance = 0
307-
308-
self.controller.zoom(zoom / self.controller.zoom_value)
281+
self.camera.zoom = zoom
309282

310283
def remove_graphic(self, graphic: Graphic):
311284
"""

fastplotlib/layouts/_defaults.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
controller_types = {
1010
'2d': pygfx.PanZoomController,
11-
'3d': pygfx.OrbitOrthoController,
11+
'3d': pygfx.OrbitController,
1212
pygfx.OrthographicCamera: pygfx.PanZoomController,
13-
pygfx.PerspectiveCamera: pygfx.OrbitOrthoController,
13+
pygfx.PerspectiveCamera: pygfx.OrbitController,
1414
}
1515

1616

fastplotlib/layouts/_subplot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from inspect import signature, getfullargspec
77
from warnings import warn
88

9-
from pygfx import Scene, OrthographicCamera, PanZoomController, OrbitOrthoController, \
9+
from pygfx import Scene, OrthographicCamera, PanZoomController, OrbitController, \
1010
AxesHelper, GridHelper, WgpuRenderer
1111
from wgpu.gui.auto import WgpuCanvas
1212

@@ -22,7 +22,7 @@ def __init__(
2222
position: Tuple[int, int] = None,
2323
parent_dims: Tuple[int, int] = None,
2424
camera: str = '2d',
25-
controller: Union[PanZoomController, OrbitOrthoController] = None,
25+
controller: Union[PanZoomController, OrbitController] = None,
2626
canvas: WgpuCanvas = None,
2727
renderer: WgpuRenderer = None,
2828
name: str = None,

fastplotlib/plot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def __init__(
1010
canvas: WgpuCanvas = None,
1111
renderer: pygfx.Renderer = None,
1212
camera: str = '2d',
13-
controller: Union[pygfx.PanZoomController, pygfx.OrbitOrthoController] = None,
13+
controller: Union[pygfx.PanZoomController, pygfx.OrbitController] = None,
1414
**kwargs
1515
):
1616
"""

fastplotlib/utils/functions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def make_colors(n_colors: int, cmap: str, alpha: float = 1.0) -> np.ndarray:
6868

6969
def get_cmap_texture(name: str, alpha: float = 1.0) -> Texture:
7070
cmap = _get_cmap(name)
71-
return Texture(cmap, dim=1).get_view()
71+
return Texture(cmap, dim=1)
7272

7373

7474
def make_colors_dict(labels: iter, cmap: str, **kwargs) -> OrderedDict:

0 commit comments

Comments
 (0)