ConvexHullNode.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. import numpy
  10. class ConvexHullNode(SceneNode):
  11. def __init__(self, node, hull, parent = None):
  12. super().__init__(parent)
  13. self.setCalculateBoundingBox(False)
  14. self._shader = None
  15. self._original_parent = parent
  16. self._inherit_orientation = False
  17. self._inherit_scale = False
  18. self._color = Color(35, 35, 35, 128)
  19. self._mesh_height = 0.1 #The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
  20. self._node = node
  21. self._node.transformationChanged.connect(self._onNodePositionChanged)
  22. self._node.parentChanged.connect(self._onNodeParentChanged)
  23. self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
  24. self._onNodeDecoratorsChanged(self._node)
  25. self._convex_hull_head_mesh = None
  26. self._hull = hull
  27. hull_points = self._hull.getPoints()
  28. hull_mesh = self.createHullMesh(self._hull.getPoints())
  29. if hull_mesh:
  30. self.setMeshData(hull_mesh)
  31. convex_hull_head = self._node.callDecoration("getConvexHullHead")
  32. if convex_hull_head:
  33. self._convex_hull_head_mesh = self.createHullMesh(convex_hull_head.getPoints())
  34. def createHullMesh(self, hull_points):
  35. #Input checking.
  36. if len(hull_points) < 3:
  37. return None
  38. mesh_builder = MeshBuilder()
  39. point_first = Vector(hull_points[0][0], self._mesh_height, hull_points[0][1])
  40. point_previous = Vector(hull_points[1][0], self._mesh_height, hull_points[1][1])
  41. for point in hull_points[2:]: #Add the faces in the order of a triangle fan.
  42. point_new = Vector(point[0], self._mesh_height, point[1])
  43. mesh_builder.addFace(point_first, point_previous, point_new, color = self._color)
  44. point_previous = point_new #Prepare point_previous for the next triangle.
  45. return mesh_builder.getData()
  46. def getWatchedNode(self):
  47. return self._node
  48. def render(self, renderer):
  49. if not self._shader:
  50. self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
  51. self._shader.setUniformValue("u_color", self._color)
  52. if self.getParent():
  53. renderer.queueNode(self, transparent = True, shader = self._shader, backface_cull = True, sort = -8)
  54. if self._convex_hull_head_mesh:
  55. renderer.queueNode(self, shader = self._shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)
  56. return True
  57. def _onNodePositionChanged(self, node):
  58. if node.callDecoration("getConvexHull"):
  59. node.callDecoration("setConvexHull", None)
  60. node.callDecoration("setConvexHullNode", None)
  61. self.setParent(None)
  62. def _onNodeParentChanged(self, node):
  63. if node.getParent():
  64. self.setParent(self._original_parent)
  65. else:
  66. self.setParent(None)
  67. def _onNodeDecoratorsChanged(self, node):
  68. self._color = Color(35, 35, 35, 0.5)
  69. if not node:
  70. return