XRayView.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # Copyright (c) 2015 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. import os.path
  4. from UM.PluginRegistry import PluginRegistry
  5. from UM.Event import Event
  6. from UM.View.View import View
  7. from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
  8. from UM.View.RenderBatch import RenderBatch
  9. from UM.View.GL.OpenGL import OpenGL
  10. from . import XRayPass
  11. ## View used to display a see-through version of objects with errors highlighted.
  12. class XRayView(View):
  13. def __init__(self):
  14. super().__init__()
  15. self._xray_shader = None
  16. self._xray_pass = None
  17. self._xray_composite_shader = None
  18. self._composite_pass = None
  19. self._old_composite_shader = None
  20. self._old_layer_bindings = None
  21. def beginRendering(self):
  22. scene = self.getController().getScene()
  23. renderer = self.getRenderer()
  24. if not self._xray_shader:
  25. self._xray_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader"))
  26. self._xray_shader.setUniformValue("u_color", [0.1, 0.1, 0.2, 1.0])
  27. for node in BreadthFirstIterator(scene.getRoot()):
  28. if not node.render(renderer):
  29. if node.getMeshData() and node.isVisible():
  30. renderer.queueNode(node,
  31. shader = self._xray_shader,
  32. type = RenderBatch.RenderType.Solid,
  33. blend_mode = RenderBatch.BlendMode.Additive,
  34. sort = -10,
  35. state_setup_callback = lambda gl: gl.glDepthFunc(gl.GL_ALWAYS),
  36. state_teardown_callback = lambda gl: gl.glDepthFunc(gl.GL_LESS)
  37. )
  38. def endRendering(self):
  39. pass
  40. def event(self, event):
  41. if event.type == Event.ViewActivateEvent:
  42. if not self._xray_pass:
  43. # Currently the RenderPass constructor requires a size > 0
  44. # This should be fixed in RenderPass's constructor.
  45. self._xray_pass = XRayPass.XRayPass(1, 1)
  46. self.getRenderer().addRenderPass(self._xray_pass)
  47. if not self._xray_composite_shader:
  48. self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader"))
  49. if not self._composite_pass:
  50. self._composite_pass = self.getRenderer().getRenderPass("composite")
  51. self._old_layer_bindings = self._composite_pass.getLayerBindings()
  52. self._composite_pass.setLayerBindings(["default", "selection", "xray"])
  53. self._old_composite_shader = self._composite_pass.getCompositeShader()
  54. self._composite_pass.setCompositeShader(self._xray_composite_shader)
  55. if event.type == Event.ViewDeactivateEvent:
  56. self._composite_pass.setLayerBindings(self._old_layer_bindings)
  57. self._composite_pass.setCompositeShader(self._old_composite_shader)