XRayView.py 3.7 KB

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