- modified a patch for VisPy Infinite Line Visual that set the line width, in order to make it compliant with newer versions of OpenGL
135 lines
5.0 KiB
Python
135 lines
5.0 KiB
Python
# ##########################################################
|
|
# FlatCAM: 2D Post-processing for Manufacturing #
|
|
# http://flatcam.org #
|
|
# File Author: Dennis Hayrullin #
|
|
# Date: 2/5/2016 #
|
|
# MIT Licence #
|
|
# ##########################################################
|
|
|
|
from vispy.visuals import markers, InfiniteLineVisual
|
|
from vispy.app.backends._pyqt6 import CanvasBackendDesktop
|
|
from vispy.visuals.axis import Ticker, _get_ticks_talbot
|
|
from vispy.scene.widgets import Grid
|
|
import numpy as np
|
|
|
|
|
|
def apply_patches():
|
|
# Patch MarkersVisual to have crossed lines marker
|
|
cross_lines = """
|
|
float cross(vec2 pointcoord, float size)
|
|
{
|
|
//vbar
|
|
float r1 = abs(pointcoord.x - 0.5)*size;
|
|
float r2 = abs(pointcoord.y - 0.5)*size - $v_size/2;
|
|
float vbar = max(r1,r2);
|
|
//hbar
|
|
float r3 = abs(pointcoord.y - 0.5)*size;
|
|
float r4 = abs(pointcoord.x - 0.5)*size - $v_size/2;
|
|
float hbar = max(r3,r4);
|
|
return min(vbar, hbar);
|
|
}
|
|
"""
|
|
|
|
markers._marker_dict['++'] = cross_lines
|
|
markers.marker_types = tuple(sorted(list(markers._marker_dict.copy().keys())))
|
|
|
|
# # Add clear_data method to LineVisual to have possibility of clearing data
|
|
# def clear_data(self):
|
|
# self._bounds = None
|
|
# self._pos = None
|
|
# self._changed['pos'] = True
|
|
# self.update()
|
|
#
|
|
# LineVisual.clear_data = clear_data
|
|
|
|
# Patch VisPy Grid to prevent updating layout on PaintGL, which cause low fps
|
|
def _prepare_draw(self, view):
|
|
pass
|
|
|
|
def _update_clipper(self):
|
|
super(Grid, self)._update_clipper()
|
|
try:
|
|
self._update_child_widget_dim()
|
|
except Exception as e:
|
|
print("VisPyPatches.apply_patches._update_clipper() -> %s" % str(e))
|
|
|
|
Grid._prepare_draw = _prepare_draw
|
|
Grid._update_clipper = _update_clipper
|
|
|
|
# Patch InfiniteLine visual to 1.5px width
|
|
def _prepare_draw(self, view=None):
|
|
"""This method is called immediately before each draw.
|
|
The *view* argument indicates which view is about to be drawn.
|
|
"""
|
|
|
|
self.update_gl_state(line_smooth=False)
|
|
px_scale = self.transforms.pixel_scale
|
|
width = px_scale * 1.5
|
|
self.update_gl_state(line_width=max(width, 1.0))
|
|
|
|
if self._changed['pos']:
|
|
self.pos_buf.set_data(self._pos)
|
|
self._changed['pos'] = False
|
|
|
|
if self._changed['color']:
|
|
self._program.vert['color'] = self._color
|
|
self._changed['color'] = False
|
|
|
|
InfiniteLineVisual._prepare_draw = _prepare_draw
|
|
|
|
# Patch AxisVisual to have less axis labels
|
|
def _get_tick_frac_labels(self):
|
|
"""Get the major ticks, minor ticks, and major labels"""
|
|
minor_num = 4 # number of minor ticks per major division
|
|
if self.axis.scale_type == 'linear':
|
|
domain = self.axis.domain
|
|
if domain[1] < domain[0]:
|
|
flip = True
|
|
domain = domain[::-1]
|
|
else:
|
|
flip = False
|
|
offset = domain[0]
|
|
scale = domain[1] - domain[0]
|
|
|
|
# trying to solve artifacts at maximum zoom
|
|
if scale == 0 or not scale:
|
|
scale = 0.00000001
|
|
|
|
transforms = self.axis.transforms
|
|
length = self.axis.pos[1] - self.axis.pos[0] # in logical coords
|
|
n_inches = np.sqrt(np.sum(length ** 2)) / transforms.dpi
|
|
|
|
# major = np.linspace(domain[0], domain[1], num=11)
|
|
# major = MaxNLocator(10).tick_values(*domain)
|
|
major = _get_ticks_talbot(domain[0], domain[1], n_inches, 1)
|
|
|
|
labels = ['%g' % x for x in major]
|
|
majstep = major[1] - major[0]
|
|
minor = []
|
|
minstep = majstep / (minor_num + 1)
|
|
minstart = 0 if self.axis._stop_at_major[0] else -1
|
|
minstop = -1 if self.axis._stop_at_major[1] else 0
|
|
for i in range(minstart, len(major) + minstop):
|
|
maj = major[0] + i * majstep
|
|
minor.extend(np.linspace(maj + minstep,
|
|
maj + majstep - minstep,
|
|
minor_num))
|
|
|
|
major_frac = (major - offset) / scale
|
|
major_frac = major_frac[::-1] if flip else major_frac
|
|
use_mask = (major_frac > -0.0001) & (major_frac < 1.0001)
|
|
major_frac = major_frac[use_mask]
|
|
labels = [l for li, l in enumerate(labels) if use_mask[li]]
|
|
|
|
minor_frac = (np.array(minor) - offset) / scale
|
|
use_minor_mask = (minor_frac > -0.0001) & (minor_frac < 1.0001)
|
|
minor_frac = minor_frac[use_minor_mask]
|
|
|
|
return major_frac, minor_frac, labels
|
|
elif self.axis.scale_type == 'logarithmic':
|
|
return NotImplementedError
|
|
elif self.axis.scale_type == 'power':
|
|
return NotImplementedError
|
|
|
|
Ticker._get_tick_frac_labels = _get_tick_frac_labels
|