CuraSceneNode.py 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from typing import List
  2. from UM.Application import Application
  3. from UM.Scene.SceneNode import SceneNode
  4. from copy import deepcopy
  5. from cura.Settings.ExtrudersModel import ExtrudersModel
  6. ## Scene nodes that are models are only seen when selecting the corresponding build plate
  7. # Note that many other nodes can just be UM SceneNode objects.
  8. class CuraSceneNode(SceneNode):
  9. def __init__(self, *args, **kwargs):
  10. super().__init__(*args, **kwargs)
  11. self._outside_buildarea = False
  12. def setOutsideBuildArea(self, new_value):
  13. self._outside_buildarea = new_value
  14. def isOutsideBuildArea(self):
  15. return self._outside_buildarea or self.callDecoration("getBuildPlateNumber") < 0
  16. def isVisible(self):
  17. return super().isVisible() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate
  18. def isSelectable(self) -> bool:
  19. return super().isSelectable() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate
  20. ## Get the extruder used to print this node. If there is no active node, then the extruder in position zero is returned
  21. # TODO The best way to do it is by adding the setActiveExtruder decorator to every node when is loaded
  22. def getPrintingExtruder(self):
  23. global_container_stack = Application.getInstance().getGlobalContainerStack()
  24. per_mesh_stack = self.callDecoration("getStack")
  25. extruders = list(global_container_stack.extruders.values())
  26. # Use the support extruder instead of the active extruder if this is a support_mesh
  27. if per_mesh_stack:
  28. if per_mesh_stack.getProperty("support_mesh", "value"):
  29. return extruders[int(global_container_stack.getProperty("support_extruder_nr", "value"))]
  30. # It's only set if you explicitly choose an extruder
  31. extruder_id = self.callDecoration("getActiveExtruder")
  32. for extruder in extruders:
  33. # Find out the extruder if we know the id.
  34. if extruder_id is not None:
  35. if extruder_id == extruder.getId():
  36. return extruder
  37. else: # If the id is unknown, then return the extruder in the position 0
  38. try:
  39. if extruder.getMetaDataEntry("position", default = "0") == "0": # Check if the position is zero
  40. return extruder
  41. except ValueError:
  42. continue
  43. # This point should never be reached
  44. return None
  45. ## Return the color of the material used to print this model
  46. def getDiffuseColor(self) -> List[float]:
  47. printing_extruder = self.getPrintingExtruder()
  48. material_color = "#808080" # Fallback color
  49. if printing_extruder is not None and printing_extruder.material:
  50. material_color = printing_extruder.material.getMetaDataEntry("color_code", default = material_color)
  51. # Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
  52. # an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
  53. return [
  54. int(material_color[1:3], 16) / 255,
  55. int(material_color[3:5], 16) / 255,
  56. int(material_color[5:7], 16) / 255,
  57. 1.0
  58. ]
  59. ## Taken from SceneNode, but replaced SceneNode with CuraSceneNode
  60. def __deepcopy__(self, memo):
  61. copy = CuraSceneNode()
  62. copy.setTransformation(self.getLocalTransformation())
  63. copy.setMeshData(self._mesh_data)
  64. copy.setVisible(deepcopy(self._visible, memo))
  65. copy._selectable = deepcopy(self._selectable, memo)
  66. copy._name = deepcopy(self._name, memo)
  67. for decorator in self._decorators:
  68. copy.addDecorator(deepcopy(decorator, memo))
  69. for child in self._children:
  70. copy.addChild(deepcopy(child, memo))
  71. self.calculateBoundingBoxMesh()
  72. return copy
  73. def transformChanged(self) -> None:
  74. self._transformChanged()