Source code for fibomat.beam_simulation.fibcanvas
from typing import Callable
import numpy as np
from vispy import app
from vispy.visuals.transforms import STTransform
from fibomat.beam_simulation.markers import Tail, DwellPoints
from fibomat.beam_simulation.scalebar import ScaleBar
[docs]class FIBCanvas(app.Canvas):
[docs] def __init__(self, dwell_points: np.ndarray, length_unit: str, on_timer_callback: Callable):
app.Canvas.__init__(self, keys='interactive', size=(800, 600))
dwell_points = np.asarray(dwell_points, dtype=np.float32)
min_x, min_y = np.min(dwell_points, axis=0)
max_x, max_y = np.max(dwell_points, axis=0)
if self.physical_size[0] / (max_x - min_x) < self.physical_size[1] / (max_y - min_y):
self._pre_scale = self.physical_size[0] / (max_x - min_x)
else:
self._pre_scale = self.physical_size[1] / (max_y - min_y)
dwell_points *= self._pre_scale
self._min_x, self._min_y = np.min(dwell_points, axis=0)
self._max_x, self._max_y = np.max(dwell_points, axis=0)
self._n_points = len(dwell_points)
self._tail = Tail(dwell_points, 100, 10)
self._dwell_points = DwellPoints(dwell_points)
self._scale_bar = ScaleBar(length_unit, self)
w, h = self.size
self._dwell_points.transform = STTransform(translate=(w / 2., h / 2.))
self._tail.transform = STTransform(translate=(w / 2., h / 2.))
self._timer = app.Timer('auto', connect=self.on_timer, start=True)
self._current_point = 0
self._last_update = 0
self._speed = 10
self._run_animation = False
self._on_timer_callback = on_timer_callback
[docs] def on_resize(self, event):
vp = (0, 0, self.physical_size[0], self.physical_size[1])
self.context.set_viewport(*vp)
self._dwell_points.transforms.configure(canvas=self, viewport=vp)
self._dwell_points.transform.translate = self.physical_size[0] / 2, self.physical_size[1] / 2
self._tail.transforms.configure(canvas=self, viewport=vp)
self._tail.transform.translate = self.physical_size[0] / 2, self.physical_size[1] / 2
width = self._max_x - self._min_x
height = self._max_y - self._min_y
margin = 0 # 10
if self.physical_size[0] / (self._max_x - self._min_x) < self.physical_size[1] / (self._max_y - self._min_y):
s = self.physical_size[0] / (width+margin)
pixel_per_length = (self._max_x - self._min_x) / (self.physical_size[0] - 2*margin)
else:
s = self.physical_size[1] / (height+margin)
pixel_per_length = (self._max_y - self._min_y) / (self.physical_size[1] - 2*margin)
self._dwell_points.transform.scale = s, s
self._tail.transform.scale = s, s
self._scale_bar.transform(pixel_per_length / self._pre_scale, s)
[docs] def on_draw(self, event):
self.context.clear('white')
self._dwell_points.draw()
self._tail.draw(self._current_point)
self._scale_bar.draw()
[docs] def on_timer(self, event):
if self._run_animation:
freq = 1 / self._speed
elapsed = self._timer.elapsed
delta = elapsed - self._last_update
if delta > freq:
n_new_points = int(delta / freq)
self._current_point += n_new_points
self._last_update = elapsed
self._on_timer_callback(self._current_point)
self.update()
[docs] def start_animation(self):
# self.timer.start()
self._run_animation = True
self._last_update = self._timer.elapsed
[docs] def stop_animation(self):
# self.timer.stop()
self._run_animation = False
[docs] def reset_animation(self):
self._last_update = 0
self._current_point = 0
self._run_animation = False
[docs] def set_speed(self, speed):
self._speed = speed
[docs] def set_tail_length(self, length):
self._tail._tail_length = length
[docs] def set_alpha(self, alpha):
self._tail._alpha = alpha
@property
def number_of_points(self) -> int:
return self._n_points
@property
def current_point_index(self) -> int:
return self._current_point
@current_point_index.setter
def current_point_index(self, value):
self._current_point = value