Spaces:
Sleeping
Sleeping
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) | |