diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 6401ad77af..5d1e38f5c8 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -111,6 +111,9 @@ class BuildVolume(SceneNode): # but it does not update the disallowed areas after material change Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged) + # Enable and disable extruder + Application.getInstance().getMachineManager().extruderChanged.connect(self.updateNodeBoundaryCheck) + # list of settings which were updated self._changed_settings_since_last_rebuild = [] @@ -217,30 +220,26 @@ class BuildVolume(SceneNode): group_nodes.append(node) # Keep list of affected group_nodes if node.callDecoration("isSliceable") or node.callDecoration("isGroup"): - node._outside_buildarea = False - bbox = node.getBoundingBox() - - # Mark the node as outside the build volume if the bounding box test fails. - if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection: - node._outside_buildarea = True + if node.collidesWithBbox(build_volume_bounding_box): + node.setOutsideBuildArea(True) continue - convex_hull = node.callDecoration("getConvexHull") - if convex_hull: - if not convex_hull.isValid(): - return - # Check for collisions between disallowed areas and the object - for area in self.getDisallowedAreas(): - overlap = convex_hull.intersectsPolygon(area) - if overlap is None: - continue - node._outside_buildarea = True - continue + if node.collidesWithArea(self.getDisallowedAreas()): + node.setOutsideBuildArea(True) + continue + + # Mark the node as outside build volume if the set extruder is disabled + extruder_position = node.callDecoration("getActiveExtruderPosition") + if not self._global_container_stack.extruders[extruder_position].isEnabled: + node.setOutsideBuildArea(True) + continue + + node.setOutsideBuildArea(False) # Group nodes should override the _outside_buildarea property of their children. for group_node in group_nodes: for child_node in group_node.getAllChildren(): - child_node._outside_buildarea = group_node._outside_buildarea + child_node.setOutsideBuildArea(group_node.isOutsideBuildArea) ## Update the outsideBuildArea of a single node, given bounds or current build volume def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None): @@ -260,24 +259,20 @@ class BuildVolume(SceneNode): build_volume_bounding_box = bounds if node.callDecoration("isSliceable") or node.callDecoration("isGroup"): - bbox = node.getBoundingBox() - - # Mark the node as outside the build volume if the bounding box test fails. - if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection: + if node.collidesWithBbox(build_volume_bounding_box): + node.setOutsideBuildArea(True) + return + + if node.collidesWithArea(self.getDisallowedAreas()): + node.setOutsideBuildArea(True) + return + + # Mark the node as outside build volume if the set extruder is disabled + extruder_position = node.callDecoration("getActiveExtruderPosition") + if not self._global_container_stack.extruders[extruder_position].isEnabled: node.setOutsideBuildArea(True) return - convex_hull = self.callDecoration("getConvexHull") - if convex_hull: - if not convex_hull.isValid(): - return - # Check for collisions between disallowed areas and the object - for area in self.getDisallowedAreas(): - overlap = convex_hull.intersectsPolygon(area) - if overlap is None: - continue - node.setOutsideBuildArea(True) - return node.setOutsideBuildArea(False) ## Recalculates the build volume & disallowed areas. diff --git a/cura/Scene/CuraSceneNode.py b/cura/Scene/CuraSceneNode.py index 88f89522f6..cfc41eb689 100644 --- a/cura/Scene/CuraSceneNode.py +++ b/cura/Scene/CuraSceneNode.py @@ -4,6 +4,7 @@ from copy import deepcopy from typing import List from UM.Application import Application +from UM.Math.AxisAlignedBox import AxisAlignedBox from UM.Scene.SceneNode import SceneNode from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator @@ -77,6 +78,29 @@ class CuraSceneNode(SceneNode): 1.0 ] + def collidesWithBbox(self, check_bbox): + bbox = self.getBoundingBox() + + # Mark the node as outside the build volume if the bounding box test fails. + if check_bbox.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection: + return True + + return False + + def collidesWithArea(self, areas): + convex_hull = self.callDecoration("getConvexHull") + if convex_hull: + if not convex_hull.isValid(): + return False + + # Check for collisions between disallowed areas and the object + for area in areas: + overlap = convex_hull.intersectsPolygon(area) + if overlap is None: + continue + return True + return False + ## Taken from SceneNode, but replaced SceneNode with CuraSceneNode def __deepcopy__(self, memo): copy = CuraSceneNode() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 817317bf0a..cb0ce4ffc5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -720,8 +720,6 @@ class MachineManager(QObject): for setting_key in self._global_container_stack.definition.getAllKeys(): if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"): continue - if setting_key == "support_infill_extruder_nr": - print("asdf") current_value = self._global_container_stack.getProperty(setting_key, "value") if current_value is None: continue diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index b853c06c8e..686c546836 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -61,7 +61,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): # use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh" # has not been updated yet. - deep_copy._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings) + deep_copy._is_non_printing_mesh = self.evaluateIsNonPrintingMesh() return deep_copy @@ -89,10 +89,13 @@ class SettingOverrideDecorator(SceneNodeDecorator): def isNonPrintingMesh(self): return self._is_non_printing_mesh + def evaluateIsNonPrintingMesh(self): + return any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings) + def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function # Trigger slice/need slicing if the value has changed. if property_name == "value": - self._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings) + self._is_non_printing_mesh = self.evaluateIsNonPrintingMesh() Application.getInstance().getBackend().needsSlicing() Application.getInstance().getBackend().tickle() diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 50ff2864b7..2abfe80f95 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -84,11 +84,7 @@ class SolidView(View): per_mesh_stack = node.callDecoration("getStack") - # Get color to render this mesh in from ExtrudersModel - extruder_index = 0 - extruder_id = node.callDecoration("getActiveExtruder") - if extruder_id: - extruder_index = max(0, self._extruders_model.find("id", extruder_id)) + extruder_index = int(node.callDecoration("getActiveExtruderPosition")) # Use the support extruder instead of the active extruder if this is a support_mesh if per_mesh_stack: