mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
Raft thickness lowers the build volume.
CURA-1707 Now adding more visuals for better UX.
This commit is contained in:
parent
56efb92f3e
commit
b3837fbafd
4 changed files with 42 additions and 10 deletions
|
@ -2,6 +2,7 @@
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
|
from UM.Scene.Platform import Platform
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Resources import Resources
|
from UM.Resources import Resources
|
||||||
|
@ -41,6 +42,9 @@ class BuildVolume(SceneNode):
|
||||||
self.setCalculateBoundingBox(False)
|
self.setCalculateBoundingBox(False)
|
||||||
self._volume_aabb = None
|
self._volume_aabb = None
|
||||||
|
|
||||||
|
self.raft_thickness = 0.0
|
||||||
|
self._platform = Platform(self)
|
||||||
|
|
||||||
self._active_container_stack = None
|
self._active_container_stack = None
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
|
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
|
||||||
self._onGlobalContainerStackChanged()
|
self._onGlobalContainerStackChanged()
|
||||||
|
@ -172,6 +176,21 @@ class BuildVolume(SceneNode):
|
||||||
" \"Print Sequence\" setting to prevent the gantry from colliding"
|
" \"Print Sequence\" setting to prevent the gantry from colliding"
|
||||||
" with printed objects."), lifetime=10).show()
|
" with printed objects."), lifetime=10).show()
|
||||||
|
|
||||||
|
def _updateRaftThickness(self):
|
||||||
|
old_raft_thickness = self.raft_thickness
|
||||||
|
adhesion_type = self._active_container_stack.getProperty("adhesion_type", "value")
|
||||||
|
self.raft_thickness = 0.0
|
||||||
|
if adhesion_type == "raft":
|
||||||
|
self.raft_thickness = (
|
||||||
|
self._active_container_stack.getProperty("raft_base_thickness", "value") +
|
||||||
|
self._active_container_stack.getProperty("raft_interface_thickness", "value") +
|
||||||
|
self._active_container_stack.getProperty("raft_surface_layers", "value") *
|
||||||
|
self._active_container_stack.getProperty("raft_surface_thickness", "value") +
|
||||||
|
self._active_container_stack.getProperty("raft_airgap", "value"))
|
||||||
|
# Rounding errors do not matter, we check if raft_thickness has changed at all
|
||||||
|
if old_raft_thickness != self.raft_thickness:
|
||||||
|
self.setPosition(Vector(0, -self.raft_thickness, 0), SceneNode.TransformSpace.World)
|
||||||
|
|
||||||
def _onGlobalContainerStackChanged(self):
|
def _onGlobalContainerStackChanged(self):
|
||||||
if self._active_container_stack:
|
if self._active_container_stack:
|
||||||
self._active_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
self._active_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
||||||
|
@ -190,6 +209,7 @@ class BuildVolume(SceneNode):
|
||||||
self._depth = self._active_container_stack.getProperty("machine_depth", "value")
|
self._depth = self._active_container_stack.getProperty("machine_depth", "value")
|
||||||
|
|
||||||
self._updateDisallowedAreas()
|
self._updateDisallowedAreas()
|
||||||
|
self._updateRaftThickness()
|
||||||
|
|
||||||
self.rebuild()
|
self.rebuild()
|
||||||
|
|
||||||
|
@ -197,15 +217,24 @@ class BuildVolume(SceneNode):
|
||||||
if property_name != "value":
|
if property_name != "value":
|
||||||
return
|
return
|
||||||
|
|
||||||
|
rebuild_me = False
|
||||||
if setting_key == "print_sequence":
|
if setting_key == "print_sequence":
|
||||||
if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time":
|
if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time":
|
||||||
self._height = self._active_container_stack.getProperty("gantry_height", "value")
|
self._height = self._active_container_stack.getProperty("gantry_height", "value")
|
||||||
self._buildVolumeMessage()
|
self._buildVolumeMessage()
|
||||||
else:
|
else:
|
||||||
self._height = self._active_container_stack.getProperty("machine_height", "value")
|
self._height = self._active_container_stack.getProperty("machine_height", "value")
|
||||||
self.rebuild()
|
rebuild_me = True
|
||||||
|
|
||||||
if setting_key in self._skirt_settings:
|
if setting_key in self._skirt_settings:
|
||||||
self._updateDisallowedAreas()
|
self._updateDisallowedAreas()
|
||||||
|
rebuild_me = True
|
||||||
|
|
||||||
|
if setting_key in self._raft_settings:
|
||||||
|
self._updateRaftThickness()
|
||||||
|
rebuild_me = True
|
||||||
|
|
||||||
|
if rebuild_me:
|
||||||
self.rebuild()
|
self.rebuild()
|
||||||
|
|
||||||
def _updateDisallowedAreas(self):
|
def _updateDisallowedAreas(self):
|
||||||
|
@ -269,7 +298,7 @@ class BuildVolume(SceneNode):
|
||||||
|
|
||||||
self._disallowed_areas = areas
|
self._disallowed_areas = areas
|
||||||
|
|
||||||
## Convenience function to calculate the size of the bed adhesion.
|
## Convenience function to calculate the size of the bed adhesion in directions x, y.
|
||||||
def _getSkirtSize(self, container_stack):
|
def _getSkirtSize(self, container_stack):
|
||||||
skirt_size = 0.0
|
skirt_size = 0.0
|
||||||
|
|
||||||
|
@ -295,3 +324,4 @@ class BuildVolume(SceneNode):
|
||||||
return max(min(value, max_value), min_value)
|
return max(min(value, max_value), min_value)
|
||||||
|
|
||||||
_skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "xy_offset"]
|
_skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "xy_offset"]
|
||||||
|
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap"]
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
from UM.Qt.QtApplication import QtApplication
|
from UM.Qt.QtApplication import QtApplication
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from UM.Scene.Camera import Camera
|
from UM.Scene.Camera import Camera
|
||||||
from UM.Scene.Platform import Platform as Scene_Platform
|
|
||||||
from UM.Math.Vector import Vector
|
from UM.Math.Vector import Vector
|
||||||
from UM.Math.Quaternion import Quaternion
|
from UM.Math.Quaternion import Quaternion
|
||||||
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
||||||
|
@ -144,7 +143,6 @@ class CuraApplication(QtApplication):
|
||||||
])
|
])
|
||||||
self._physics = None
|
self._physics = None
|
||||||
self._volume = None
|
self._volume = None
|
||||||
self._platform = None
|
|
||||||
self._output_devices = {}
|
self._output_devices = {}
|
||||||
self._print_information = None
|
self._print_information = None
|
||||||
self._previous_active_tool = None
|
self._previous_active_tool = None
|
||||||
|
@ -377,8 +375,8 @@ class CuraApplication(QtApplication):
|
||||||
Selection.selectionChanged.connect(self.onSelectionChanged)
|
Selection.selectionChanged.connect(self.onSelectionChanged)
|
||||||
|
|
||||||
root = controller.getScene().getRoot()
|
root = controller.getScene().getRoot()
|
||||||
self._platform = Scene_Platform(root)
|
|
||||||
|
|
||||||
|
# The platform is a child of BuildVolume
|
||||||
self._volume = BuildVolume.BuildVolume(root)
|
self._volume = BuildVolume.BuildVolume(root)
|
||||||
|
|
||||||
self.getRenderer().setBackgroundColor(QColor(245, 245, 245))
|
self.getRenderer().setBackgroundColor(QColor(245, 245, 245))
|
||||||
|
@ -857,3 +855,6 @@ class CuraApplication(QtApplication):
|
||||||
@pyqtSlot("QSize")
|
@pyqtSlot("QSize")
|
||||||
def setMinimumWindowSize(self, size):
|
def setMinimumWindowSize(self, size):
|
||||||
self.getMainWindow().setMinimumSize(size)
|
self.getMainWindow().setMinimumSize(size)
|
||||||
|
|
||||||
|
def getBuildVolume(self):
|
||||||
|
return self._volume
|
|
@ -40,6 +40,7 @@ class PlatformPhysics:
|
||||||
return
|
return
|
||||||
|
|
||||||
root = self._controller.getScene().getRoot()
|
root = self._controller.getScene().getRoot()
|
||||||
|
|
||||||
for node in BreadthFirstIterator(root):
|
for node in BreadthFirstIterator(root):
|
||||||
if node is root or type(node) is not SceneNode or node.getBoundingBox() is None:
|
if node is root or type(node) is not SceneNode or node.getBoundingBox() is None:
|
||||||
continue
|
continue
|
||||||
|
@ -58,10 +59,7 @@ class PlatformPhysics:
|
||||||
move_vector = Vector()
|
move_vector = Vector()
|
||||||
if not (node.getParent() and node.getParent().callDecoration("isGroup")): #If an object is grouped, don't move it down
|
if not (node.getParent() and node.getParent().callDecoration("isGroup")): #If an object is grouped, don't move it down
|
||||||
z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0
|
z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0
|
||||||
if bbox.bottom > 0:
|
move_vector = move_vector.set(y=-bbox.bottom + z_offset)
|
||||||
move_vector = move_vector.set(y=-bbox.bottom + z_offset)
|
|
||||||
elif bbox.bottom < z_offset:
|
|
||||||
move_vector = move_vector.set(y=(-bbox.bottom) - z_offset)
|
|
||||||
|
|
||||||
# If there is no convex hull for the node, start calculating it and continue.
|
# If there is no convex hull for the node, start calculating it and continue.
|
||||||
if not node.getDecorator(ConvexHullDecorator):
|
if not node.getDecorator(ConvexHullDecorator):
|
||||||
|
|
|
@ -128,7 +128,10 @@ class ProcessSlicedLayersJob(Job):
|
||||||
new_node.addDecorator(decorator)
|
new_node.addDecorator(decorator)
|
||||||
|
|
||||||
new_node.setMeshData(mesh)
|
new_node.setMeshData(mesh)
|
||||||
new_node.setParent(self._scene.getRoot()) # Note: After this we can no longer abort!
|
# Set build volume as parent, the build volume can move as a result of raft settings.
|
||||||
|
# It makes sense to set the build volume as parent: the print is actually printed on it.
|
||||||
|
new_node_parent = Application.getInstance().getBuildVolume()
|
||||||
|
new_node.setParent(new_node_parent) # Note: After this we can no longer abort!
|
||||||
|
|
||||||
settings = Application.getInstance().getGlobalContainerStack()
|
settings = Application.getInstance().getGlobalContainerStack()
|
||||||
if not settings.getProperty("machine_center_is_zero", "value"):
|
if not settings.getProperty("machine_center_is_zero", "value"):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue