77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
"""Background Open3D mesh rendering for the Qt dashboard."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
from PyQt5.QtCore import QMutex, QMutexLocker, QThread, pyqtSignal
|
|
|
|
|
|
class MeshRenderWorker(QThread):
|
|
"""Render finger mesh off the GUI thread; drops stale frames."""
|
|
|
|
rgb_ready = pyqtSignal(object)
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self._mutex = QMutex()
|
|
self._stop = False
|
|
self._wake = False
|
|
self._renderer = None
|
|
self._pending: dict | None = None
|
|
|
|
def set_renderer(self, renderer) -> None:
|
|
with QMutexLocker(self._mutex):
|
|
self._renderer = renderer
|
|
|
|
def clear_renderer(self) -> None:
|
|
with QMutexLocker(self._mutex):
|
|
self._renderer = None
|
|
self._pending = None
|
|
|
|
def submit(self, *, flow, scalar_map, centroid, centroid_found, fnormal, valid_mask=None) -> None:
|
|
with QMutexLocker(self._mutex):
|
|
self._pending = {
|
|
"flow": flow,
|
|
"scalar_map": scalar_map,
|
|
"centroid": centroid,
|
|
"centroid_found": centroid_found,
|
|
"fnormal": fnormal,
|
|
"valid_mask": valid_mask,
|
|
}
|
|
self._wake = True
|
|
if not self.isRunning():
|
|
self.start()
|
|
|
|
def stop_worker(self) -> None:
|
|
with QMutexLocker(self._mutex):
|
|
self._stop = True
|
|
self._wake = True
|
|
self.wait(2000)
|
|
|
|
def run(self) -> None:
|
|
while True:
|
|
with QMutexLocker(self._mutex):
|
|
if self._stop:
|
|
break
|
|
if not self._wake or self._renderer is None or self._pending is None:
|
|
self.msleep(1)
|
|
continue
|
|
job = self._pending
|
|
self._pending = None
|
|
self._wake = False
|
|
renderer = self._renderer
|
|
|
|
rgb = renderer.render(
|
|
flow=job["flow"],
|
|
scalar_map=job["scalar_map"],
|
|
centroid=job["centroid"],
|
|
centroid_found=job["centroid_found"],
|
|
fnormal=job["fnormal"],
|
|
valid_mask=job["valid_mask"],
|
|
)
|
|
self.rgb_ready.emit(np.ascontiguousarray(rgb))
|
|
|
|
with QMutexLocker(self._mutex):
|
|
if self._pending is not None:
|
|
self._wake = True
|