SolidView.py 4.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Copyright (c) 2015 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. from UM.View.View import View
  4. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
  5. from UM.Resources import Resources
  6. from UM.Application import Application
  7. from UM.Preferences import Preferences
  8. from UM.View.Renderer import Renderer
  9. from UM.View.GL.OpenGL import OpenGL
  10. import cura.Settings
  11. import math
  12. ## Standard view for mesh models.
  13. class SolidView(View):
  14. def __init__(self):
  15. super().__init__()
  16. Preferences.getInstance().addPreference("view/show_overhang", True)
  17. self._enabled_shader = None
  18. self._disabled_shader = None
  19. self._extruders_model = cura.Settings.ExtrudersModel()
  20. def beginRendering(self):
  21. scene = self.getController().getScene()
  22. renderer = self.getRenderer()
  23. if not self._enabled_shader:
  24. self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
  25. if not self._disabled_shader:
  26. self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
  27. self._disabled_shader.setUniformValue("u_diffuseColor", [0.68, 0.68, 0.68, 1.0])
  28. self._disabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))
  29. if Application.getInstance().getGlobalContainerStack():
  30. if Preferences.getInstance().getValue("view/show_overhang"):
  31. angle = Application.getInstance().getGlobalContainerStack().getProperty("support_angle", "value")
  32. if angle is not None:
  33. self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle)))
  34. else:
  35. self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang.
  36. else:
  37. self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))
  38. for node in DepthFirstIterator(scene.getRoot()):
  39. if not node.render(renderer):
  40. if node.getMeshData() and node.isVisible():
  41. # TODO: Find a better way to handle this
  42. #if node.getBoundingBoxMesh():
  43. # renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines)
  44. uniforms = {}
  45. if self._extruders_model.rowCount() > 0:
  46. # Get color to render this mesh in from ExtrudersModel
  47. extruder_index = 0
  48. extruder_id = node.callDecoration("getActiveExtruder")
  49. if extruder_id:
  50. extruder_index = max(0, self._extruders_model.find("id", extruder_id))
  51. extruder_color = self._extruders_model.getItem(extruder_index)["colour"]
  52. try:
  53. # Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
  54. # an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
  55. uniforms["diffuse_color"] = [
  56. int(extruder_color[1:3], 16) / 255,
  57. int(extruder_color[3:5], 16) / 255,
  58. int(extruder_color[5:7], 16) / 255,
  59. 1.0
  60. ]
  61. except ValueError:
  62. pass
  63. if hasattr(node, "_outside_buildarea"):
  64. if node._outside_buildarea:
  65. renderer.queueNode(node, shader = self._disabled_shader)
  66. else:
  67. renderer.queueNode(node, shader = self._enabled_shader, uniforms = uniforms)
  68. else:
  69. renderer.queueNode(node, material = self._enabled_shader, uniforms = uniforms)
  70. if node.callDecoration("isGroup"):
  71. renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(), mode = Renderer.RenderLines)
  72. def endRendering(self):
  73. pass
  74. #def _onPreferenceChanged(self, preference):
  75. #if preference == "view/show_overhang": ## Todo: This a printer only setting. Should be removed from Uranium.
  76. #self._enabled_material = None