ConvexHullNode.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. # Copyright (c) 2015 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from UM.Application import Application
  4. from UM.Scene.SceneNode import SceneNode
  5. from UM.Resources import Resources
  6. from UM.Math.Color import Color
  7. from UM.Mesh.MeshBuilder import MeshBuilder # To create a mesh to display the convex hull with.
  8. from UM.View.GL.OpenGL import OpenGL
  9. class ConvexHullNode(SceneNode):
  10. shader = None # To prevent the shader from being re-built over and over again, only load it once.
  11. ## Convex hull node is a special type of scene node that is used to display an area, to indicate the
  12. # location an object uses on the buildplate. This area (or area's in case of one at a time printing) is
  13. # then displayed as a transparent shadow. If the adhesion type is set to raft, the area is extruded
  14. # to represent the raft as well.
  15. def __init__(self, node, hull, thickness, parent = None):
  16. super().__init__(parent)
  17. self.setCalculateBoundingBox(False)
  18. self._original_parent = parent
  19. # Color of the drawn convex hull
  20. if Application.getInstance().hasGui():
  21. self._color = Color(*Application.getInstance().getTheme().getColor("convex_hull").getRgb())
  22. else:
  23. self._color = Color(0, 0, 0)
  24. # The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
  25. self._mesh_height = 0.1
  26. self._thickness = thickness
  27. # The node this mesh is "watching"
  28. self._node = node
  29. self._convex_hull_head_mesh = None
  30. self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
  31. self._onNodeDecoratorsChanged(self._node)
  32. self._hull = hull
  33. if self._hull:
  34. hull_mesh_builder = MeshBuilder()
  35. if hull_mesh_builder.addConvexPolygonExtrusion(
  36. self._hull.getPoints()[::-1], # bottom layer is reversed
  37. self._mesh_height-thickness, self._mesh_height, color=self._color):
  38. hull_mesh = hull_mesh_builder.build()
  39. self.setMeshData(hull_mesh)
  40. def getHull(self):
  41. return self._hull
  42. def getThickness(self):
  43. return self._thickness
  44. def getWatchedNode(self):
  45. return self._node
  46. def render(self, renderer):
  47. if not ConvexHullNode.shader:
  48. ConvexHullNode.shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
  49. ConvexHullNode.shader.setUniformValue("u_diffuseColor", self._color)
  50. ConvexHullNode.shader.setUniformValue("u_opacity", 0.6)
  51. if self.getParent():
  52. if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate:
  53. renderer.queueNode(self, transparent = True, shader = ConvexHullNode.shader, backface_cull = True, sort = -8)
  54. if self._convex_hull_head_mesh:
  55. renderer.queueNode(self, shader = ConvexHullNode.shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)
  56. return True
  57. def _onNodeDecoratorsChanged(self, node):
  58. convex_hull_head = self._node.callDecoration("getConvexHullHead")
  59. if convex_hull_head:
  60. convex_hull_head_builder = MeshBuilder()
  61. convex_hull_head_builder.addConvexPolygon(convex_hull_head.getPoints(), self._mesh_height - self._thickness)
  62. self._convex_hull_head_mesh = convex_hull_head_builder.build()
  63. if not node:
  64. return