LayerPass.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. # Copyright (c) 2016 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
  4. from UM.Resources import Resources
  5. from UM.Scene.SceneNode import SceneNode
  6. from UM.Scene.ToolHandle import ToolHandle
  7. from UM.Application import Application
  8. from UM.PluginRegistry import PluginRegistry
  9. from UM.View.RenderPass import RenderPass
  10. from UM.View.RenderBatch import RenderBatch
  11. from UM.View.GL.OpenGL import OpenGL
  12. from cura.Settings.ExtruderManager import ExtruderManager
  13. import os.path
  14. ## RenderPass used to display g-code paths.
  15. class LayerPass(RenderPass):
  16. def __init__(self, width, height):
  17. super().__init__("layerview", width, height)
  18. self._layer_shader = None
  19. self._tool_handle_shader = None
  20. self._gl = OpenGL.getInstance().getBindingsObject()
  21. self._scene = Application.getInstance().getController().getScene()
  22. self._extruder_manager = ExtruderManager.getInstance()
  23. self._layer_view = None
  24. self._compatibility_mode = None
  25. def setLayerView(self, layerview):
  26. self._layer_view = layerview
  27. self._compatibility_mode = layerview.getCompatibilityMode()
  28. def render(self):
  29. if not self._layer_shader:
  30. if self._compatibility_mode:
  31. shader_filename = "layers.shader"
  32. else:
  33. shader_filename = "layers3d.shader"
  34. self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), shader_filename))
  35. # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
  36. self._layer_shader.setUniformValue("u_active_extruder", float(max(0, self._extruder_manager.activeExtruderIndex)))
  37. if self._layer_view:
  38. self._layer_shader.setUniformValue("u_layer_view_type", self._layer_view.getLayerViewType())
  39. self._layer_shader.setUniformValue("u_extruder_opacity", self._layer_view.getExtruderOpacities())
  40. self._layer_shader.setUniformValue("u_show_travel_moves", self._layer_view.getShowTravelMoves())
  41. self._layer_shader.setUniformValue("u_show_helpers", self._layer_view.getShowHelpers())
  42. self._layer_shader.setUniformValue("u_show_skin", self._layer_view.getShowSkin())
  43. self._layer_shader.setUniformValue("u_show_infill", self._layer_view.getShowInfill())
  44. else:
  45. #defaults
  46. self._layer_shader.setUniformValue("u_layer_view_type", 1)
  47. self._layer_shader.setUniformValue("u_extruder_opacity", [1, 1, 1, 1])
  48. self._layer_shader.setUniformValue("u_show_travel_moves", 0)
  49. self._layer_shader.setUniformValue("u_show_helpers", 1)
  50. self._layer_shader.setUniformValue("u_show_skin", 1)
  51. self._layer_shader.setUniformValue("u_show_infill", 1)
  52. if not self._tool_handle_shader:
  53. self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader"))
  54. self.bind()
  55. tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay)
  56. for node in DepthFirstIterator(self._scene.getRoot()):
  57. if isinstance(node, ToolHandle):
  58. tool_handle_batch.addItem(node.getWorldTransformation(), mesh = node.getSolidMesh())
  59. elif isinstance(node, SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible():
  60. layer_data = node.callDecoration("getLayerData")
  61. if not layer_data:
  62. continue
  63. # Render all layers below a certain number as line mesh instead of vertices.
  64. if self._layer_view._current_layer_num > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())):
  65. start = 0
  66. end = 0
  67. element_counts = layer_data.getElementCounts()
  68. for layer, counts in element_counts.items():
  69. if layer > self._layer_view._current_layer_num:
  70. break
  71. if self._layer_view._minimum_layer_num > layer:
  72. start += counts
  73. end += counts
  74. # This uses glDrawRangeElements internally to only draw a certain range of lines.
  75. batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid, mode = RenderBatch.RenderMode.Lines, range = (start, end))
  76. batch.addItem(node.getWorldTransformation(), layer_data)
  77. batch.render(self._scene.getActiveCamera())
  78. # Create a new batch that is not range-limited
  79. batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid)
  80. if self._layer_view.getCurrentLayerMesh():
  81. batch.addItem(node.getWorldTransformation(), self._layer_view.getCurrentLayerMesh())
  82. if self._layer_view.getCurrentLayerJumps():
  83. batch.addItem(node.getWorldTransformation(), self._layer_view.getCurrentLayerJumps())
  84. if len(batch.items) > 0:
  85. batch.render(self._scene.getActiveCamera())
  86. # Render toolhandles on top of the layerview
  87. if len(tool_handle_batch.items) > 0:
  88. tool_handle_batch.render(self._scene.getActiveCamera())
  89. self.release()