80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
"""Embedded offscreen 3D mesh viewport for the Qt dashboard."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pipeline.frame import FingerFrameView
|
|
from viz.offscreen_mesh import OffscreenFingerMeshRenderer
|
|
|
|
from ..layout import DashboardLayout, LAYOUT
|
|
from .qt_pixmap import ndarray_to_pixmap
|
|
from .image_panel import ImagePanel
|
|
|
|
|
|
class MeshViewportWidget(ImagePanel):
|
|
"""Render the finger mesh offscreen in a square 1:1 viewport."""
|
|
|
|
def __init__(self, parent=None, *, layout: DashboardLayout = LAYOUT):
|
|
self._layout = layout
|
|
self._renderer: OffscreenFingerMeshRenderer | None = None
|
|
self._mesh_map = "depth"
|
|
self._threshold = 0.0
|
|
self._enable_3d = True
|
|
slot = layout.top_slot("mesh")
|
|
super().__init__(
|
|
title=layout.mesh_panel_title,
|
|
object_name="meshViewport",
|
|
default_side=min(slot.width_px, slot.height_px),
|
|
parent=parent,
|
|
)
|
|
|
|
def configure(self, pipeline) -> None:
|
|
self._mesh_map = pipeline.config.mesh_map
|
|
self._threshold = pipeline.config.flow_threshold
|
|
self._enable_3d = pipeline.config.enable_3d and pipeline.uv_mesh is not None
|
|
if self._renderer is not None:
|
|
self._renderer.close()
|
|
self._renderer = None
|
|
if not self._enable_3d:
|
|
self.label.setText(
|
|
"3D mesh disabled" if not pipeline.config.enable_3d else "3D mesh unavailable"
|
|
)
|
|
self.set_source_pixmap(None)
|
|
return
|
|
self.label.setText("")
|
|
self._init_renderer(pipeline)
|
|
|
|
def _init_renderer(self, pipeline) -> None:
|
|
if not self._enable_3d or pipeline.uv_mesh is None:
|
|
return
|
|
side = self.side_length
|
|
self._renderer = OffscreenFingerMeshRenderer(
|
|
pipeline.uv_mesh,
|
|
width=side,
|
|
height=side,
|
|
threshold=self._threshold,
|
|
color_mode=self._mesh_map,
|
|
world_to_cam=pipeline.world_to_cam,
|
|
lookat=pipeline.mesh_lookat,
|
|
)
|
|
|
|
def on_side_length_changed(self, side: int) -> None:
|
|
if self._renderer is not None:
|
|
self._renderer.resize(side, side)
|
|
|
|
def update_frame(self, frame: FingerFrameView) -> None:
|
|
if not self._enable_3d or self._renderer is None:
|
|
return
|
|
rgb = self._renderer.render(
|
|
flow=frame.flow,
|
|
scalar_map=frame.depth_map,
|
|
centroid=frame.centroid,
|
|
centroid_found=frame.centroid_found,
|
|
fnormal=frame.fnormal,
|
|
)
|
|
self.set_source_pixmap(ndarray_to_pixmap(rgb, bgr=False))
|
|
|
|
def close_renderer(self) -> None:
|
|
if self._renderer is not None:
|
|
self._renderer.close()
|
|
self._renderer = None
|