plot_window.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. from time import perf_counter
  2. import pyglet.gl as pgl
  3. from sympy.plotting.pygletplot.managed_window import ManagedWindow
  4. from sympy.plotting.pygletplot.plot_camera import PlotCamera
  5. from sympy.plotting.pygletplot.plot_controller import PlotController
  6. class PlotWindow(ManagedWindow):
  7. def __init__(self, plot, antialiasing=True, ortho=False,
  8. invert_mouse_zoom=False, linewidth=1.5, caption="SymPy Plot",
  9. **kwargs):
  10. """
  11. Named Arguments
  12. ===============
  13. antialiasing = True
  14. True OR False
  15. ortho = False
  16. True OR False
  17. invert_mouse_zoom = False
  18. True OR False
  19. """
  20. self.plot = plot
  21. self.camera = None
  22. self._calculating = False
  23. self.antialiasing = antialiasing
  24. self.ortho = ortho
  25. self.invert_mouse_zoom = invert_mouse_zoom
  26. self.linewidth = linewidth
  27. self.title = caption
  28. self.last_caption_update = 0
  29. self.caption_update_interval = 0.2
  30. self.drawing_first_object = True
  31. super().__init__(**kwargs)
  32. def setup(self):
  33. self.camera = PlotCamera(self, ortho=self.ortho)
  34. self.controller = PlotController(self,
  35. invert_mouse_zoom=self.invert_mouse_zoom)
  36. self.push_handlers(self.controller)
  37. pgl.glClearColor(1.0, 1.0, 1.0, 0.0)
  38. pgl.glClearDepth(1.0)
  39. pgl.glDepthFunc(pgl.GL_LESS)
  40. pgl.glEnable(pgl.GL_DEPTH_TEST)
  41. pgl.glEnable(pgl.GL_LINE_SMOOTH)
  42. pgl.glShadeModel(pgl.GL_SMOOTH)
  43. pgl.glLineWidth(self.linewidth)
  44. pgl.glEnable(pgl.GL_BLEND)
  45. pgl.glBlendFunc(pgl.GL_SRC_ALPHA, pgl.GL_ONE_MINUS_SRC_ALPHA)
  46. if self.antialiasing:
  47. pgl.glHint(pgl.GL_LINE_SMOOTH_HINT, pgl.GL_NICEST)
  48. pgl.glHint(pgl.GL_POLYGON_SMOOTH_HINT, pgl.GL_NICEST)
  49. self.camera.setup_projection()
  50. def on_resize(self, w, h):
  51. super().on_resize(w, h)
  52. if self.camera is not None:
  53. self.camera.setup_projection()
  54. def update(self, dt):
  55. self.controller.update(dt)
  56. def draw(self):
  57. self.plot._render_lock.acquire()
  58. self.camera.apply_transformation()
  59. calc_verts_pos, calc_verts_len = 0, 0
  60. calc_cverts_pos, calc_cverts_len = 0, 0
  61. should_update_caption = (perf_counter() - self.last_caption_update >
  62. self.caption_update_interval)
  63. if len(self.plot._functions.values()) == 0:
  64. self.drawing_first_object = True
  65. iterfunctions = iter(self.plot._functions.values())
  66. for r in iterfunctions:
  67. if self.drawing_first_object:
  68. self.camera.set_rot_preset(r.default_rot_preset)
  69. self.drawing_first_object = False
  70. pgl.glPushMatrix()
  71. r._draw()
  72. pgl.glPopMatrix()
  73. # might as well do this while we are
  74. # iterating and have the lock rather
  75. # than locking and iterating twice
  76. # per frame:
  77. if should_update_caption:
  78. try:
  79. if r.calculating_verts:
  80. calc_verts_pos += r.calculating_verts_pos
  81. calc_verts_len += r.calculating_verts_len
  82. if r.calculating_cverts:
  83. calc_cverts_pos += r.calculating_cverts_pos
  84. calc_cverts_len += r.calculating_cverts_len
  85. except ValueError:
  86. pass
  87. for r in self.plot._pobjects:
  88. pgl.glPushMatrix()
  89. r._draw()
  90. pgl.glPopMatrix()
  91. if should_update_caption:
  92. self.update_caption(calc_verts_pos, calc_verts_len,
  93. calc_cverts_pos, calc_cverts_len)
  94. self.last_caption_update = perf_counter()
  95. if self.plot._screenshot:
  96. self.plot._screenshot._execute_saving()
  97. self.plot._render_lock.release()
  98. def update_caption(self, calc_verts_pos, calc_verts_len,
  99. calc_cverts_pos, calc_cverts_len):
  100. caption = self.title
  101. if calc_verts_len or calc_cverts_len:
  102. caption += " (calculating"
  103. if calc_verts_len > 0:
  104. p = (calc_verts_pos / calc_verts_len) * 100
  105. caption += " vertices %i%%" % (p)
  106. if calc_cverts_len > 0:
  107. p = (calc_cverts_pos / calc_cverts_len) * 100
  108. caption += " colors %i%%" % (p)
  109. caption += ")"
  110. if self.caption != caption:
  111. self.set_caption(caption)