diff --git a/cura/Arranging/ArrangeObjectsJob.py b/cura/Arranging/ArrangeObjectsJob.py index f84a0a8c42..481b8c2dc8 100644 --- a/cura/Arranging/ArrangeObjectsJob.py +++ b/cura/Arranging/ArrangeObjectsJob.py @@ -27,7 +27,7 @@ class ArrangeObjectsJob(Job): title = i18n_catalog.i18nc("@info:title", "Finding Location")) status_message.show() - found_solution_for_all = arrange(self._nodes, Application.getInstance().getBuildVolume()) + found_solution_for_all = arrange(self._nodes, Application.getInstance().getBuildVolume(), self._fixed_nodes) status_message.hide() if not found_solution_for_all: diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a9555a6608..ee6cc57523 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -36,6 +36,7 @@ from UM.Scene.Camera import Camera from UM.Scene.GroupDecorator import GroupDecorator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.SceneNode import SceneNode +from UM.Scene.SceneNodeSettings import SceneNodeSettings from UM.Scene.Selection import Selection from UM.Scene.ToolHandle import ToolHandle from UM.Settings.ContainerRegistry import ContainerRegistry @@ -43,6 +44,7 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType from UM.Settings.SettingFunction import SettingFunction from UM.Settings.Validator import Validator +from UM.Util import parseBool from UM.View.SelectionPass import SelectionPass # For typing. from UM.Workspace.WorkspaceReader import WorkspaceReader from UM.i18n import i18nCatalog @@ -1381,6 +1383,7 @@ class CuraApplication(QtApplication): def arrangeAll(self) -> None: nodes_to_arrange = [] active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate + fixed_nodes = [] for node in DepthFirstIterator(self.getController().getScene().getRoot()): if not isinstance(node, SceneNode): continue @@ -1402,8 +1405,12 @@ class CuraApplication(QtApplication): # Skip nodes that are too big bounding_box = node.getBoundingBox() if bounding_box is None or bounding_box.width < self._volume.getBoundingBox().width or bounding_box.depth < self._volume.getBoundingBox().depth: - nodes_to_arrange.append(node) - self.arrange(nodes_to_arrange, fixed_nodes = []) + # Arrange only the unlocked nodes and keep the locked ones in place + if not parseBool(node.getSetting(SceneNodeSettings.LockPosition)): + nodes_to_arrange.append(node) + else: + fixed_nodes.append(node) + self.arrange(nodes_to_arrange, fixed_nodes = fixed_nodes) def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode]) -> None: """Arrange a set of nodes given a set of fixed nodes