Skip to content

Commit

Permalink
improve pygfx
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Jan 21, 2025
1 parent a900665 commit d8aa123
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 166 deletions.
2 changes: 1 addition & 1 deletion src/ndv/models/_scene/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def size(self) -> tuple[int, int]:
return self.width, self.height

Check warning on line 76 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L76

Added line #L76 was not covered by tests

@size.setter
def size(self, value: tuple[float, float]) -> None:
def size(self, value: tuple[int, int]) -> None:

Check warning on line 79 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L78-L79

Added lines #L78 - L79 were not covered by tests
"""Set the size of the canvas."""
self.width, self.height = value

Check warning on line 81 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L81

Added line #L81 was not covered by tests

Expand Down
11 changes: 5 additions & 6 deletions src/ndv/models/_scene/nodes/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ class Camera(Node["CameraAdaptorProtocol"]):
)

def _set_range(self, margin: float = 0) -> None:
if self.has_backend_adaptor("vispy"):
adaptor = self.backend_adaptor()
# TODO: this method should probably be pulled off of the backend,
# calculated directly in the core, and then applied as a change to the
# camera transform
adaptor._vis_set_range(margin=margin)
adaptor = self.backend_adaptor()

Check warning on line 43 in src/ndv/models/_scene/nodes/camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/camera.py#L42-L43

Added lines #L42 - L43 were not covered by tests
# TODO: this method should probably be pulled off of the backend,
# calculated directly in the core, and then applied as a change to the
# camera transform
adaptor._vis_set_range(margin=margin)

Check warning on line 47 in src/ndv/models/_scene/nodes/camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/camera.py#L47

Added line #L47 was not covered by tests
4 changes: 3 additions & 1 deletion src/ndv/models/_scene/nodes/points.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def _vis_set_opacity(self, opacity: float) -> None: ...
"star",
"cross_lines",
]
ScalingMode = Literal[True, False, "fixed", "scene", "visual"]

Check warning on line 55 in src/ndv/models/_scene/nodes/points.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/points.py#L55

Added line #L55 was not covered by tests


class Points(Node[PointsBackend]):

Check warning on line 58 in src/ndv/models/_scene/nodes/points.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/points.py#L58

Added line #L58 was not covered by tests
Expand All @@ -72,7 +73,8 @@ class Points(Node[PointsBackend]):
symbol: SymbolName = Field(

Check warning on line 73 in src/ndv/models/_scene/nodes/points.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/points.py#L72-L73

Added lines #L72 - L73 were not covered by tests
default="disc", description="The symbol to use for the points."
)
scaling: Literal[True, False, "fixed", "scene", "visual"] = Field(
# TODO: these are vispy-specific names. Determine more general names
scaling: ScalingMode = Field(

Check warning on line 77 in src/ndv/models/_scene/nodes/points.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/points.py#L77

Added line #L77 was not covered by tests
default=True, description="Determines how points scale when zooming."
)

Expand Down
4 changes: 2 additions & 2 deletions src/ndv/models/_scene/nodes/scene.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Literal

Check warning on line 1 in src/ndv/models/_scene/nodes/scene.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/scene.py#L1

Added line #L1 was not covered by tests

from .node import Node
from .node import Node, NodeAdaptorProtocol

Check warning on line 3 in src/ndv/models/_scene/nodes/scene.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/scene.py#L3

Added line #L3 was not covered by tests


class Scene(Node):
class Scene(Node[NodeAdaptorProtocol]):

Check warning on line 6 in src/ndv/models/_scene/nodes/scene.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/scene.py#L6

Added line #L6 was not covered by tests
"""A Root node for a scene graph.
This really isn't anything more than a regular Node, but it's an explicit
Expand Down
35 changes: 25 additions & 10 deletions src/ndv/models/_scene/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import TYPE_CHECKING, Any, Protocol, TypeVar

Check warning on line 5 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L3-L5

Added lines #L3 - L5 were not covered by tests

from cmap import Color
from pydantic import ConfigDict, Field
from pydantic import ConfigDict, Field, PrivateAttr, computed_field

Check warning on line 8 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L7-L8

Added lines #L7 - L8 were not covered by tests

from ._vis_model import ModelBase, SupportsVisibility, VisModel
from .nodes import Camera, Scene
Expand Down Expand Up @@ -121,10 +121,31 @@ class View(VisModel[ViewAdaptorProtocol]):

model_config = ConfigDict(repr_exclude_defaults=False) # type: ignore

Check warning on line 122 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L122

Added line #L122 was not covered by tests

_canvas: Canvas | None = PrivateAttr(None)

Check warning on line 124 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L124

Added line #L124 was not covered by tests

def model_post_init(self, __context: Any) -> None:
super().model_post_init(__context)
self.camera.parent = self.scene
self.layout.events.connect(self._on_layout_event)

Check warning on line 129 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L126-L129

Added lines #L126 - L129 were not covered by tests

@computed_field # type: ignore
@property
def canvas(self) -> Canvas:

Check warning on line 133 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L131-L133

Added lines #L131 - L133 were not covered by tests
"""The canvas that the view is on.
If one hasn't been created/assigned, a new one is created.
"""
if (canvas := self._canvas) is None:
from .canvas import Canvas

Check warning on line 139 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L138-L139

Added lines #L138 - L139 were not covered by tests

self.canvas = canvas = Canvas()
return canvas

Check warning on line 142 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L141-L142

Added lines #L141 - L142 were not covered by tests

@canvas.setter
def canvas(self, value: Canvas) -> None:
self._canvas = value
self._canvas.add_view(self)

Check warning on line 147 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L144-L147

Added lines #L144 - L147 were not covered by tests

def _on_layout_event(self, info: EmissionInfo) -> None:
_signal_name = info.signal.name

Check warning on line 150 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L149-L150

Added lines #L149 - L150 were not covered by tests
...
Expand All @@ -135,15 +156,9 @@ def show(self) -> Canvas:
Convenience method for showing the canvas that the view is on.
If no canvas exists, a new one is created.
"""
if not hasattr(self, "_canvas"):
from .canvas import Canvas

# TODO: we need to know/check somehow if the view is already on a canvas
# This just creates a new canvas every time
self._canvas = Canvas()
self._canvas.add_view(self)
self._canvas.show()
return self._canvas
canvas = self.canvas
canvas.show()
return self.canvas

Check warning on line 161 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L159-L161

Added lines #L159 - L161 were not covered by tests

def add_node(self, node: NodeType) -> NodeType:

Check warning on line 163 in src/ndv/models/_scene/view.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/view.py#L163

Added line #L163 was not covered by tests
"""Add any node to the scene."""
Expand Down
3 changes: 2 additions & 1 deletion src/ndv/views/_scene/pygfx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from ._canvas import Canvas
from ._image import Image
from ._node import Node
from ._points import Points
from ._scene import Scene
from ._view import View

Check warning on line 7 in src/ndv/views/_scene/pygfx/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/__init__.py#L1-L7

Added lines #L1 - L7 were not covered by tests

__all__ = ["Camera", "Canvas", "Image", "Node", "Scene", "View"]
__all__ = ["Camera", "Canvas", "Image", "Node", "Points", "Scene", "View"]

Check warning on line 9 in src/ndv/views/_scene/pygfx/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/__init__.py#L9

Added line #L9 was not covered by tests
44 changes: 30 additions & 14 deletions src/ndv/views/_scene/pygfx/_camera.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import annotations

Check warning on line 1 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L1

Added line #L1 was not covered by tests

import warnings
from typing import Any
from typing import Any, cast

Check warning on line 3 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L3

Added line #L3 was not covered by tests

import numpy as np
import pygfx

Check warning on line 6 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L5-L6

Added lines #L5 - L6 were not covered by tests

from ndv._types import CameraType
Expand All @@ -14,18 +14,19 @@
class Camera(Node, camera.CameraAdaptorProtocol):

Check warning on line 14 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L14

Added line #L14 was not covered by tests
"""Adaptor for pygfx camera."""

_pygfx_node: pygfx.Camera
_pygfx_node: pygfx.PerspectiveCamera
pygfx_controller: pygfx.Controller

Check warning on line 18 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L17-L18

Added lines #L17 - L18 were not covered by tests

def __init__(self, camera: camera.Camera, **backend_kwargs: Any) -> None:
self._camera_model = camera
if camera.type == CameraType.PANZOOM:
self._pygfx_node = pygfx.OrthographicCamera(**backend_kwargs)
self.controller = pygfx.PanZoomController(self._pygfx_node)
self._pygfx_node = pygfx.OrthographicCamera()
self.pygfx_controller = pygfx.PanZoomController(self._pygfx_node)
elif camera.type == CameraType.ARCBALL:
self._pygfx_node = pygfx.PerspectiveCamera(**backend_kwargs)
self.controller = pygfx.OrbitOrthoController(self._pygfx_node)
self._pygfx_node = pygfx.PerspectiveCamera(70, 4 / 3)
self.pygfx_controller = pygfx.OrbitController(self._pygfx_node)

Check warning on line 27 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L20-L27

Added lines #L20 - L27 were not covered by tests

# FIXME: hardcoded
# self._pygfx_cam.scale.y = -1
self._pygfx_node.local.scale_y = -1 # don't think this is working...

def _vis_set_zoom(self, zoom: float) -> None:

Check warning on line 31 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L31

Added line #L31 was not covered by tests
raise NotImplementedError
Expand All @@ -44,14 +45,29 @@ def update_controller(self) -> None:
# This is called by the View Adaptor in the `_visit` method
# ... which is in turn called by the Canvas backend adaptor's `_animate` method
# i.e. the main render loop.
self.controller.update_camera(self._pygfx_node)
self.pygfx_controller.update_camera(self._pygfx_node)

Check warning on line 48 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L48

Added line #L48 was not covered by tests

def set_viewport(self, viewport: pygfx.Viewport) -> None:

Check warning on line 50 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L50

Added line #L50 was not covered by tests
# This is used by the Canvas backend adaptor...
# and should perhaps be moved to the View Adaptor
self.controller.add_default_event_handlers(viewport, self._pygfx_node)
self.pygfx_controller.add_default_event_handlers(viewport, self._pygfx_node)

Check warning on line 53 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L53

Added line #L53 was not covered by tests

def _vis_set_range(self, margin: float) -> None:

Check warning on line 55 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L55

Added line #L55 was not covered by tests
warnings.warn(
"set_range not implemented for pygfx", RuntimeWarning, stacklevel=2
)
# reset camera to fit all objects
if not (scene := self._camera_model.parent):
print("No scene found for camera")
return

Check warning on line 59 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L57-L59

Added lines #L57 - L59 were not covered by tests

py_scene = cast("pygfx.Scene", scene.backend_adaptor("pygfx")._vis_get_native())
cam = self._pygfx_node
cam.show_object(py_scene)

Check warning on line 63 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L61-L63

Added lines #L61 - L63 were not covered by tests

if (bb := py_scene.get_world_bounding_box()) is not None:
width, height, _depth = np.ptp(bb, axis=0)
if width < 0.01:
width = 1
if height < 0.01:
height = 1
cam.width = width
cam.height = height
cam.zoom = 1 - margin

Check warning on line 73 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L65-L73

Added lines #L65 - L73 were not covered by tests
83 changes: 25 additions & 58 deletions src/ndv/views/_scene/pygfx/_canvas.py
Original file line number Diff line number Diff line change
@@ -1,84 +1,51 @@
from __future__ import annotations

Check warning on line 1 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L1

Added line #L1 was not covered by tests

from contextlib import suppress
from typing import TYPE_CHECKING, Any, Union, cast

import pygfx
from typing import TYPE_CHECKING, Any, cast

Check warning on line 3 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L3

Added line #L3 was not covered by tests

from ndv.models import _scene as core

Check warning on line 5 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L5

Added line #L5 was not covered by tests

if TYPE_CHECKING:
import numpy as np
from cmap import Color
from typing_extensions import TypeAlias
from wgpu.gui import glfw, jupyter, offscreen, qt
from rendercanvas.auto import RenderCanvas

from ._view import View

# from wgpu.gui.auto import WgpuCanvas
# ... will result in one of the following canvas classes
TypeWgpuCanvasType: TypeAlias = Union[
type[offscreen.WgpuCanvas], # if WGPU_FORCE_OFFSCREEN=1
type[jupyter.WgpuCanvas], # if is_jupyter()
type[glfw.WgpuCanvas], # if glfw is installed
type[qt.WgpuCanvas], # if any pyqt backend is installed
]
# TODO: lol... there's probably a better way to do this :)
WgpuCanvasType: TypeAlias = Union[
offscreen.WgpuCanvas, # if WGPU_FORCE_OFFSCREEN=1
jupyter.WgpuCanvas, # if is_jupyter()
glfw.WgpuCanvas, # if glfw is installed
qt.WgpuCanvas, # if any pyqt backend is installed
]


class Canvas(core.canvas.CanvasAdaptorProtocol):

Check warning on line 15 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L15

Added line #L15 was not covered by tests
"""Canvas interface for pygfx Backend."""

def __init__(self, canvas: core.Canvas, **backend_kwargs: Any) -> None:
# wgpu.gui.auto.WgpuCanvas is a "magic" import that itself is context sensitive
# see TYPE_CHECKING section above for details
from wgpu.gui.auto import WgpuCanvas

WgpuCanvas = cast("TypeWgpuCanvasType", WgpuCanvas)
from rendercanvas.auto import RenderCanvas

Check warning on line 19 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L18-L19

Added lines #L18 - L19 were not covered by tests

canvas = WgpuCanvas(size=canvas.size, title=canvas.title, **backend_kwargs)
self._wgpu_canvas = cast("WgpuCanvasType", canvas)
# TODO: background_color
# the qt backend, this shows by default...
# if we need to prevent it, we could potentially monkeypatch during init.
self._wgpu_canvas = RenderCanvas()

Check warning on line 21 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L21

Added line #L21 was not covered by tests
# Qt RenderCanvas calls show() in its __init__ method, so we need to hide it
if hasattr(self._wgpu_canvas, "hide"):
self._wgpu_canvas.hide()

Check warning on line 24 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L23-L24

Added lines #L23 - L24 were not covered by tests

self._renderer = pygfx.renderers.WgpuRenderer(self._wgpu_canvas)
self._viewport: pygfx.Viewport = pygfx.Viewport(self._renderer)
self._views: list[View] = []
# self._grid: dict[tuple[int, int], View] = {}
self._wgpu_canvas.set_logical_size(canvas.width, canvas.height)
self._wgpu_canvas.set_title(canvas.title)
self._views = canvas.views

Check warning on line 28 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L26-L28

Added lines #L26 - L28 were not covered by tests

def _vis_get_native(self) -> WgpuCanvasType:
def _vis_get_native(self) -> RenderCanvas:
return self._wgpu_canvas

Check warning on line 31 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L30-L31

Added lines #L30 - L31 were not covered by tests

def _vis_set_visible(self, arg: bool) -> None:

Check warning on line 33 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L33

Added line #L33 was not covered by tests
# show the qt canvas we patched earlier in __init__
if hasattr(self._wgpu_canvas, "show"):
self._wgpu_canvas.show()
self._wgpu_canvas.request_draw(self._animate)
self._wgpu_canvas.request_draw(self._draw)

Check warning on line 37 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L35-L37

Added lines #L35 - L37 were not covered by tests

def _animate(self, viewport: pygfx.Viewport | None = None) -> None:
vp = viewport or self._viewport
def _draw(self) -> None:
for view in self._views:
view._visit(vp)
if hasattr(vp.renderer, "flush"):
# an attribute error can occur if flush() is called before render()
# https://github.com/pygfx/pygfx/issues/946
with suppress(AttributeError):
vp.renderer.flush()
if viewport is None:
self._wgpu_canvas.request_draw()
adaptor = cast("View", view.backend_adaptor("pygfx"))
adaptor._draw()

Check warning on line 42 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L39-L42

Added lines #L39 - L42 were not covered by tests

def _vis_add_view(self, view: core.View) -> None:

Check warning on line 44 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L44

Added line #L44 was not covered by tests
adaptor = cast("View", view.backend_adaptor())
pass
# adaptor = cast("View", view.backend_adaptor())
# adaptor._pygfx_cam.set_viewport(self._viewport)
self._views.append(adaptor)
# self._views.append(adaptor)

def _vis_set_width(self, arg: int) -> None:
_, height = self._wgpu_canvas.get_logical_size()
Expand All @@ -88,11 +55,12 @@ def _vis_set_height(self, arg: int) -> None:
width, _ = self._wgpu_canvas.get_logical_size()
self._wgpu_canvas.set_logical_size(width, arg)

Check warning on line 56 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L54-L56

Added lines #L54 - L56 were not covered by tests

def _vis_set_background_color(self, arg: Color | None) -> None:
raise NotImplementedError()
def _vis_set_background_color(self, arg: Color) -> None:

Check warning on line 58 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L58

Added line #L58 was not covered by tests
# not sure if pygfx has both a canavs and view background color...
pass

def _vis_set_title(self, arg: str) -> None:
raise NotImplementedError()
self._wgpu_canvas.set_title(arg)

Check warning on line 63 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L62-L63

Added lines #L62 - L63 were not covered by tests

def _vis_close(self) -> None:

Check warning on line 65 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L65

Added line #L65 was not covered by tests
"""Close canvas."""
Expand All @@ -107,11 +75,10 @@ def _vis_render(
alpha: bool = True,
) -> np.ndarray:
"""Render to screenshot."""
from wgpu.gui.offscreen import WgpuCanvas
from rendercanvas.offscreen import OffscreenRenderCanvas

Check warning on line 78 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L78

Added line #L78 was not covered by tests

# not sure about this...
w, h = self._wgpu_canvas.get_logical_size()
canvas = WgpuCanvas(width=w, height=h, pixel_ratio=1)
renderer = pygfx.renderers.WgpuRenderer(canvas)
viewport = pygfx.Viewport(renderer)
canvas.request_draw(lambda: self._animate(viewport))
canvas = OffscreenRenderCanvas(width=w, height=h, pixel_ratio=1)
canvas.request_draw(self._draw)
return cast("np.ndarray", canvas.draw())

Check warning on line 84 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L81-L84

Added lines #L81 - L84 were not covered by tests
Loading

0 comments on commit d8aa123

Please sign in to comment.