|
|
from time import perf_counter
import pyglet.gl as pgl
from sympy.plotting.pygletplot.managed_window import ManagedWindow from sympy.plotting.pygletplot.plot_camera import PlotCamera from sympy.plotting.pygletplot.plot_controller import PlotController
class PlotWindow(ManagedWindow):
def __init__(self, plot, antialiasing=True, ortho=False, invert_mouse_zoom=False, linewidth=1.5, caption="SymPy Plot", **kwargs): """
Named Arguments ===============
antialiasing = True True OR False ortho = False True OR False invert_mouse_zoom = False True OR False """
self.plot = plot
self.camera = None self._calculating = False
self.antialiasing = antialiasing self.ortho = ortho self.invert_mouse_zoom = invert_mouse_zoom self.linewidth = linewidth self.title = caption self.last_caption_update = 0 self.caption_update_interval = 0.2 self.drawing_first_object = True
super().__init__(**kwargs)
def setup(self): self.camera = PlotCamera(self, ortho=self.ortho) self.controller = PlotController(self, invert_mouse_zoom=self.invert_mouse_zoom) self.push_handlers(self.controller)
pgl.glClearColor(1.0, 1.0, 1.0, 0.0) pgl.glClearDepth(1.0)
pgl.glDepthFunc(pgl.GL_LESS) pgl.glEnable(pgl.GL_DEPTH_TEST)
pgl.glEnable(pgl.GL_LINE_SMOOTH) pgl.glShadeModel(pgl.GL_SMOOTH) pgl.glLineWidth(self.linewidth)
pgl.glEnable(pgl.GL_BLEND) pgl.glBlendFunc(pgl.GL_SRC_ALPHA, pgl.GL_ONE_MINUS_SRC_ALPHA)
if self.antialiasing: pgl.glHint(pgl.GL_LINE_SMOOTH_HINT, pgl.GL_NICEST) pgl.glHint(pgl.GL_POLYGON_SMOOTH_HINT, pgl.GL_NICEST)
self.camera.setup_projection()
def on_resize(self, w, h): super().on_resize(w, h) if self.camera is not None: self.camera.setup_projection()
def update(self, dt): self.controller.update(dt)
def draw(self): self.plot._render_lock.acquire() self.camera.apply_transformation()
calc_verts_pos, calc_verts_len = 0, 0 calc_cverts_pos, calc_cverts_len = 0, 0
should_update_caption = (perf_counter() - self.last_caption_update > self.caption_update_interval)
if len(self.plot._functions.values()) == 0: self.drawing_first_object = True
iterfunctions = iter(self.plot._functions.values())
for r in iterfunctions: if self.drawing_first_object: self.camera.set_rot_preset(r.default_rot_preset) self.drawing_first_object = False
pgl.glPushMatrix() r._draw() pgl.glPopMatrix()
# might as well do this while we are # iterating and have the lock rather # than locking and iterating twice # per frame:
if should_update_caption: try: if r.calculating_verts: calc_verts_pos += r.calculating_verts_pos calc_verts_len += r.calculating_verts_len if r.calculating_cverts: calc_cverts_pos += r.calculating_cverts_pos calc_cverts_len += r.calculating_cverts_len except ValueError: pass
for r in self.plot._pobjects: pgl.glPushMatrix() r._draw() pgl.glPopMatrix()
if should_update_caption: self.update_caption(calc_verts_pos, calc_verts_len, calc_cverts_pos, calc_cverts_len) self.last_caption_update = perf_counter()
if self.plot._screenshot: self.plot._screenshot._execute_saving()
self.plot._render_lock.release()
def update_caption(self, calc_verts_pos, calc_verts_len, calc_cverts_pos, calc_cverts_len): caption = self.title if calc_verts_len or calc_cverts_len: caption += " (calculating" if calc_verts_len > 0: p = (calc_verts_pos / calc_verts_len) * 100 caption += " vertices %i%%" % (p) if calc_cverts_len > 0: p = (calc_cverts_pos / calc_cverts_len) * 100 caption += " colors %i%%" % (p) caption += ")" if self.caption != caption: self.set_caption(caption)
|