ConvexHullNode.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # Copyright (c) 2015 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. from UM.Scene.SceneNode import SceneNode
  4. from UM.Resources import Resources
  5. from UM.Math.Color import Color
  6. from UM.Math.Vector import Vector
  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. ## Convex hull node is a special type of scene node that is used to display a 2D area, to indicate the
  11. # location an object uses on the buildplate. This area (or area's in case of one at a time printing) is
  12. # then displayed as a transparent shadow.
  13. def __init__(self, node, hull, parent = None):
  14. super().__init__(parent)
  15. self.setCalculateBoundingBox(False)
  16. self._shader = None
  17. self._original_parent = parent
  18. # Color of the drawn convex hull
  19. self._color = Color(35, 35, 35, 128)
  20. # The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
  21. self._mesh_height = 0.1
  22. # The node this mesh is "watching"
  23. self._node = node
  24. self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
  25. self._onNodeDecoratorsChanged(self._node)
  26. self._convex_hull_head_mesh = None
  27. self._hull = hull
  28. if self._hull:
  29. hull_mesh = self.createHullMesh(self._hull.getPoints())
  30. if hull_mesh:
  31. self.setMeshData(hull_mesh)
  32. convex_hull_head = self._node.callDecoration("getConvexHullHead")
  33. if convex_hull_head:
  34. self._convex_hull_head_mesh = self.createHullMesh(convex_hull_head.getPoints())
  35. def getHull(self):
  36. return self._hull
  37. ## Actually create the mesh from the hullpoints
  38. # /param hull_points list of xy values
  39. # /return meshData
  40. def createHullMesh(self, hull_points):
  41. # Input checking.
  42. if len(hull_points) < 3:
  43. return None
  44. mesh_builder = MeshBuilder()
  45. point_first = Vector(hull_points[0][0], self._mesh_height, hull_points[0][1])
  46. point_previous = Vector(hull_points[1][0], self._mesh_height, hull_points[1][1])
  47. for point in hull_points[2:]: # Add the faces in the order of a triangle fan.
  48. point_new = Vector(point[0], self._mesh_height, point[1])
  49. mesh_builder.addFace(point_first, point_previous, point_new, color = self._color)
  50. point_previous = point_new # Prepare point_previous for the next triangle.
  51. return mesh_builder.build()
  52. def getWatchedNode(self):
  53. return self._node
  54. def render(self, renderer):
  55. if not self._shader:
  56. self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
  57. self._shader.setUniformValue("u_color", self._color)
  58. if self.getParent():
  59. if self.getMeshData():
  60. renderer.queueNode(self, transparent = True, shader = self._shader, backface_cull = True, sort = -8)
  61. if self._convex_hull_head_mesh:
  62. renderer.queueNode(self, shader = self._shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)
  63. return True
  64. def _onNodeDecoratorsChanged(self, node):
  65. self._color = Color(35, 35, 35, 0.5)
  66. if not node:
  67. return