mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 21:44:01 -06:00
Merge branch 'master' into feature_intent_per_quality
This commit is contained in:
commit
fee6ec417f
5 changed files with 252 additions and 74 deletions
|
@ -727,48 +727,17 @@ class BuildVolume(SceneNode):
|
|||
|
||||
self._error_areas = []
|
||||
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
used_extruders = extruder_manager.getUsedExtruderStacks()
|
||||
used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
|
||||
disallowed_border_size = self.getEdgeDisallowedSize()
|
||||
|
||||
if not used_extruders:
|
||||
# If no extruder is used, assume that the active extruder is used (else nothing is drawn)
|
||||
if extruder_manager.getActiveExtruderStack():
|
||||
used_extruders = [extruder_manager.getActiveExtruderStack()]
|
||||
else:
|
||||
used_extruders = [self._global_container_stack]
|
||||
|
||||
result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) #Normal machine disallowed areas can always be added.
|
||||
result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) # Normal machine disallowed areas can always be added.
|
||||
prime_areas = self._computeDisallowedAreasPrimeBlob(disallowed_border_size, used_extruders)
|
||||
result_areas_no_brim = self._computeDisallowedAreasStatic(0, used_extruders) #Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
|
||||
prime_disallowed_areas = copy.deepcopy(result_areas_no_brim)
|
||||
result_areas_no_brim = self._computeDisallowedAreasStatic(0, used_extruders) # Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
|
||||
|
||||
#Check if prime positions intersect with disallowed areas.
|
||||
# Check if prime positions intersect with disallowed areas.
|
||||
for extruder in used_extruders:
|
||||
extruder_id = extruder.getId()
|
||||
|
||||
collision = False
|
||||
for prime_polygon in prime_areas[extruder_id]:
|
||||
for disallowed_polygon in prime_disallowed_areas[extruder_id]:
|
||||
if prime_polygon.intersectsPolygon(disallowed_polygon) is not None:
|
||||
collision = True
|
||||
break
|
||||
if collision:
|
||||
break
|
||||
|
||||
#Also check other prime positions (without additional offset).
|
||||
for other_extruder_id in prime_areas:
|
||||
if extruder_id == other_extruder_id: #It is allowed to collide with itself.
|
||||
continue
|
||||
for other_prime_polygon in prime_areas[other_extruder_id]:
|
||||
if prime_polygon.intersectsPolygon(other_prime_polygon):
|
||||
collision = True
|
||||
break
|
||||
if collision:
|
||||
break
|
||||
if collision:
|
||||
break
|
||||
|
||||
result_areas[extruder_id].extend(prime_areas[extruder_id])
|
||||
result_areas_no_brim[extruder_id].extend(prime_areas[extruder_id])
|
||||
|
||||
|
@ -776,37 +745,32 @@ class BuildVolume(SceneNode):
|
|||
for area in nozzle_disallowed_areas:
|
||||
polygon = Polygon(numpy.array(area, numpy.float32))
|
||||
polygon_disallowed_border = polygon.getMinkowskiHull(Polygon.approximatedCircle(disallowed_border_size))
|
||||
result_areas[extruder_id].append(polygon_disallowed_border) #Don't perform the offset on these.
|
||||
#polygon_minimal_border = polygon.getMinkowskiHull(5)
|
||||
result_areas_no_brim[extruder_id].append(polygon) # no brim
|
||||
result_areas[extruder_id].append(polygon_disallowed_border) # Don't perform the offset on these.
|
||||
result_areas_no_brim[extruder_id].append(polygon) # No brim
|
||||
|
||||
# Add prime tower location as disallowed area.
|
||||
if len(used_extruders) > 1: #No prime tower in single-extrusion.
|
||||
|
||||
if len([x for x in used_extruders if x.isEnabled]) > 1: #No prime tower if only one extruder is enabled
|
||||
prime_tower_collision = False
|
||||
prime_tower_areas = self._computeDisallowedAreasPrinted(used_extruders)
|
||||
for extruder_id in prime_tower_areas:
|
||||
for i_area, prime_tower_area in enumerate(prime_tower_areas[extruder_id]):
|
||||
for area in result_areas[extruder_id]:
|
||||
if prime_tower_area.intersectsPolygon(area) is not None:
|
||||
prime_tower_collision = True
|
||||
break
|
||||
if prime_tower_collision: #Already found a collision.
|
||||
if len([x for x in used_extruders if x.isEnabled]) > 1: # No prime tower if only one extruder is enabled
|
||||
prime_tower_collision = False
|
||||
prime_tower_areas = self._computeDisallowedAreasPrinted(used_extruders)
|
||||
for extruder_id in prime_tower_areas:
|
||||
for area_index, prime_tower_area in enumerate(prime_tower_areas[extruder_id]):
|
||||
for area in result_areas[extruder_id]:
|
||||
if prime_tower_area.intersectsPolygon(area) is not None:
|
||||
prime_tower_collision = True
|
||||
break
|
||||
if (ExtruderManager.getInstance().getResolveOrValue("prime_tower_brim_enable") and
|
||||
ExtruderManager.getInstance().getResolveOrValue("adhesion_type") != "raft"):
|
||||
prime_tower_areas[extruder_id][i_area] = prime_tower_area.getMinkowskiHull(
|
||||
Polygon.approximatedCircle(disallowed_border_size))
|
||||
if not prime_tower_collision:
|
||||
result_areas[extruder_id].extend(prime_tower_areas[extruder_id])
|
||||
result_areas_no_brim[extruder_id].extend(prime_tower_areas[extruder_id])
|
||||
else:
|
||||
self._error_areas.extend(prime_tower_areas[extruder_id])
|
||||
if prime_tower_collision: # Already found a collision.
|
||||
break
|
||||
if self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft":
|
||||
prime_tower_areas[extruder_id][area_index] = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(disallowed_border_size))
|
||||
if not prime_tower_collision:
|
||||
result_areas[extruder_id].extend(prime_tower_areas[extruder_id])
|
||||
result_areas_no_brim[extruder_id].extend(prime_tower_areas[extruder_id])
|
||||
else:
|
||||
self._error_areas.extend(prime_tower_areas[extruder_id])
|
||||
|
||||
self._has_errors = len(self._error_areas) > 0
|
||||
|
||||
self._disallowed_areas = []
|
||||
self._disallowed_areas = [] # type: List[Polygon]
|
||||
for extruder_id in result_areas:
|
||||
self._disallowed_areas.extend(result_areas[extruder_id])
|
||||
self._disallowed_areas_no_brim = []
|
||||
|
@ -826,8 +790,8 @@ class BuildVolume(SceneNode):
|
|||
for extruder in used_extruders:
|
||||
result[extruder.getId()] = []
|
||||
|
||||
#Currently, the only normally printed object is the prime tower.
|
||||
if ExtruderManager.getInstance().getResolveOrValue("prime_tower_enable"):
|
||||
# Currently, the only normally printed object is the prime tower.
|
||||
if self._global_container_stack.getProperty("prime_tower_enable"):
|
||||
prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value")
|
||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||
|
@ -837,8 +801,7 @@ class BuildVolume(SceneNode):
|
|||
prime_tower_x = prime_tower_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
|
||||
prime_tower_y = prime_tower_y + machine_depth / 2
|
||||
|
||||
if (ExtruderManager.getInstance().getResolveOrValue("prime_tower_brim_enable") and
|
||||
ExtruderManager.getInstance().getResolveOrValue("adhesion_type") != "raft"):
|
||||
if self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft":
|
||||
brim_size = (
|
||||
extruder.getProperty("brim_line_count", "value") *
|
||||
extruder.getProperty("skirt_brim_line_width", "value") / 100.0 *
|
||||
|
@ -908,9 +871,12 @@ class BuildVolume(SceneNode):
|
|||
# for.
|
||||
# \return A dictionary with for each used extruder ID the disallowed areas
|
||||
# where that extruder may not print.
|
||||
def _computeDisallowedAreasStatic(self, border_size, used_extruders):
|
||||
#Convert disallowed areas to polygons and dilate them.
|
||||
def _computeDisallowedAreasStatic(self, border_size:float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
|
||||
# Convert disallowed areas to polygons and dilate them.
|
||||
machine_disallowed_polygons = []
|
||||
if self._global_container_stack is None:
|
||||
return {}
|
||||
|
||||
for area in self._global_container_stack.getProperty("machine_disallowed_areas", "value"):
|
||||
polygon = Polygon(numpy.array(area, numpy.float32))
|
||||
polygon = polygon.getMinkowskiHull(Polygon.approximatedCircle(border_size))
|
||||
|
@ -921,7 +887,7 @@ class BuildVolume(SceneNode):
|
|||
nozzle_offsetting_for_disallowed_areas = self._global_container_stack.getMetaDataEntry(
|
||||
"nozzle_offsetting_for_disallowed_areas", True)
|
||||
|
||||
result = {}
|
||||
result = {} # type: Dict[str, List[Polygon]]
|
||||
for extruder in used_extruders:
|
||||
extruder_id = extruder.getId()
|
||||
offset_x = extruder.getProperty("machine_nozzle_offset_x", "value")
|
||||
|
@ -930,13 +896,13 @@ class BuildVolume(SceneNode):
|
|||
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
|
||||
if offset_y is None:
|
||||
offset_y = 0
|
||||
offset_y = -offset_y #Y direction of g-code is the inverse of Y direction of Cura's scene space.
|
||||
offset_y = -offset_y # Y direction of g-code is the inverse of Y direction of Cura's scene space.
|
||||
result[extruder_id] = []
|
||||
|
||||
for polygon in machine_disallowed_polygons:
|
||||
result[extruder_id].append(polygon.translate(offset_x, offset_y)) #Compensate for the nozzle offset of this extruder.
|
||||
result[extruder_id].append(polygon.translate(offset_x, offset_y)) # Compensate for the nozzle offset of this extruder.
|
||||
|
||||
#Add the border around the edge of the build volume.
|
||||
# Add the border around the edge of the build volume.
|
||||
left_unreachable_border = 0
|
||||
right_unreachable_border = 0
|
||||
top_unreachable_border = 0
|
||||
|
@ -944,7 +910,8 @@ class BuildVolume(SceneNode):
|
|||
|
||||
# Only do nozzle offsetting if needed
|
||||
if nozzle_offsetting_for_disallowed_areas:
|
||||
#The build volume is defined as the union of the area that all extruders can reach, so we need to know the relative offset to all extruders.
|
||||
# The build volume is defined as the union of the area that all extruders can reach, so we need to know
|
||||
# the relative offset to all extruders.
|
||||
for other_extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||
other_offset_x = other_extruder.getProperty("machine_nozzle_offset_x", "value")
|
||||
if other_offset_x is None:
|
||||
|
@ -1028,8 +995,8 @@ class BuildVolume(SceneNode):
|
|||
[ half_machine_width - border_size, 0]
|
||||
], numpy.float32)))
|
||||
result[extruder_id].append(Polygon(numpy.array([
|
||||
[ half_machine_width,-half_machine_depth],
|
||||
[-half_machine_width,-half_machine_depth],
|
||||
[ half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width, -half_machine_depth],
|
||||
[ 0, -half_machine_depth + border_size]
|
||||
], numpy.float32)))
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ class ExtruderManager(QObject):
|
|||
# list.
|
||||
#
|
||||
# \return A list of extruder stacks.
|
||||
def getUsedExtruderStacks(self) -> List["ContainerStack"]:
|
||||
def getUsedExtruderStacks(self) -> List["ExtruderStack"]:
|
||||
global_stack = self._application.getGlobalContainerStack()
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
|
||||
|
|
|
@ -1196,6 +1196,13 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
"surface energy": "material_surface_energy",
|
||||
"shrinkage percentage": "material_shrinkage_percentage",
|
||||
"build volume temperature": "build_volume_temperature",
|
||||
"anti ooze retracted position": "material_anti_ooze_retracted_position",
|
||||
"anti ooze retract speed": "material_anti_ooze_retraction_speed",
|
||||
"break preparation retracted position": "material_break_preparation_retracted_position",
|
||||
"break preparation speed": "material_break_preparation_speed",
|
||||
"break retracted position": "material_break_retracted_position",
|
||||
"break speed": "material_break_speed",
|
||||
"break temperature": "material_break_temperature"
|
||||
}
|
||||
__unmapped_settings = [
|
||||
"hardware compatible",
|
||||
|
|
|
@ -2234,6 +2234,107 @@
|
|||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_crystallinity":
|
||||
{
|
||||
"label": "Crystalline Material",
|
||||
"description": "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"enabled": false,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_anti_ooze_retracted_position":
|
||||
{
|
||||
"label": "Anti-ooze Retracted Position",
|
||||
"description": "How far the material needs to be retracted before it stops oozing.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"default_value": 4,
|
||||
"enabled": false,
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "retraction_amount",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_anti_ooze_retraction_speed":
|
||||
{
|
||||
"label": "Anti-ooze Retraction Speed",
|
||||
"description": "How fast the material needs to be retracted during a filament switch to prevent oozing.",
|
||||
"type": "float",
|
||||
"unit": "mm/s",
|
||||
"default_value": 5,
|
||||
"enabled": false,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_break_preparation_retracted_position":
|
||||
{
|
||||
"label": "Break Preparation Retracted Position",
|
||||
"description": "How far the filament can be stretched before it breaks, while heated.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"default_value": 16,
|
||||
"enabled": false,
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "retraction_amount * 4",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_break_preparation_speed":
|
||||
{
|
||||
"label": "Break Preparation Retraction Speed",
|
||||
"description": "How fast the filament needs to be retracted just before breaking it off in a retraction.",
|
||||
"type": "float",
|
||||
"unit": "mm/s",
|
||||
"default_value": 2,
|
||||
"enabled": false,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_break_retracted_position":
|
||||
{
|
||||
"label": "Break Retracted Position",
|
||||
"description": "How far to retract the filament in order to break it cleanly.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"default_value": 50,
|
||||
"enabled": false,
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "100",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_break_speed":
|
||||
{
|
||||
"label": "Break Retraction Speed",
|
||||
"description": "The speed at which to retract the filament in order to break it cleanly.",
|
||||
"type": "float",
|
||||
"unit": "mm/s",
|
||||
"default_value": 25,
|
||||
"enabled": false,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_break_temperature":
|
||||
{
|
||||
"label": "Break Temperature",
|
||||
"description": "The temperature at which the filament is broken for a clean break.",
|
||||
"type": "float",
|
||||
"unit": "°C",
|
||||
"default_value": 50,
|
||||
"enabled": false,
|
||||
"minimum_value": "-273.15",
|
||||
"maximum_value_warning": "300",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_flow":
|
||||
{
|
||||
"label": "Flow",
|
||||
|
|
|
@ -43,6 +43,109 @@ def test_buildGridMesh(build_volume):
|
|||
assert numpy.array_equal(result_vertices, mesh.getVertices())
|
||||
|
||||
|
||||
def test_clamp(build_volume):
|
||||
assert build_volume._clamp(0, 0, 200) == 0
|
||||
assert build_volume._clamp(0, -200, 200) == 0
|
||||
assert build_volume._clamp(300, -200, 200) == 200
|
||||
|
||||
|
||||
class TestCalculateBedAdhesionSize:
|
||||
setting_property_dict = {"adhesion_type": {"value": "brim"},
|
||||
"skirt_brim_line_width": {"value": 0},
|
||||
"initial_layer_line_width_factor": {"value": 0},
|
||||
"brim_line_count": {"value": 0},
|
||||
"machine_width": {"value": 200},
|
||||
"machine_depth": {"value": 200},
|
||||
"skirt_line_count": {"value": 0},
|
||||
"skirt_gap": {"value": 0},
|
||||
"raft_margin": {"value": 0}
|
||||
}
|
||||
|
||||
def getPropertySideEffect(*args, **kwargs):
|
||||
properties = TestCalculateBedAdhesionSize.setting_property_dict.get(args[1])
|
||||
if properties:
|
||||
return properties.get(args[2])
|
||||
|
||||
def createAndSetGlobalStack(self, build_volume):
|
||||
mocked_stack = MagicMock()
|
||||
mocked_stack.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
|
||||
|
||||
build_volume._global_container_stack = mocked_stack
|
||||
|
||||
def test_noGlobalStack(self, build_volume: BuildVolume):
|
||||
assert build_volume._calculateBedAdhesionSize([]) is None
|
||||
|
||||
@pytest.mark.parametrize("setting_dict, result", [
|
||||
({}, 0),
|
||||
({"adhesion_type": {"value": "skirt"}}, 0),
|
||||
({"adhesion_type": {"value": "raft"}}, 0),
|
||||
({"adhesion_type": {"value": "none"}}, 0),
|
||||
({"adhesion_type": {"value": "skirt"}, "skirt_line_count": {"value": 2}, "initial_layer_line_width_factor": {"value": 1}, "skirt_brim_line_width": {"value": 2}}, 0.02),
|
||||
# Even though it's marked as skirt, it should behave as a brim as the prime tower has a brim (skirt line count is still at 0!)
|
||||
({"adhesion_type": {"value": "skirt"}, "prime_tower_brim_enable": {"value": True}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, -0.06),
|
||||
({"brim_line_count": {"value": 1}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, 0),
|
||||
({"brim_line_count": {"value": 2}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, 0.06),
|
||||
({"brim_line_count": {"value": 9000000}, "skirt_brim_line_width": {"value": 90000}, "initial_layer_line_width_factor": {"value": 9000}}, 100), # Clamped at half the max size of buildplate
|
||||
])
|
||||
def test_singleExtruder(self, build_volume: BuildVolume, setting_dict, result):
|
||||
self.createAndSetGlobalStack(build_volume)
|
||||
patched_dictionary = self.setting_property_dict.copy()
|
||||
patched_dictionary.update(setting_dict)
|
||||
with patch.dict(self.setting_property_dict, patched_dictionary):
|
||||
assert build_volume._calculateBedAdhesionSize([]) == result
|
||||
|
||||
def test_unknownBedAdhesion(self, build_volume: BuildVolume):
|
||||
self.createAndSetGlobalStack(build_volume)
|
||||
patched_dictionary = self.setting_property_dict.copy()
|
||||
patched_dictionary.update({"adhesion_type": {"value": "OMGZOMGBBQ"}})
|
||||
with patch.dict(self.setting_property_dict, patched_dictionary):
|
||||
with pytest.raises(Exception):
|
||||
build_volume._calculateBedAdhesionSize([])
|
||||
|
||||
class TestComputeDisallowedAreasStatic:
|
||||
setting_property_dict = {"machine_disallowed_areas": {"value": [[[-200, 112.5], [ -82, 112.5], [ -84, 102.5], [-115, 102.5]]]},
|
||||
"machine_width": {"value": 200},
|
||||
"machine_depth": {"value": 200},
|
||||
}
|
||||
|
||||
def getPropertySideEffect(*args, **kwargs):
|
||||
properties = TestComputeDisallowedAreasStatic.setting_property_dict.get(args[1])
|
||||
if properties:
|
||||
return properties.get(args[2])
|
||||
|
||||
def test_computeDisallowedAreasStaticNoExtruder(self, build_volume: BuildVolume):
|
||||
mocked_stack = MagicMock()
|
||||
mocked_stack.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
|
||||
|
||||
build_volume._global_container_stack = mocked_stack
|
||||
assert build_volume._computeDisallowedAreasStatic(0, []) == {}
|
||||
|
||||
def test_computeDisalowedAreasStaticSingleExtruder(self, build_volume: BuildVolume):
|
||||
mocked_stack = MagicMock()
|
||||
mocked_stack.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
|
||||
|
||||
mocked_extruder = MagicMock()
|
||||
mocked_extruder.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
|
||||
mocked_extruder.getId = MagicMock(return_value = "zomg")
|
||||
|
||||
build_volume._global_container_stack = mocked_stack
|
||||
with patch("cura.Settings.ExtruderManager.ExtruderManager.getInstance"):
|
||||
result = build_volume._computeDisallowedAreasStatic(0, [mocked_extruder])
|
||||
assert result == {"zomg": [Polygon([[-84.0, 102.5], [-115.0, 102.5], [-200.0, 112.5], [-82.0, 112.5]])]}
|
||||
|
||||
def test_computeDisalowedAreasMutliExtruder(self, build_volume):
|
||||
mocked_stack = MagicMock()
|
||||
mocked_stack.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
|
||||
|
||||
mocked_extruder = MagicMock()
|
||||
mocked_extruder.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
|
||||
mocked_extruder.getId = MagicMock(return_value="zomg")
|
||||
extruder_manager = MagicMock()
|
||||
extruder_manager.getActiveExtruderStacks = MagicMock(return_value = [mocked_stack])
|
||||
build_volume._global_container_stack = mocked_stack
|
||||
with patch("cura.Settings.ExtruderManager.ExtruderManager.getInstance", MagicMock(return_value = extruder_manager)):
|
||||
result = build_volume._computeDisallowedAreasStatic(0, [mocked_extruder])
|
||||
assert result == {"zomg": [Polygon([[-84.0, 102.5], [-115.0, 102.5], [-200.0, 112.5], [-82.0, 112.5]])]}
|
||||
|
||||
class TestUpdateRaftThickness:
|
||||
setting_property_dict = {"raft_base_thickness": {"value": 1},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue